M1: rörelse, kollision, kamera, scener, tileset, skärmdumpar, CI
Some checks failed
release / build-release (push) Failing after 27s

- 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>
This commit is contained in:
2026-10-23 19:16:53 +02:00
parent ae50d444a4
commit 4ae7dba291
34 changed files with 1730 additions and 124 deletions

BIN
doc/img/level-001.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
doc/img/level-002.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
doc/img/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
doc/img/result.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -34,7 +34,7 @@ att bygga på Linux som på Windows.
| 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 | 1 av 1 |
| 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 |
@@ -65,7 +65,7 @@ att bygga på Linux som på Windows.
| 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` | manuellt / med skärm |
| 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
@@ -78,13 +78,18 @@ att bygga på Linux som på Windows.
| `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/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 |
| ~~M1 Rörelse & kamera~~ ✓ | Kollision mot vägg, rörelse i 4 riktningar, kamera klampas till kartan – finns, se tabellen ovan |
| M2 Stationen | Tidtabell: nästa avgång beräknas rätt; spärr släpper igenom med giltigt kort/biljett och stoppar annars; vinst när rätt tåg tas, förlust vid fel tåg; simuleringstest: bot går kortaste vägen och klarar bana 001 |
| 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 |

View File

@@ -24,15 +24,15 @@ mål för spelet, men Gitea-CI kan byggas på Pi5-runnern senare.
## Leverans
Mönster A enligt playbooken (nedladdningsbar binär), när projektet ska
delas: `build/release/<os>-<arch>/` är redan formen som en release-zip ska
ha. Repot är **lokalt** nu och synkas till Gitea senare (Björn skapar repot
och lägger till `claude` som medlem, därefter `git remote add origin
gitea-claude:brasse/metro-puzzle-jp.git`).
Mönster A enligt playbooken (nedladdningsbar binär). Repot ligger på Gitea
(`brasse/metro-puzzle-jp`, sedan 2026-10-23) och CI bygger release-zippar
för Linux och Windows till den rullande releasen `latest` vid varje push
till master; en tagg `vX.Y.Z` ger en versionerad release. Byggs på
brasse-linux01-runnern, inte Pi5:n.
## Milstolpar
M0 skelett ✓ → M1 rörelse → M2 första spelbara banan → M3 japanska/skyltar
M0 skelett ✓ → M1 rörelse/kamera ✓ → M2 första spelbara banan → M3 japanska/skyltar
→ M4 lämmeltåget → M5 minikarta → M6 kort/biljetter/minispel → M7
svårighet/poäng/debuffar → M8 progression/sparfiler → M9 navigeringslägen →
M10 story-innehåll → M11 oändligt läge/NG+ → M12 ljud/polish/release.

View File

@@ -58,16 +58,20 @@ metro-puzzle-jp/
│ ├── res/ hittar och läser resources/ (ren Go)
│ ├── rng/ seedad slump (ren Go)
│ ├── level/ banformat, validering, BFS (ren Go)
│ ├── game/ Ebitengine-loop, scener, rendering ← får använda Ebitengine
│ ├── sim/ rutbaserad rörelse, kollision, kamera (ren Go)
│ ├── game/ Ebitengine-loop, scener, input, rendering, skriptläge ← får använda Ebitengine
│ ├── archtest/ beroenderegler
│ └── … kommande: sim/, lang/, nav/, score/, save/, minigame/, ui/, audio/
│ └── … 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/ 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>/
```
@@ -85,6 +89,27 @@ metro-puzzle-jp/
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)
@@ -97,17 +122,23 @@ så en tagg `v0.1.0` ger `metro-puzzle-jp v0.1.0` i `-version`.
- Verifierat: debug-bygge, Linux-release, Windows-korsbygge, smoke-test
med fönster, alla tester gröna.
### M1 – Rörelse, kollision och kamera
### M1 – Rörelse, kollision och kamera ✓ (klar 2026-10-23)
- **Mål:** gå runt i en labyrint som är större än skärmen.
- Spelare som rör sig i 4 riktningar (tangentbord + gamepad), kollision mot
väggar, kamera som följer och klampas till kartan.
- Scen-system (meny → bana → resultat) som en enkel tillståndsmaskin.
- Tileset i stället för färgade rutor; sprite-animation (gå/stå).
- **Teknik:** `internal/game/scene`, `internal/sim` (rörelse/kollision som
ren logik), Ebitengine `inpututil`.
- **Klar när:** man kan gå från S till P i bana 001, kameran följer, testerna
i mål-dokumentet för M1 är gröna.
- 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