feat: Engine-Kopie von Ninelands v0.11.0, Tageskarte mit eigenem Seed, Assets
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
@ -87,6 +87,9 @@ Abrufe (403).
|
|||
anspricht, in der Devvit-Doku prüfen (https://developers.reddit.com/docs).
|
||||
- Aktuelle Devvit-Doku lesen, bevor etwas gebaut wird – die Plattform ändert sich schnell; nicht aus dem Gedächtnis
|
||||
arbeiten.
|
||||
- **Engine-Kopie:** `scripts/sync-engine.sh <ninelands-tag>` (Stand in `src/engine/VERSION`), holt auch Sprites und
|
||||
Musik nach `public/`. `src/engine/` nie von Hand ändern; Biome ignoriert es. Unit-Tests werden vor `node --test` mit
|
||||
esbuild gebündelt (die Engine importiert ohne Dateiendung).
|
||||
- `.github/workflows/ci.yaml` stammt aus der Vorlage. Forgejo führt `.github/workflows` aus, wenn es kein
|
||||
`.forgejo/workflows` gibt; `runs-on: ubuntu-latest` ist der gemeinsame Hetzner-Runner (für `npm run test` reicht er).
|
||||
|
||||
|
|
@ -118,7 +121,7 @@ Abrufe (403).
|
|||
- CI: Die `parallel:`-Stufe der Vorlage ersetzt (Forgejo-Runner v13: „Invalid run/uses syntax“), Schritte laufen
|
||||
nacheinander.
|
||||
- `PLAN.md` angelegt, Lizenz auf GPL-3.0 umgestellt.
|
||||
- Nächste Schritte: offene Fragen in `PLAN.md` klären, dann Phase 0 (Sync-Skript, Engine, Assets).
|
||||
- Phase 0 erledigt (Engine `v0.11.0`, Tageskarte `src/shared/daily.ts`, Assets). Nächster Schritt: Phase 1.
|
||||
- Subreddit `r/Ninelands` ist frei (Besitzer hat nachgesehen); anlegen erst für den Demo-Post.
|
||||
|
||||
Diese Datei bei neuen Arbeitsregeln und Entscheidungen aktualisieren.
|
||||
|
|
|
|||
31
PLAN.md
|
|
@ -90,6 +90,16 @@ Abgabe: **9. Dezember 2026, 03:00 MEZ**. Eingereicht wird in „Best Daily Game
|
|||
legt der Besitzer erst für den Demo-Post an. Hochgeladene, nicht veröffentlichte Apps lassen sich nur in Subreddits
|
||||
mit < 200 Mitgliedern installieren – für die Jam-Demo reicht das.
|
||||
|
||||
## Devvit-Vorgaben, die das Design betreffen (Doku, 2026-11-13)
|
||||
|
||||
- **Ton:** erst nach einer Nutzeraktion abspielen, **Stumm-Knopf** im Spiel, bei `visibilitychange` stumm schalten.
|
||||
- **Gesten:** nur Tippen/Klicken; kein Scroll-Abfangen, kein Zoom/Pan – man muss am Post vorbeiscrollen können.
|
||||
- **Expanded Mode** nur auf ausdrückliche Aktion (Knopf), nie automatisch; die Standardansicht bleibt im Post.
|
||||
- **Responsive**, die meisten Spieler sind mobil.
|
||||
- **`localStorage` wird bei jedem App-Update gelöscht** → Streak, Freischaltungen, gewähltes Thema, Stumm-Schalter in
|
||||
Redis speichern.
|
||||
- Server: serverlos, max. 30 s je Anfrage, 4 MB Anfrage, 10 MB Antwort; kein `fs`. Client: keine externen Abrufe.
|
||||
|
||||
## Risiken
|
||||
|
||||
- Devvit ändert sich schnell: Scheduler, Redis, Flair und Journeys vor dem Bauen in der aktuellen Doku lesen
|
||||
|
|
@ -109,3 +119,24 @@ Abgabe: **9. Dezember 2026, 03:00 MEZ**. Eingereicht wird in „Best Daily Game
|
|||
keinen Zeilenumbruch am Ende.
|
||||
- Lizenz auf GPL-3.0 umgestellt (`LICENSE` aus dem Hauptspiel, `package.json` → `GPL-3.0-only`). Der BSD-Text der
|
||||
Vorlage bleibt als `LICENSE-TEMPLATE.md`, denn BSD verlangt, dass der Hinweis erhalten bleibt. `CREDITS.md` angelegt.
|
||||
|
||||
### 2026-11-13 – Phase 0: Engine und Assets
|
||||
|
||||
- `scripts/sync-engine.sh <tag>` holt per `git archive` (nur lesend) `src/core`, `src/campaign`, `src/puzzles` nach
|
||||
`src/engine/` und Sprites (Tiles, Brett-Themen) sowie Musik nach `public/`. Stand in `src/engine/VERSION`
|
||||
(`v0.11.0`). Avatare nicht übernommen (braucht die Basic-Version nicht).
|
||||
- `src/engine/` hat eine eigene `tsconfig.json` (strict, `noUncheckedIndexedAccess` aus, `resolveJsonModule`,
|
||||
`lib` WebWorker für `crypto`/`structuredClone`). **`erasableSyntaxOnly` aus**, weil `duel.ts` Parameter-Properties
|
||||
nutzt. Biome ignoriert `src/engine/`.
|
||||
- **Fallstrick:** Die Engine importiert ohne Dateiendung (`'./Board'`). `node --experimental-strip-types` kann das
|
||||
nicht auflösen. Deshalb bündelt `test:unit` die Tests jetzt erst mit esbuild nach `dist/test/` (`--packages=external`,
|
||||
damit `@devvit/web` als ein Modul geladen wird und die Redis-Attrappen im Server-Test greifen), dann `node --test`.
|
||||
Der Glob `src/**/*.test.ts` läuft unter `sh` ohne globstar = nur eine Ebene tief (`src/*/…`).
|
||||
- `src/shared/daily.ts`: Tageskarte mit Seed `fnv1a('ninelands-reddit-daily-' + UTC-Tag)`, Nummer ab 2026-11-13 (#1),
|
||||
Welt-Regel wie im Hauptspiel `rolledTrait(seed)`. **Präfix und `FIRST_DAY` nie ändern** (sonst andere Karten und
|
||||
Nummern rückwirkend); Schutztests in `daily.test.ts`.
|
||||
- Ziele (`computeGoals`, 7 Bot-Partien) plus Nachspielen dauern in Node ≈ 80 ms – unproblematisch für den Server.
|
||||
Für die Prüfung **nicht** `verifyProgress` aus `progress.ts` nehmen: das zieht Kampagnen-JSONs ins Bundle und kennt
|
||||
nur die Website-Tageskarte. Eigene Prüfung aus `applyMoves` + `computeGoals` + `starsOf`.
|
||||
- Musik: vorerst ein Titel („Peaceful Village“, MP3, 1,6 MB) – MP3 läuft auch in iOS-Webviews. Ein Größenlimit für
|
||||
Webview-Assets steht nicht in der Doku; weitere Titel in `scripts/sync-engine.sh` (`musik=(…)`) ergänzen.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.6.6/schema.json",
|
||||
"css": {"formatter": {"enabled": true, "quoteStyle": "single"}},
|
||||
"files": {"includes": ["**", "!dist/", "!public/*.js*"]},
|
||||
// src/engine/ ist eine Kopie aus Ninelands (scripts/sync-engine.sh) und wird nicht umformatiert
|
||||
"files": {"includes": ["**", "!dist/", "!public/*.js*", "!src/engine"]},
|
||||
"formatter": {
|
||||
"bracketSpacing": false,
|
||||
"enabled": true,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
"playtest": "devvit playtest",
|
||||
"test": "npm run test:types && npm run lint && npm run test:unit && npm run build",
|
||||
"test:types": "tsc --build",
|
||||
"test:unit": "node --experimental-strip-types --no-warnings=ExperimentalWarning --test src/**/*.test.ts",
|
||||
"test:unit": "esbuild --bundle --log-level=warning --platform=node --format=esm --packages=external --outdir=dist/test --outbase=src src/**/*.test.ts && node --test dist/test/**/*.test.js",
|
||||
"publish": "npm run clean && npm run build && devvit publish",
|
||||
"watch": "sh -c 'trap \"kill 0\" exit; npm run build:client -- --watch=forever& npm run build:server -- --watch=forever& wait' --"
|
||||
},
|
||||
|
|
|
|||
BIN
public/audio/music/peaceful-village.mp3
Normal file
BIN
public/sprites/themes/autumn/cave.png
Normal file
|
After Width: | Height: | Size: 914 B |
BIN
public/sprites/themes/autumn/chapel.png
Normal file
|
After Width: | Height: | Size: 807 B |
BIN
public/sprites/themes/autumn/grass0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/autumn/grass1.png
Normal file
|
After Width: | Height: | Size: 562 B |
BIN
public/sprites/themes/autumn/grass2.png
Normal file
|
After Width: | Height: | Size: 565 B |
BIN
public/sprites/themes/autumn/grass3.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/autumn/grass4.png
Normal file
|
After Width: | Height: | Size: 584 B |
BIN
public/sprites/themes/autumn/grass5.png
Normal file
|
After Width: | Height: | Size: 579 B |
BIN
public/sprites/themes/autumn/house.png
Normal file
|
After Width: | Height: | Size: 667 B |
BIN
public/sprites/themes/autumn/hut.png
Normal file
|
After Width: | Height: | Size: 701 B |
BIN
public/sprites/themes/autumn/moor0.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/autumn/moor1.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
public/sprites/themes/autumn/moor2.png
Normal file
|
After Width: | Height: | Size: 606 B |
BIN
public/sprites/themes/autumn/moor3.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/autumn/moor4.png
Normal file
|
After Width: | Height: | Size: 591 B |
BIN
public/sprites/themes/autumn/moor5.png
Normal file
|
After Width: | Height: | Size: 603 B |
BIN
public/sprites/themes/autumn/rock0.png
Normal file
|
After Width: | Height: | Size: 622 B |
BIN
public/sprites/themes/autumn/rock1.png
Normal file
|
After Width: | Height: | Size: 653 B |
BIN
public/sprites/themes/autumn/rock2.png
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
public/sprites/themes/autumn/tree.png
Normal file
|
After Width: | Height: | Size: 798 B |
BIN
public/sprites/themes/autumn/water0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/autumn/water1.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/autumn/well.png
Normal file
|
After Width: | Height: | Size: 645 B |
BIN
public/sprites/themes/classic/cave.png
Normal file
|
After Width: | Height: | Size: 917 B |
BIN
public/sprites/themes/classic/chapel.png
Normal file
|
After Width: | Height: | Size: 807 B |
BIN
public/sprites/themes/classic/grass0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/classic/grass1.png
Normal file
|
After Width: | Height: | Size: 577 B |
BIN
public/sprites/themes/classic/grass2.png
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
public/sprites/themes/classic/grass3.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/classic/grass4.png
Normal file
|
After Width: | Height: | Size: 583 B |
BIN
public/sprites/themes/classic/grass5.png
Normal file
|
After Width: | Height: | Size: 578 B |
BIN
public/sprites/themes/classic/house.png
Normal file
|
After Width: | Height: | Size: 667 B |
BIN
public/sprites/themes/classic/hut.png
Normal file
|
After Width: | Height: | Size: 701 B |
BIN
public/sprites/themes/classic/moor0.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/classic/moor1.png
Normal file
|
After Width: | Height: | Size: 600 B |
BIN
public/sprites/themes/classic/moor2.png
Normal file
|
After Width: | Height: | Size: 610 B |
BIN
public/sprites/themes/classic/moor3.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/classic/moor4.png
Normal file
|
After Width: | Height: | Size: 603 B |
BIN
public/sprites/themes/classic/moor5.png
Normal file
|
After Width: | Height: | Size: 607 B |
BIN
public/sprites/themes/classic/rock0.png
Normal file
|
After Width: | Height: | Size: 622 B |
BIN
public/sprites/themes/classic/rock1.png
Normal file
|
After Width: | Height: | Size: 653 B |
BIN
public/sprites/themes/classic/rock2.png
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
public/sprites/themes/classic/tree.png
Normal file
|
After Width: | Height: | Size: 800 B |
BIN
public/sprites/themes/classic/water0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/classic/water1.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/classic/well.png
Normal file
|
After Width: | Height: | Size: 645 B |
BIN
public/sprites/themes/desert/cave.png
Normal file
|
After Width: | Height: | Size: 915 B |
BIN
public/sprites/themes/desert/chapel.png
Normal file
|
After Width: | Height: | Size: 824 B |
BIN
public/sprites/themes/desert/grass0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/desert/grass1.png
Normal file
|
After Width: | Height: | Size: 572 B |
BIN
public/sprites/themes/desert/grass2.png
Normal file
|
After Width: | Height: | Size: 574 B |
BIN
public/sprites/themes/desert/grass3.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/desert/grass4.png
Normal file
|
After Width: | Height: | Size: 578 B |
BIN
public/sprites/themes/desert/grass5.png
Normal file
|
After Width: | Height: | Size: 576 B |
BIN
public/sprites/themes/desert/house.png
Normal file
|
After Width: | Height: | Size: 671 B |
BIN
public/sprites/themes/desert/hut.png
Normal file
|
After Width: | Height: | Size: 698 B |
BIN
public/sprites/themes/desert/moor0.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/desert/moor1.png
Normal file
|
After Width: | Height: | Size: 598 B |
BIN
public/sprites/themes/desert/moor2.png
Normal file
|
After Width: | Height: | Size: 605 B |
BIN
public/sprites/themes/desert/moor3.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/desert/moor4.png
Normal file
|
After Width: | Height: | Size: 593 B |
BIN
public/sprites/themes/desert/moor5.png
Normal file
|
After Width: | Height: | Size: 602 B |
BIN
public/sprites/themes/desert/rock0.png
Normal file
|
After Width: | Height: | Size: 622 B |
BIN
public/sprites/themes/desert/rock1.png
Normal file
|
After Width: | Height: | Size: 659 B |
BIN
public/sprites/themes/desert/rock2.png
Normal file
|
After Width: | Height: | Size: 685 B |
BIN
public/sprites/themes/desert/tree.png
Normal file
|
After Width: | Height: | Size: 639 B |
BIN
public/sprites/themes/desert/water0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/desert/water1.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/desert/well.png
Normal file
|
After Width: | Height: | Size: 646 B |
BIN
public/sprites/themes/easter/cave.png
Normal file
|
After Width: | Height: | Size: 917 B |
BIN
public/sprites/themes/easter/chapel.png
Normal file
|
After Width: | Height: | Size: 807 B |
BIN
public/sprites/themes/easter/grass0.png
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
public/sprites/themes/easter/grass1.png
Normal file
|
After Width: | Height: | Size: 601 B |
BIN
public/sprites/themes/easter/grass2.png
Normal file
|
After Width: | Height: | Size: 609 B |
BIN
public/sprites/themes/easter/grass3.png
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
public/sprites/themes/easter/grass4.png
Normal file
|
After Width: | Height: | Size: 609 B |
BIN
public/sprites/themes/easter/grass5.png
Normal file
|
After Width: | Height: | Size: 614 B |
BIN
public/sprites/themes/easter/house.png
Normal file
|
After Width: | Height: | Size: 667 B |
BIN
public/sprites/themes/easter/hut.png
Normal file
|
After Width: | Height: | Size: 701 B |
BIN
public/sprites/themes/easter/moor0.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/easter/moor1.png
Normal file
|
After Width: | Height: | Size: 599 B |
BIN
public/sprites/themes/easter/moor2.png
Normal file
|
After Width: | Height: | Size: 605 B |
BIN
public/sprites/themes/easter/moor3.png
Normal file
|
After Width: | Height: | Size: 487 B |
BIN
public/sprites/themes/easter/moor4.png
Normal file
|
After Width: | Height: | Size: 599 B |
BIN
public/sprites/themes/easter/moor5.png
Normal file
|
After Width: | Height: | Size: 603 B |
BIN
public/sprites/themes/easter/rock0.png
Normal file
|
After Width: | Height: | Size: 622 B |
BIN
public/sprites/themes/easter/rock1.png
Normal file
|
After Width: | Height: | Size: 653 B |
BIN
public/sprites/themes/easter/rock2.png
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
public/sprites/themes/easter/tree.png
Normal file
|
After Width: | Height: | Size: 797 B |
BIN
public/sprites/themes/easter/water0.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/easter/water1.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
public/sprites/themes/easter/well.png
Normal file
|
After Width: | Height: | Size: 645 B |
BIN
public/sprites/themes/halloween/cave.png
Normal file
|
After Width: | Height: | Size: 894 B |
BIN
public/sprites/themes/halloween/chapel.png
Normal file
|
After Width: | Height: | Size: 809 B |
BIN
public/sprites/themes/halloween/grass0.png
Normal file
|
After Width: | Height: | Size: 486 B |