Files
metro-puzzle-jp/doc/mal-och-tester.md
claude a5a660b32f
All checks were successful
release / build-release (push) Successful in 1m35s
M2: tåg med tidtabell, spärrar med kort, skyltar, vinst/förlust
- level: Schedule (ankomst/intervall/uppehåll) med Status(t), spårnummer,
  avgift, skylttexter per i-ruta, Path (BFS) och UngatedPlatforms – regeln
  att perronger bara nås via spärrar testas för alla banor
- sim.Run: klocka, tågkort (saldo dras vid spärr, tomt kort stoppas),
  ombordstigning med Enter när tåget är inne, vinst/förlust; headless
  bot-test klarar bana 001 och förlorar på fel tåg
- game: perronginfo (avgår om / nästa tåg om), skyltruta, nekad spärr,
  tågvagn som ritas när tåget är inne, inforutan flyttas upp när spelaren
  står nära nederkanten; resultat med spärrpassager och saldo
- bana 001 ombyggd så spärrarna är flaskhalsar; bana 002 omgenererad med
  spärrar runt perrongerna och skylttexter
- tools/shots räknar ut vägar med BFS; skriptkommandot waittrain
- docs/README/wiki uppdaterade med nya bilder

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

9.3 KiB
Raw Blame History

Mål och tester

Projektmål

Vision

Ett pixel art-pusselspel där känslan av att vara vilse på en japansk station är själva spelet – och där man faktiskt blir bättre på att läsa skyltarna ju mer man spelar. Spelet ska vara en enda binär som är lika lätt att bygga på Linux som på Windows.

Konkreta mål

  1. Spelbar story från flygplatsen till flygplatsen, med stigande svårighet, flerbytesbanor, sidobanor, slutanimation och eftertexter.
  2. En binär + en resources/-mapp per plattform. Inga installers, inga runtime-beroenden utöver vad ett vanligt skrivbord redan har.
  3. Få byggverktyg. Go är det enda kravet (Linux behöver dessutom en C-kompilator och X11/GL-headers för fönsterhanteringen). Allt byggs med go run ./tools/build.
  4. Debug och release i VS Code med F5 respektive Ctrl+Shift+B, utan extra skript.
  5. All spellogik testbar utan fönster. Bara presentationslagret känner till Ebitengine.
  6. Deterministiskt. Samma seed ger samma minispel och samma mål i oändligt läge.
  7. Windows utan omskrivning. -os windows ska vara allt som krävs för att få en fungerande Windows-binär från Linux.

Mätbara mål

Mål Mått Status 2026-10-23
Inkrementellt debug-bygge < 10 s 4,7 s
Release-binär < 20 MB 10,2 MB (Linux), 10,8 MB (Windows)
Testsviten go test ./... grön på < 30 s ~0,1 s
Banor 100 % passerar det automatiska lösbarhetstestet 2 av 2
Windows-korsbygge från Linux fungerar utan extra verktyg ✓ (CGO_ENABLED=0)
Linux-binärens länkade bibliotek bara libc ✓ (GL/X11 laddas dynamiskt vid körning)
Bildfrekvens 60 fps vid 4× skala på integrerad grafik ej mätt
Uppstart < 2 s till första bildruta ej mätt

Teststrategi

Principer

  • Ren logik → enhetstester. Paket under internal/ som inte är presentation får inte importera Ebitengine. Det kontrolleras av internal/archtest, som läser beroendegrafen med go list och faller om något annat paket än internal/game, internal/ui, internal/audio eller cmd/… drar in Ebitengine.
  • Data testas som data. Varje bana, språkfil och ordbok som ligger i resources/ valideras av tester, så att trasigt innehåll stoppar bygget i stället för att krascha spelet.
  • Slump går alltid via internal/rng med en känd seed. Då går minispel och event-timing att testa deterministiskt.
  • Inga tester kräver display. Smoke-testet av själva fönstret körs manuellt (eller på en maskin med skärm) med -smoke.

Testnivåer

Nivå Vad Hur Körs
1. Enhet Funktioner i ett paket *_test.go bredvid koden go test ./...
2. Data Allt under resources/ Datadrivna tester som läser filerna go test ./...
3. Arkitektur Beroenderegler internal/archtest go test ./...
4. Simulering En bot spelar en bana headless Deterministisk körning av spelloopen utan rendering (kommande) go test ./...
5. Smoke Binären öppnar fönster och avslutar metro-puzzle-jp -smoke 90, eller tools/shots som dessutom spelar igenom bana 001 i skriptläge manuellt / med skärm
6. Speltest Känsla, svårighet, buggar Checklistan nedan före varje release

Tester som finns i dag

Paket Test Verifierar
internal/res TestLocate_* Uppslagsordningen env → bredvid binären → uppåt från cwd
internal/res TestDir_RealRepo Att repots resources/ hittas och att sv.json + placeholder.png går att läsa
internal/rng TestDeterministic, TestDeriveIsStableAndContextual Samma seed → samma sekvens; del-seeds per kontext
internal/level TestParseAndSolve, TestUnsolvableWhenWalledOff BFS hittar/hittar inte väg till rätt perrong
internal/level TestValidationErrors Ojämna rader, okända tecken, fel antal starter, tåg vid saknad perrong …
internal/level TestAllShippedLevels Varje bana i resources/data/levels parsar, har id = filnamn, är lösbar och har inga onåbara interaktiva rutor
internal/level TestListAndLoadFile Banlistan är sorterad, laddning från disk, TrainAt hittar rätt/fel tåg
internal/sim TestMoveFourDirections, TestBlockedByWallTurnsButStays Rörelse åt alla håll; vägg stoppar men vänder figuren
internal/sim TestContinuousMovementKeepsPace, TestStopsAtTileBoundaryWithoutInput, TestDirectionChangesOnlyAtTileBoundary Jämn fart med hållen tangent, stopp vid rutgräns, riktningsbyte bara vid rutgräns
internal/sim TestWorldPosInterpolates, TestFrameExactArrival, TestHugeDtIsBounded Pixelposition mellan rutor; exakt 10 bildrutor per ruta vid 6 rutor/s; inga oändliga loopar
internal/sim TestCamera* Kameran centrerar, klampas mot kanter och centrerar små världar
internal/level TestScheduleStatus, TestScheduleAndFareDefaults Tidtabellen ger rätt "inne/borta" och sekunder kvar; standardvärden fylls i
internal/level TestSignAt, TestPath, TestUngatedPlatforms Skylttext per ruta; BFS-väg är kortast och sammanhängande; perronger utan spärr framför upptäcks
internal/level TestAllShippedLevels (utökat) …plus: tidtabeller giltiga, alla skyltrutor har sv/en-text, alla tåg har spår, inga perronger nås utan spärr
internal/sim TestBotWinsLevel001 Simuleringstest M2: bot går kortaste vägen, passerar spärren (saldo dras en gång), väntar in tåget, kliver på → vinst; Step är no-op efteråt
internal/sim TestBotLosesOnWrongTrain, TestBoardOnlyWhenTrainPresent Fel tåg → förlust; Enter utan tåg inne gör inget
internal/sim TestGateNeedsCardBalance, TestSignHereOnlyWhenStill Tomt kort stoppas och registreras för HUD; mellan två spärrutor gratis; skylt visas bara stilla
internal/archtest TestOnlyPresentationPackagesImportEbitengine Beroenderegeln ovan

Planerade tester per milstolpe

Milstolpe (se roadmap) Tester som ska finnas när den är klar
M1 Rörelse & kamera ✓ Kollision mot vägg, rörelse i 4 riktningar, kamera klampas till kartan – finns, se tabellen ovan
M2 Stationen ✓ Tidtabell, spärr med/utan saldo, vinst/förlust, bot klarar bana 001 headless – finns, se tabellen ovan
M3 Japanska & skyltar Delvis översättning ger exakt de ord spelaren kan; andel engelska följer svårighetstabellen; ordboken: alla nycklar har kana/romaji/en/sv; alla skyltord i banorna finns i ordboken; hjälptid = f(japanska-nivå)
M4 Lämmeltåget Mätare sjunker med rätt takt; event-frekvens ökar med gruppstorlek; event väljs deterministiskt per seed
M5 Minikarta Upptäckta rutor markeras, återställs per bana; avgångar syns från start
M6 Kort/biljetter/minispel Saldo dras i spärr; tomt kort → automatkrav; biljettminispel: rätt/fel biljett; telefon-skanning misslyckas med given procent per seed; batteri tar bara slut över tröskeltid
M7 Svårighet/poäng/debuffs Poängformeln (tid, pengar, mätare, läge); tidsgräns och maxantal missade tåg; varje debuff ändrar rätt stat; temporära debuffar räknar ned 1–4 banor
M8 Progression & sparfil Sparfil round-trip (skriv → läs ger samma tillstånd inkl. seed); skill tree-krav; upplåsningar efter rätt bana; "< 33 %"-regeln kontrolleras mot itemlistan
M9 Navigeringslägen Listläge genererar rätt ordning av tåg; skyltläge: 1–4 giltiga vägar; fel-riktnings-förlust triggar vid rätt slutstation
M10 Story-innehåll Alla banor lösbara (redan automatiskt); flerbytesbanor har sammanhängande byten; sista banan slutar på flygplatsen
M11 Oändligt läge & NG+ Målsekvens deterministisk per seed; NG+ behåller skills men nollställer items
M12 Ljud & polish Alla ljudfiler som refereras finns och går att avkoda; Windows-binär startar (manuellt)

Acceptanskriterier för "klar"

En milstolpe är klar när:

  1. Alla tester i raden ovan finns och är gröna.
  2. go vet ./... och go test -race ./... är gröna.
  3. Debug- och release-bygget går igenom för Linux och Windows.
  4. Roadmapen är uppdaterad med datum och eventuella avsteg.

Manuell testchecklista (speltest)

  • Spelet startar till meny på under 2 s; ESC/avsluta fungerar.
  • Fönstret kan skalas; pixlarna är skarpa (heltalsskalning).
  • Bana 001 går att klara i både listläge och skyltläge.
  • Fel tåg ger tydlig förlust med förklaring.
  • Mätarna syns, sjunker och går att fylla på.
  • Tomt kort tvingar till automaten; minispelet är begripligt första gången.
  • Minikartan fylls i när man går runt och nollställs vid ny bana.
  • Spara mitt i en bana, ladda, och få samma minispelsutfall.
  • Ljud spelas vid ankomst och avgång; inget knaster vid loop.
  • Samma sparfil fungerar på Linux och Windows.

Kommandon

go test ./...                 # hela sviten
go test -race -v ./...        # utförligt med race-detektor
go test ./internal/level/ -run TestAllShippedLevels -v   # bara banorna
go vet ./...
go run ./tools/build -mode debug -run -- -smoke 90       # bygg + smoke-test med fönster