Add The Frontier, a second setting, and a picker to choose between them

Cold Fork is a freight yard: 29 events across two stages, a four-day cycle, and
its own relationship and skill vocabulary. src/engine/ was not touched. Adding it
needed three changes outside the engine: one save slot per pack, app.js holding
the current pack, and turn.js no longer naming the mailroom (DECISIONS #34).
build.js now handles imports wrapped across lines. A conformance suite runs over
every registered pack. DECISIONS #35 records three calls on open questions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RxdJFbLq1rBKsUeticGV1g
This commit is contained in:
JesseMarkowitz
2026-09-12 21:03:50 -04:00
co-authored by Claude Opus 5
parent 4957c24e31
commit 7f20be83e8
25 changed files with 3015 additions and 300 deletions
+47 -27
View File
@@ -9,13 +9,14 @@ retrospective.
The engine knows nothing about offices, mailrooms or bosses. A **setting is a
content pack** — characters, events, choices, stat names and tuning, all data.
`corporateladder` is the default pack; a Wild West or lemonade-stand pack would
be new data and no new code.
Two ship: **Corporate Ladder**, a modern office and a mailroom, and **The
Frontier**, a freight yard at the end of a stage line. They share every line of
engine code and no content at all.
## Status
Engine and the first content pack are built and tested. No UI yet — the game is
currently playable only from a test harness.
Engine, interface and two content packs, all built and tested, and played in a
real browser.
| Piece | State |
| --- | --- |
@@ -33,7 +34,10 @@ currently playable only from a test harness.
| Repetition analytics (`npm run analyze`) | done |
| Version and build shown on screen | done |
| Keyboard play (Enter / Tab) | done |
| Played in a real browser | done — first playtest 2026-09-09 |
| Second content pack — The Frontier, 29 events, two tiers | done |
| Setting picker, one save slot per pack | done |
| Pack conformance suite (every pack, every check) | done |
| Played in a real browser | Corporate Ladder yes, first playtest 2026-09-09; **The Frontier not yet** |
The first playtest confirmed the interface, saves and the exported log all work
in a real browser. Its findings — an unexplained daily drain, no sense of the
@@ -70,9 +74,16 @@ That is one self-contained file with the stylesheet and every module inlined.
It plays by double-clicking it — no server, no network, nothing installed.
```sh
npm test # 121 tests: engine, content, UI wiring, and the build
npm test # 149 tests: engine, both packs, UI wiring, and the build
```
Tests are in three layers. `test/conformance.test.js` runs over **every pack in
the registry** and asserts only what is true of a pack because it is a pack —
validity, no dead content, the declared economic baseline, variety, replay from
seed, a way out of every event. `test/content.test.js` and
`test/frontier.test.js` hold each pack to its own tuning. The engine suite runs
against a fixture pack, so tuning a setting can never break it.
To see what a playtest actually did — turns against distinct situations, how
often each recurred, which locked gates players kept meeting, and anything they
typed into the feedback box:
@@ -90,26 +101,32 @@ used only to run the tests, the single-file build, and the log analyser.
## Where things stand
The MVP is complete and has survived three playtests. Two tiers, 31 events, a
retrospective, saves, and a feedback log that has already found one real bug.
The MVP is complete and has survived three playtests, and a second setting now
exists to prove the engine/content split holds. Adding it required **no engine
change** — and three interface changes, two of which were latent defects a
second pack made visible (a single global save slot, and the one place the UI
still named a setting). See DECISIONS.md #34.
Open questions, in the order they are likely to matter:
- **Does money stop mattering late?** A careful player ends around $8,300 over
200 turns. Tuning has been corrected twice from playtest logs and should be
judged from a session, not from simulated play — that is how the last trap got
in.
- **`skills.negotiation >= 15` gates four different early options.** The logs
show players bouncing off it repeatedly in the first thirty turns. It is
probably set too high for how slowly the skill grows.
- **Nobody uses the feedback widget.** Zero ratings across three sessions. The
locked-gate data in the log has been more useful than anything typed; the
widget may need to be more present, or may not need to exist.
- **The Frontier has never been played by a human.** Its economy is asserted by
the conformance suite and exercised by six archetypes, and that is exactly the
evidence that was not enough the last two times. It needs a session before its
numbers are believed.
- **Money stops mattering late, and it should not.** A careful player ends
around $8,300 over 200 turns. The direction is set: standing should cost
money to keep — a better car, a better place to live, better clothes — so
expenses climb as the player rises. Not built yet.
- **Dispatch is eleven events against the mailroom's nineteen.** It passes the
variety guard, but it has had far less play than the mailroom.
- **The third tier, or the second content pack.** Promotion working entirely as
data is decent evidence the engine/content split holds; a second *setting*
would be the proof.
variety guard, but it has had far less play than the mailroom. Waits on more
playtesting.
- **A third tier in either pack.** Two rungs is what both settings have. The
split is now proven across settings; it is not proven across a long ladder.
Waits until the Frontier has been played.
Settled, and not open: Corporate Ladder's negotiation gate stays as it is, and
the feedback widget stays as it is (DECISIONS #35).
## Layout
@@ -124,13 +141,16 @@ src/engine/ the game engine — imports nothing from content/, or from src/u
rng.js seeded, serializable RNG
validate.js load-time content checking
src/ui/ screens, formatting and the app controller
app.js the only module that names a content pack
screens/ the turn screen and the retrospective
app.js the only module that knows there is more than one pack
screens/ the turn screen, the retrospective, the setting picker
format.js state paths and conditions rendered as English
src/io/ local-storage save, file export/import, the feedback log
content/ content packs (settings)
src/io/ local-storage save (one slot per pack), export/import, feedback log
content/
index.js the pack registry — the only list of settings
corporateladder/ a modern office and a mailroom
frontier/ a freight yard at the end of a stage line
tools/build.js flattens everything into one self-contained HTML file
test/ engine tests against a fixture pack; content and UI tests
test/ engine tests against a fixture pack; conformance, per-pack, UI
docs/ DECISIONS.md — why things are the way they are
Planning/ the original design documents
```