135 lines
5.4 KiB
Markdown
135 lines
5.4 KiB
Markdown
# Skyrama TUI
|
|
|
|
A terminal user interface for a Skyrama-clone airport management game, built with BubbleTea.
|
|
|
|
## Tech Stack
|
|
|
|
- **Go 1.22**
|
|
- **github.com/charmbracelet/bubbletea** — TUI framework
|
|
- **github.com/charmbracelet/lipgloss** — terminal styling
|
|
- **github.com/charmbracelet/bubbles** — list, textinput, etc.
|
|
- **github.com/go-sql-driver/mysql** — MySQL driver
|
|
- **golang.org/x/crypto/bcrypt** — password hashing
|
|
- **sqlc** — SQL → Go codegen (generated files in `internal/db/`)
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
cmd/skyrama/main.go # Entry point: rootModel (login → app screen transition)
|
|
internal/
|
|
db/
|
|
client.go # Thin wrapper over sqlc Queries; auth, transactions, row mappers
|
|
db.go / querier.go /
|
|
queries.sql.go / models.go # sqlc-generated files (do not edit by hand)
|
|
model/model.go # Domain types: Airport, Plane, PlayerPlane, Building, Contract, …
|
|
style/style.go # All lipgloss styles and colors
|
|
ui/
|
|
app.go # AppModel: tab bar, 10s tick, window sizing
|
|
login.go # Login / register screen
|
|
airport_view.go # Tab 0: resources, XP bar
|
|
fleet.go # Tab 1: planes, launch/land flights
|
|
buildings.go # Tab 2: owned buildings + build catalogue
|
|
contracts.go # Tab 3: active delivery contracts
|
|
shop.go # Tab 4: buy planes
|
|
sql/
|
|
schema.sql # MySQL DDL (source of truth)
|
|
queries.sql # sqlc input queries
|
|
sqlc.yaml # sqlc configuration
|
|
buidl.bat # build script (go build -o skyrama ./cmd/skyrama/)
|
|
```
|
|
|
|
## Database
|
|
|
|
- **Engine:** MySQL
|
|
- **Default DSN:** `skyramaUser:Skyrama1234.@tcp(127.0.0.1:3306)/skyrama_clone?parseTime=true`
|
|
- Override via `--dsn` flag or `SKYRAMA_DSN` environment variable.
|
|
- Schema must be applied before first run: `sql/schema.sql`
|
|
|
|
## Build & Run
|
|
|
|
```bat
|
|
# Build
|
|
buidl.bat
|
|
# or
|
|
go build -o skyrama.exe ./cmd/skyrama/
|
|
|
|
# Run (uses default DSN if SKYRAMA_DSN not set)
|
|
.\skyrama.exe
|
|
|
|
# Run with custom DSN
|
|
.\skyrama.exe --dsn "user:pass@tcp(host:port)/dbname?parseTime=true"
|
|
|
|
# Regenerate sqlc files after editing sql/queries.sql
|
|
sqlc_generate.bat
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Screen flow
|
|
|
|
`rootModel` (main.go) owns two screens:
|
|
1. `screenLogin` → `ui.LoginModel` — handles `LoginSuccessMsg` / `LoginErrMsg`
|
|
2. `screenApp` → `ui.AppModel` — full game TUI after login
|
|
|
|
On `LoginSuccessMsg`, `rootModel` builds `AppModel` and injects all sub-models (Fleet, Buildings, Contracts, Shop) with the resolved `airportID`.
|
|
|
|
### AppModel (ui/app.go)
|
|
|
|
- Owns all tab sub-models as value/pointer fields.
|
|
- Routes `tea.Msg` to the active tab sub-model.
|
|
- Fires a 10-second tick that:
|
|
1. Calls `RefreshResources` (regenerates fuel/passengers via MySQL `TIMESTAMPDIFF`)
|
|
2. Auto-lands planes ready to land (`GetPlanesReadyToLand` + `LandFlight`)
|
|
|
|
### db.Client (internal/db/client.go)
|
|
|
|
Wraps the sqlc `*Queries` object. All multi-step DB operations are wrapped in transactions:
|
|
- `BuyPlane` — deducts cash, inserts `player_planes`, logs transaction
|
|
- `LaunchFlight` — deducts fuel, sets plane status to `flying`, logs transaction
|
|
- `LandFlight` — awards cash + XP, parks plane in hangar, logs transaction
|
|
- `ConstructBuilding` — deducts cash, inserts `airport_buildings`, logs transaction
|
|
|
|
Some queries use raw `database/sql` (e.g. `GetAirportBuildings`, `GetActiveContracts`) because the sqlc-generated join queries are not yet wired up.
|
|
|
|
### Domain model (internal/model/model.go)
|
|
|
|
Key types: `Airport`, `Plane`, `PlayerPlane`, `Building`, `AirportBuilding`, `Contract`, `Country`, `User`.
|
|
|
|
`PlayerPlane.TimeRemainingSeconds()` computes seconds until landing client-side.
|
|
`Contract.ProgressPct()` returns delivery progress as an integer percentage.
|
|
|
|
Tab index constants: `TabAirport=0`, `TabFleet=1`, `TabBuildings=2`, `TabContracts=3`, `TabShop=4`.
|
|
|
|
## Key Bindings
|
|
|
|
| Key | Action |
|
|
|-----|--------|
|
|
| `1-5` / `tab` / `shift+tab` | Switch tabs |
|
|
| `↑↓` / `j k` | Navigate lists |
|
|
| `enter` / `space` | Select / action |
|
|
| `/` | Filter list |
|
|
| `r` | Refresh current tab |
|
|
| `h / l` | Switch sub-tabs (Buildings) |
|
|
| `q` / `ctrl+c` | Quit |
|
|
|
|
**Fleet tab:** `enter` on idle plane → launch; `enter` on flying plane → check/land if ready.
|
|
**Buildings tab:** `h/l` or `←→` → toggle Owned ↔ Build catalogue; `enter` in catalogue → construct.
|
|
**Shop tab:** `enter` / `b` → buy selected plane (deducts cash, parks in first hangar).
|
|
|
|
## DB Schema Overview
|
|
|
|
Core tables: `users`, `airports`, `planes`, `player_planes`, `buildings`, `airport_buildings`, `countries`, `products`, `airport_contracts`, `airport_inventory`.
|
|
Log tables: `currency_transaction_logs`, `completed_flight_routes_log`.
|
|
Stage 1 (not yet active): `recipes`, `building_products`.
|
|
|
|
**Plane statuses:** `idle` | `maintenance` | `boarding` | `taxiing` | `flying`
|
|
**Building types:** `none` | `storage` | `support` | `operation` | `passive` | `shop` | `production`
|
|
**Aircraft sizes:** `small` | `medium` | `large` | `huge`
|
|
**Aircraft types:** `plane` | `helicopter` | `seaplane` | `spaceship`
|
|
|
|
## Development Stages
|
|
|
|
- **Stage 0 (current):** Launch planes to country's base airport, basic resources, buildings, shop.
|
|
- **Stage 1:** NPCs, cargo planes, shop buildings, recipes, inventory.
|
|
- **Stage 2:** Player progression, building upgrades, effects, complex recipes.
|
|
- **Stage 3:** TBD.
|