ninelands-reddit/docs/submission.md
Lukas Müllner 59dde4061a docs: App-Link ist ohne Veröffentlichung privat (403)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 11:47:52 +01:00

214 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.

# Einreichung – Texte und Checkliste
Sammelstelle für alle Texte und Assets rund um Devpost und das Developer Portal. Texte auf Englisch (Jam-Vorgabe),
Erklärungen auf Deutsch. Stand: 2026-11-13.
## Developer Portal – In-app catalog
App: developers.reddit.com → `ninelands-game` → Developer Settings → In-app catalog.
| Feld | Text | Zeichen |
| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | :------ |
| Tile tagline | Claim the nine lands – a new map every day. | 43 |
| Featuring description | A fresh 9×9 map every day. Place your castle, farmers, knights and bishops, claim land and gold, earn three stars and climb today's leaderboard. | 147 |
| Description (15–200) | Daily strategy puzzle: one 9×9 map for everyone. Build your realm piece by piece, claim lands and gold, chase three stars and keep your streak alive. | 151 |
| Game category | Game → Strategy | – |
| App icon | Icon aus dem Hauptspiel (Ninelands) | – |
### Assets
Erzeugen mit `npm run capture` → `dist/marketing/` (nicht im Repo). Vor der Einreichung neu aufnehmen (z. B. mit
Winter-Brett).
| Datei | Feld | Vorgabe Portal | Stand |
| :-------------- | :------------------- | :----------------------------------------------------- | :------------------------ |
| `featuring.mp4` | Featuring asset | MP4, 3:2, 1000–1500 px breit, 6–15 s, ≤ 30 fps, ≤ 3 MB | 1500×1000, 11,3 s, 1,7 MB |
| `fallback.gif` | Fallback (animiert) | 3:2, 1000–1500 px, 3–10 s Schleife, Ziel ≤ 2 MB | 1000×667, 6 s, 1,8 MB |
| `fallback.png` | Fallback (Standbild) | 1500×1000 empfohlen, ≤ 800 KB | 52 KB |
| `tile.png` | Tile image | 560×256 empfohlen, ≤ 800 KB | 58 KB |
Nur die Spielfläche, keine Menüs (Wunsch Besitzer). Karte vom 2026-10-10 – läuft nie als Tageskarte (kein Spoiler).
## Devpost – Project overview
### Elevator pitch (≤ 200 Zeichen)
Empfehlung (176 Zeichen):
> Ninelands is a daily strategy puzzle on Reddit: one 9×9 map for everyone, place castles, farmers and knights to
> claim lands and gold, earn three stars and climb the leaderboard.
Alternativen:
- (181) A daily port of the strategy game Ninelands: everyone gets the same 9×9 map each day – build your realm, chase
three stars, keep your streak and compare strategies in the comments.
- (141) One map. Nine lands. Every day. Build your realm piece by piece, chase three stars and climb today's
leaderboard – right inside a Reddit post.
### About the project (Markdown, LaTeX erlaubt)
> Abschnitt „Inspiration“ bei Bedarf persönlicher machen (eigene Worte des Besitzers). Ob die KI-Unterstützung
> erwähnt wird, entscheidet der Besitzer (die Regeln erlauben technische Hilfe, solange Ideen und Rechte beim
> Teilnehmer liegen).
```markdown
## Inspiration
Ninelands started as a strategy board game on a 9×9 board split into nine lands: you place a castle, farmers,
knights and bishops, every piece claims land, and the goal is to rule the nine lands. It runs on the web, desktop,
Android and itch.io – and its most popular mode has always been the **map of the day**, where everyone plays the same
map and compares results.
Reddit felt like the natural home for that mode. A daily map is a shared puzzle, and a shared puzzle wants a place to
talk about it: _Where did you put your castle? How did you get 9/9 lands?_ So we built **Ninelands for Reddit** – a
focused, bite-sized daily edition that lives inside a post, with the comment thread as the place to compare realms.
## What it does
- **One 9×9 map per day, the same for everyone.** A new post appears automatically every day.
- **Easy to start, hard to master.** Tap to preview what a piece would claim and how much gold it brings; tap again to
place it. The line below the board explains why a cell fits or not – no wall of rules.
- **Three stars per map:** reach the gold target, rule the lands target, and both in one game. Targets come from
computer games on that very map, so every day is fair.
- **Leaderboard and streaks.** Only your first game counts. More stars first, then more gold, then the earlier
submission.
- **Your realm.** Unlock board themes with your streak and new banners and factions (orcs, pirates) with your stars.
- **Reddit-native.** Post your result to the comments with one tap, earn a 🔥 streak flair, and the best player of the
day wears 👑 _Ruler of the day_ the next day.
## How we built it
- **Devvit Web** with plain TypeScript, bundled by esbuild; no UI framework. An inline start screen in the feed, the
full board in expanded mode.
- **The original engine, untouched.** The Ninelands engine is pure TypeScript (seeded RNG, `legalMoves`,
`applyMove`, replay). A sync script copies it – plus the SVG board renderer – from a tagged release, so the Reddit
edition plays exactly like the original and fixes flow in one direction only.
- **A server that trusts nothing.** The client sends only its moves. The server replays them with the same engine and
computes gold, lands and stars itself, so results cannot be faked.
- **Redis leaderboards.** Each day is a sorted set. To rank by stars, then gold, then submission time in a single
score, we use
$$\text{score} = 100\,000 \cdot \text{stars} + \text{gold} + \frac{1}{\text{seq} + 1}$$
where $\text{seq}$ is the running number of the submission. The fraction lies in $(0, \tfrac12]$, so it only breaks
ties – and it makes every score unique, which turns a player's rank into a simple
$\text{rank} = \text{count} - \text{zRank}$.
- **First attempt only**, enforced atomically with `hSetNX` – two parallel submissions can never both count.
- **Daily posts** via the Devvit scheduler, **Devvit Journeys** for analytics (journey starts when the castle is
placed, a progress event per star, the end carries the gold as score).
- **Privacy by design:** all user data expires 30 days after a player's last game.
## Challenges we ran into
- **Making the daily map unspoilable.** The website has a map of the day too – including a replay of the best game.
The Reddit edition therefore uses its own seed, so its daily map can never be looked up elsewhere.
- **Knowing when to stop.** In the original, a game ends when no move is left. On a phone that can drag on, especially
under the law _One farm per land_, where only costly knights remain. We added an _End game_ button, and the game now
detects when no remaining move earns gold and suggests ending.
- **Fitting a strategy board into a post.** The board, the goals and nine piece costs have to be readable on a phone in
portrait mode. Container queries keep the board as large as possible without pushing the hint line away.
- **Platform details:** a template workflow our CI runner didn't understand, Redis commands that are not enabled for
every app, `localStorage` that is cleared on every app update (so all choices live in Redis), and an analytics router
that expects Express while our server has no framework – we rebuilt its five endpoints by hand.
## What we learned
- A daily game lives from **one shared moment**: same map, same day, one first attempt. Every feature we kept serves
that moment; menus and settings did not make the cut.
- Contextual hints beat tutorials. Showing _why_ a move doesn't fit teaches the rules faster than any rules screen.
- Porting is easiest when the game logic is pure: the engine moved to a new platform without a single change.
## What's next
- Seasonal events beyond the winter festival, and more unlockable banners and boards.
- A weekly challenge with a twist (fog of war, bandit camps) – both already exist in the original engine.
- An optional duel against the computer after the daily map.
```
### Built with (Tags, max. 25)
typescript, javascript, html5, css3, svg, node.js, devvit, devvit-web, reddit, reddit-api, redis, devvit-scheduler,
devvit-journeys, esbuild, biome, playwright, ffmpeg, pixel-art
### „Try it out“-Links
- App: `https://developers.reddit.com/apps/ninelands-game`
- Spielen: `https://www.reddit.com/r/Ninelands/` (angelegt 2026-11-13, Restricted; erst eintragen, wenn der erste Post
steht)
- Original-Spiel: `https://ninelands.stackteam.at`
- Code: Repo ist privat – nur eintragen, wenn es öffentlich wird (optional)
### Devpost – Project media und Video
Erzeugen mit `npm run capture:trailer` → `dist/marketing/` (nicht im Repo, ≈ 2 min). Das echte Spiel läuft in einer
Bühne (links Untertitel, rechts Handy), API als Attrappe, ein Bot spielt die Karte vom 2026-10-10 (3 Sterne, beendet
per „End game“). Leaderboard-Namen sind erfunden.
| Datei | Wofür | Vorgabe | Stand |
| :-------------------- | :------------------------------------------- | :--------------------------------------- | :---------------------------- |
| `trailer.mp4` | Video (Vimeo/YouTube, Devpost-Link) | < 1 min, öffentlich | 1920×1080, ≈ 47 s, ≈ 9 MB |
| `vimeo-cover.png` | Vorschaubild (Thumbnail) auf Vimeo | 16:9, 1920×1080 | Logo + Brett mit 3 Sternen |
| `gallery/00…06-*.png` | Devpost „Image gallery“ (Reihenfolge = Name) | JPG/PNG/GIF, ≤ 5 MB, 3:2 empfohlen, ≤ 15 | 7 Bilder, 1800×1200, ≤ 150 KB |
Galerie: 00 Titel, 01 Tagespost, 02 Land beanspruchen (Vorschau), 03 drei Sterne, 04 Ergebniskarte mit Bestenliste
und Freischaltung, 05 Realm, 06 Schluss. Ergänzen lassen sich echte Reddit-Screenshots (Kommentar im Thread, Flair).
**Bildunterschriften (Devpost-Caption je Bild, Englisch):**
| Bild | Caption |
| :------------------- | :--------------------------------------------------------------------------------------------------------- |
| `00-cover.png` | Ninelands – a daily strategy game on Reddit. One 9×9 map a day, the same for everyone. |
| `01-daily-post.png` | The daily post: today's map, its law, three goals, your streak and today's best – one tap to play. |
| `02-claim-land.png` | Place castle, knights, farmers and bishops to mine gold. A live preview shows what each move earns. |
| `03-three-stars.png` | One star each for the gold goal, for ruling all nine lands, and for doing both in one game. |
| `04-result.png` | The result card: stars, rank, streak and new unlocks. Post your result to the comments with one tap. |
| `05-realm.png` | Your realm: colours, factions, boards and banners, unlocked by stars and streaks. Same rules for everyone. |
| `06-outro.png` | A new map every day at 00:01 UTC on r/Ninelands. A port of Ninelands (ninelands.stackteam.at). |
**Eigene Reddit-Aufnahmen (optional):** hochkant (Handy oder Handy-Ansicht im Browser) als
`dist/trailer/input/feed.mp4` (Tagespost im Feed, ≤ 8 s) und `dist/trailer/input/comment.mp4` (der Ergebnis-Kommentar
im Thread, ≤ 8 s) ablegen (auch `.mov`/`.webm`), dann `npm run capture:trailer` neu laufen lassen – sie erscheinen im
Handy an passender Stelle. Keine aktuelle Tageskarte zeigen (Spoiler) und keine fremden Nutzernamen.
**Vimeo-Beschreibung** (Musik ist CC BY-SA 4.0, Nennung nötig):
```text
Ninelands – a daily strategy game on Reddit (Devvit Web). A new 9×9 map every day, one shared leaderboard per
subreddit, streaks, unlockable realms and your result in the comments. Port of Ninelands (ninelands.stackteam.at).
Music: "Dreamscape (part I)" by Vee Ray, CC BY-SA 4.0 (re-encoded).
Graphics: "Mini World Sprites" by Shade and octoshrimpy, CC0. Font: Pixelify Sans, SIL OFL 1.1.
```
### Noch zu schreiben
- **Portierung angeben** (Kategorie „Best Ported Daily Game“): Ninelands gehört StackTeam; erklären, was seit dem
11. Nov. neu entstanden ist (Pflicht für bestehende Projekte): neue Codebasis auf Devvit Web, neuer Tagesmodus mit
eigenem Seed, serverseitig nachgespielte Bestenliste in Redis, Streak, Realm-Freischaltungen, Flair, Ergebnis als
Kommentar, Devvit Journeys. Übernommen: Engine und Brett-Darstellung (Kopie mit festem Stand `v0.11.0`), Sprites,
Musik.
- **Testanleitung** für die Jury (kurz, Englisch).
## Checkliste Einreichung (Abgabe 9. Dez. 2026, 03:00 MEZ)
Pflicht laut offiziellen Regeln:
- [ ] Devpost: Text-Beschreibung (Funktionen)
- [ ] App-Link: `https://developers.reddit.com/apps/ninelands-game` (entsteht beim Upload; ohne Anmeldung 403 „You do not have permission…“, weil nicht veröffentlicht – so gewollt, die Regeln verlangen trotzdem nur diesen Link, Reddit-Admins sehen die Seite)
- [ ] `README.md` im Repo-Wurzelverzeichnis (Spiel und Anleitung) – vorhanden, vor Abgabe prüfen
- [ ] Demo: Link zum Subreddit (`r/Ninelands`, öffentlich, < 200 Mitglieder) **und** zu einem Post mit dem Spiel
- [ ] Angabe „Portierung“ + was im Jam-Zeitraum neu entstanden ist
Optional:
- [ ] Video < 1 min, öffentlich auf YouTube/Vimeo (die Jury darf allein danach urteilen)
- [ ] Öffentliches Repo (Repo ist derzeit privat)
- [ ] Developer-Platform-Feedback-Umfrage (eigener Preis)
Nicht tun:
- [ ] **Kein `devvit publish`** – hochladen und playtesten reicht, die App darf privat bleiben.
- [ ] Während der Bewertung (9.–16. Dez.) keine riskanten Uploads; Tagesposts müssen weiterlaufen.
Besitzer entscheidet bei der Anmeldung: Einzelperson oder Organisation (StackTeam) – betrifft Preisgeld und
Steuerformulare (W-8BEN).