skyrama_tui/CLAUDE.md

135 lines
5.4 KiB
Markdown
Raw Permalink Normal View History

2026-06-04 20:51:20 +03:00
# 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.