Files
metro-puzzle-jp/doc/roadmap.md
claude 4ae7dba291
Some checks failed
release / build-release (push) Failing after 27s
M1: rörelse, kollision, kamera, scener, tileset, skärmdumpar, CI
- internal/sim: rutbaserad Mover (4 riktningar, riktningsbyte vid rutgräns,
  bildrute-exakt ankomst) och Camera (följer, klampar, centrerar små kartor),
  med tester
- internal/game: scener meny -> bana -> resultat, tangentbord + gamepad,
  tileset och spelaranimation, HUD, skriptläge (-script) för deterministiska
  skärmdumpar och tester
- tools/genart genererar placeholder-grafik (tiles.png, player.png);
  tools/shots tar doc/img/*.png som README och wiki visar
- bana 002-shinjuku (33x21) för kamerascroll; level.List/LoadFile/TrainAt
- .gitea/workflows/release.yaml: vet + test + linux/windows-zippar till
  rullande latest på brasse-linux01-runnern (linux-amd64)
- docs: roadmap M1 klar, tester, plan, README med bilder och styrning

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-23 19:16:53 +02:00

265 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Roadmap och teknikval
Ordningen nedan är den ordning saker ska byggas i. Varje milstolpe är ett
körbart, testat steg som går att visa upp. Teknikvalen står först eftersom
de styr hur milstolparna byggs.
## Teknikval
| Område | Val | Varför |
|--------|-----|--------|
| Språk | **Go 1.27** | En enda installation ger kompilator, pakethanterare, testramverk och formatterare. Snabba byggen. Björn använder redan Go i andra projekt. |
| Spelbibliotek | **Ebitengine v2.10** (`github.com/hajimehoshi/ebiten/v2`) | Byggt för 2D-pixelspel: intern upplösning + heltalsskalning, nearest-neighbour-sampling, inbyggt ljud (OGG/WAV/MP3), tangentbord/gamepad/mus, textrendering med TTF. **Ren Go på Windows** → korsbygge från Linux utan C-verktyg. |
| Tester | Standardbiblioteket `testing` | Inget att installera. `go test ./...` kör allt. |
| Speldata | **JSON** i `resources/data/` | Läsbart, diffbart i git, `encoding/json` i standardbiblioteket. Byt till TOML bara om kommentarer blir ett verkligt behov. |
| Bygg | **`go run ./tools/build`** | Ett Go-program i stället för make/bash/PowerShell. Samma kommando på alla plattformar. Stämplar version och läge, kopierar resurser. |
| IDE | **VS Code + tillägget `golang.go`** | `.vscode/tasks.json` (bygg/test) och `.vscode/launch.json` (F5 med delve). Tillägget installerar delve åt dig. |
| Font | **PixelMplus** (10/12 px) eller **Misaki** (8 px) via `ebiten/v2/text/v2` | Pixelfonter med kana **och kanji**. Fri licens. Krävs för att skyltar ska kunna visas på riktigt. Beslut i M3. |
| Ljud | `ebiten/v2/audio` med OGG Vorbis (musik, jinglar) och WAV (korta effekter) | Ingår i Ebitengine, inga externa bibliotek. |
| Slump | `math/rand/v2` (PCG) genom `internal/rng` | Seedbart, deterministiskt, del-seeds per kontext. |
| Sparfiler | JSON i `os.UserConfigDir()/metro-puzzle-jp/` | Rätt plats på både Linux (`~/.config`) och Windows (`%AppData%`). |
| Versionshantering | Git, lokalt nu, Gitea senare | Enligt playbooken; CI-release när projektet är redo att delas. |
### Varför inte …
- **Godot:** utmärkt för pixel art, men bygger inte "i VS Code" på samma
sätt, kräver editor + exportmallar, och C#-spåret drar in .NET. Hade
passat om kravet varit "snabbast till prototyp", inte "få byggverktyg".
- **Rust + macroquad/Bevy:** bra, men Windows-korsbygge kräver MinGW eller
MSVC, och Bevy har långa byggtider. Rust-toolchain är en till sak att hålla
i gång på två OS.
- **C++ + raylib/SDL:** CMake + kompilator per plattform, pakethantering
för hand. Precis det "många byggverktyg"-problem vi vill undvika.
- **Love2D (Lua):** inget byggsteg alls, men distribution som en binär
kräver att man "fuserar" ihop filer, och det saknas ett naturligt
testramverk.
### Regler för Windows-portabilitet (gäller från dag 1)
1. Bygg sökvägar med `filepath.Join`, aldrig med `/` i strängar.
2. Inga Linux-specifika syscalls eller `/proc`-läsningar. Behövs OS-specifik
kod: lägg den i `*_linux.go` / `*_windows.go`.
3. Sparfiler och konfiguration via `os.UserConfigDir()`, aldrig `~` i
strängar.
4. Resurser hittas relativt binären (`internal/res`), aldrig relativt
arbetskatalogen i release.
5. Textfiler skrivs med `\n`; läsning tål `\r\n`.
6. Varje milstolpe avslutas med `go run ./tools/build -mode release -os windows`
så att Windows-bygget aldrig hinner gå sönder obemärkt.
7. Inget `cgo` i vår egen kod.
### Katalogstruktur
```
metro-puzzle-jp/
├── cmd/metro-puzzle-jp/ main.go – flaggor, fönster, startar spelet
├── internal/
│ ├── buildinfo/ version + läge (sätts av byggverktyget)
│ ├── res/ hittar och läser resources/ (ren Go)
│ ├── rng/ seedad slump (ren Go)
│ ├── level/ banformat, validering, BFS (ren Go)
│ ├── sim/ rutbaserad rörelse, kollision, kamera (ren Go)
│ ├── game/ Ebitengine-loop, scener, input, rendering, skriptläge ← får använda Ebitengine
│ ├── archtest/ beroenderegler
│ └── … kommande: lang/, nav/, score/, save/, minigame/, ui/, audio/
├── tools/build/ byggverktyget
├── tools/genart/ genererar placeholder-grafik (tiles.png, player.png)
├── tools/shots/ tar dokumentationens skärmdumpar till doc/img/
├── resources/ kopieras bredvid binären vid bygge
│ ├── sprites/ bilder, tilesets, UI
│ ├── sound/ OGG/WAV
│ ├── text/ sv.json, en.json, jp-dictionary.json, fonts/
│ └── data/ levels/, items, skills (JSON)
├── doc/ denna dokumentation (doc/img/ = skärmdumpar från tools/shots)
├── .gitea/workflows/ CI: test + release-zippar för linux/windows på brasse-linux01-runnern
├── .vscode/ tasks.json, launch.json
└── build/ (gitignorerad) debug/ och release/<os>-<arch>/
```
### Byggflöde
| Vad | Kommando | Resultat |
|-----|----------|----------|
| Debug (standard, Ctrl+Shift+B) | `go run ./tools/build` | `build/debug/metro-puzzle-jp` + `resources/`; inga optimeringar, full debuginfo |
| Debug med debugger (F5) | VS Code "Debug (dlv)" | Kompilerar och startar under delve med cwd = repots rot |
| Release Linux | `go run ./tools/build -mode release -os linux -arch amd64` | `build/release/linux-amd64/` – strippad, `-trimpath` |
| Release Windows | `go run ./tools/build -mode release -os windows -arch amd64` | `build/release/windows-amd64/metro-puzzle-jp.exe` – GUI-subsystem, inget konsolfönster |
| Tester | `go test ./...` | |
Versionen i binären kommer från `git describe --tags --always --dirty`,
så en tagg `v0.1.0` ger `metro-puzzle-jp v0.1.0` i `-version`.
### Skärmdumpar till dokumentationen
README och wikin visar bilder från `doc/img/`. De tas av spelet självt i
skriptläge så att de alltid är pixelexakta och går att återskapa:
```bash
go run ./tools/genart # bara om placeholder-grafiken ska genereras om
go run ./tools/shots # bygger debug, kör spelet med -script, skriver doc/img/*.png
```
**Regel:** när sprites, tileset eller UI ändras – kör `tools/shots` och
committa `doc/img/` i samma commit, så visar README och wiki alltid aktuell
grafik. Nya vyer läggs till i listan i `tools/shots/main.go`.
### CI
`.gitea/workflows/release.yaml` kör `go vet` + `go test`, bygger
`linux-amd64` och `windows-amd64` och lägger zipparna på den rullande
releasen `latest` (en tagg `vX.Y.Z` ger en versionerad release). Jobbet körs
på **brasse-linux01-runnern** (label `linux-amd64`), aldrig på Pi5:n.
## Milstolpar
### M0 – Skelett och byggkedja ✓ (klar 2026-10-23)
- Repo, Go-modul, Ebitengine-fönster 320×180 med heltalsskalning.
- `internal/res`, `internal/rng`, `internal/level` med tester.
- Byggverktyg, VS Code-tasks och launch-konfigurationer.
- Första banan (`001-flygplatsen`) renderad som färgade rutor med
placeholder-sprite.
- Verifierat: debug-bygge, Linux-release, Windows-korsbygge, smoke-test
med fönster, alla tester gröna.
### M1 – Rörelse, kollision och kamera ✓ (klar 2026-10-23)
- **Mål:** gå runt i en labyrint som är större än skärmen.
- Rutbaserad rörelse i 4 riktningar (pilar/WASD + gamepad d-pad/spak), mjukt
interpolerad, riktningsbyte vid rutgränser; kollision mot väggar; kamera
som följer spelaren och klampas till kartan (centrerar små kartor).
- Scen-system: meny (banlista) → bana → resultat (rätt/fel tåg, R = spela om).
- Tileset (`tiles.png`) och spelarsprite med gå-animation i fyra riktningar
(`player.png`), genererade av `tools/genart` tills riktig pixel art finns.
- Större testbana `002-shinjuku` (33×21 rutor) som bevisar kamerascrollen.
- Skriptläge (`-script`) och `tools/shots` som tar dokumentationens
skärmdumpar deterministiskt.
- **Teknik:** `internal/sim` (Mover, Camera – ren Go med tester),
`internal/game` (scener, input, assets), Ebitengine `inpututil`/`vector`.
- **Avsteg:** resultatskärmen visar redan rätt/fel tåg eftersom perrongen är
det naturliga slutet på en bana; tidtabell, spärrar och väntan på tåg
kommer i M2 som planerat.
### M2 – Stationen: tåg, spärrar och vinst/förlust → första spelbara banan
- **Mål:** bana 001 går att klara och misslyckas.
- Tåg med tidtabell som står vid perrongen en stund och avgår; nästa avgång
visas vid perrongen.
- Spärrar som kräver kort (kortet finns och har alltid saldo i M2).
- Vinst när rätt tåg tas; förlust när fel tåg tas. Resultatskärm.
- Interaktion med skyltar (visar text, än så länge på svenska/engelska).
- **Teknik:** `internal/sim/schedule`, `internal/level` utökas med
tidtabell + skyltinnehåll.
- **Klar när:** en simuleringstest låter en bot klara bana 001 headless;
manuellt spel från start till mål fungerar.
### M3 – Japanska och skyltsystemet
- **Mål:** spelets identitet – skyltar på japanska som man lär sig läsa.
- Pixelfont med kana + kanji (beslut PixelMplus/Misaki, licens in i repot).
- Kunskapsmodell: vilka tecken/ord spelaren kan. Skyltar renderas med
delvis översättning, egen färg för det som är översatt, interaktion för
att se översättning.
- Andel engelska på skyltar styrs av banans svårighet.
- "Fråga en japan": NPC-interaktion med väntetid beroende på japanska-nivå.
- Hintar i UI/bana skalar med japanska-nivå.
- **Teknik:** `internal/lang` (ordbok, kunskap, översättningslogik – ren
Go), `text/v2` i `internal/game`.
- **Klar när:** samma skylt visar olika mycket beroende på kunskap, och det
är testat; bana 001 spelas med japanska skyltar.
### M4 – Lämmeltåget och mätarna
- **Mål:** sällskapet följer med och ställer till det.
- Följare som går i rad efter spelaren.
- Mätare mat/dryck/toa per karaktär; händelser (toabesök, köpa dricka,
distraktion) vars frekvens skalar med gruppstorlek.
- Toaletter, kiosker och automater som rutor i banan.
- **Teknik:** `internal/sim/party`, `internal/sim/events` (seedade via
`internal/rng`).
- **Klar när:** fler i gruppen ger mätbart fler händelser i test; händelser
går att lösa i spelet.
### M5 – Minikarta och utforskning
- **Mål:** orientering utan att avslöja labyrinten.
- Minikarta som visar avgångar och riktmärken från start och fylls i när
man utforskar. Nollställs per bana och omgång.
- **Teknik:** `internal/sim/fog` (ren Go), rendering i `internal/game`.
### M6 – Kort, biljetter, telefon och minispel
- **Mål:** resurshantering och de seedade minispelen.
- Kortsaldo som dras i spärren; tomt kort → hitta automat → påfyllningsminispel.
- Separata biljetter på svårare banor → biljettköpsminispel (rätt biljett).
- Kort i telefonen: speed-buff + procentchans för omskanning. Batteri som
tar slut på långa banor → tvingar till biljett.
- Minispel på tåget: få plats, komma av, gå av på rätt station.
- **Teknik:** `internal/minigame/*` med gemensamt gränssnitt
(`Start(seed) / Update / Result`), all slump via del-seeds.
- **Klar när:** varje minispel är deterministiskt för en seed (test) och
spelbart.
### M7 – Svårighet, tid, poäng och debuffar
- **Mål:** banor som kan misslyckas och poäng att jaga.
- Tidsgräns och maxantal missade tåg på svåra banor; lätta banor obegränsade.
- Poängformel: tid, pengar/påfyllningar, mätarnas status, navigeringsläge.
- Stats (speed, törst, fokus, toalett, tur) och debuffar (onda fötter,
trötthet, hunger/irritation, matförgiftning); temporära debuffar 1–4 banor.
- Svårighetsprofil per bana i JSON.
- **Teknik:** `internal/score`, `internal/sim/stats`.
### M8 – Progression, items och sparfiler
- **Mål:** något att låsa upp och en anledning att fortsätta.
- XP/level-ups, skill tree, items (kläder, masker, hattar) med buffar.
- Bankarta i spelbrädesstil; sidobanor som ger skins/powers/items; items
som låser upp genvägar i huvudbanor.
- Sparfil med framsteg, items, skills, debuffar och seed. Autospar vid
banstart.
- **Teknik:** `internal/save` (JSON, versionsfält för migrering),
`resources/data/items.json`, `skills.json`.
- **Klar när:** sparfil round-trip-test grön; "< 33 % per omgång" går att
räkna ut från datan.
### M9 – Navigeringslägen: lista och skyltläge
- **Mål:** de två sätten att spela story.
- Listläge: nästa tåg visas.
- Skyltläge: 1–4 giltiga vägar, mer poäng, förlust om man åker i fel
riktning / för långt bort.
- **Teknik:** `internal/nav` (graf över stationer/linjer, giltiga vägar,
riktningskontroll – ren Go).
### M10 – Story-innehåll och flerbytesbanor
- **Mål:** hela resan från flygplats till flygplats.
- Alla huvudbanor och sidobanor; banor med flera stopp och byten; buss.
- Slutanimation (karaktärerna flyger iväg, items och poäng visas) och
eftertexter.
- Överstimulerande UI/banor som extra svårighet.
- **Teknik:** baneditor-stöd behövs troligen här: ett `tools/levelcheck`
som ritar banan som bild och rapporterar onåbara rutor.
### M11 – Oändligt läge och New Game+
- Slumpade mål från seed, poäng per mål, egen poänglista. NG+ behåller skills.
- Låses upp när storyn är klar.
### M12 – Ljud, polish och release
- Avgångsmelodier/ankomstjinglar, effekter, musik.
- Inställningar (ljudnivåer, språk sv/en, skala, tangenter).
- Windows-test på riktig maskin, ikon i exe:n, eventuell Gitea-CI med
releaser enligt playbooken.
## Prioritering
- **Måste för ett spelbart spel:** M1–M3, M6 (åtminstone kort/spärr), M7.
- **Gör spelet till *det här* spelet:** M3, M4, M9.
- **Kan skjutas utan att något går sönder:** M5, M11, delar av M8 (skill
tree), överstimulerande UI i M10.
- Windows-bygget körs vid varje milstolpe men testas på riktig Windows
först i M12.