Keep money mattering at the top, and fix the instruments that hid it

Both settings now carry a charge levied by standing itself, which no purchase
ends. Corporate Ladder's steps on money (1200/-60, 2400/-120, 3600/-240): a flat
charge cannot flatten a slope, since late income scales with how well the player
plays, and the flat charge needed to stop an optimiser accumulating put ordinary
archetypes below zero for 44% of a run. Stepped, the balance settles around
$4,250 and ordinary play comes out better than before it existed. The Frontier's
is flat at -4 a run, because its late game never accumulated in the first place.

Found in the first two human sessions of this work:

- A career saved before a pack gained a stat had no path for it, and conditions
  compare numbers only, so every event, option and upkeep entry gated on a new
  stat silently did not exist for that run. Loading now fills those in.
- 'Wrap up my career' sat immediately after the last option in tab order, so one
  Tab too many and Enter read as the game ending at day 31. It goes last, and
  the retrospective says plainly that it is a summary.
- A 181-turn session ran against a stale bundle and the change under test never
  fired. Every logged turn now records app_version and build.
- src/version.js had reported 0.3.0 since 0.3.0, while playtesters were told to
  check the status bar. A test now holds it to package.json.
- 'Put money against the book' was shown locked to a player who owed nothing,
  six times. Options gated on a state the player cannot choose to enter are now
  hidden rather than greyed.

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 23:07:35 -04:00
co-authored by Claude Opus 5
parent 5d645e6452
commit d84ae495f4
17 changed files with 318 additions and 23 deletions
+62
View File
@@ -548,6 +548,32 @@ direction is that rising standing brings rising expenses — the car, the place
live, the clothes a position expects. Upkeep entries are already gated
conditions over state, so this is content work, not an engine change.
## 37. A playtest is only as good as its instruments
The second session — 181 turns of the Frontier, the first time that pack has
been played by a human at all — ran against a **stale bundle**. The page had
been loaded before the last rebuild, and switching settings inside an open tab
does not re-fetch the script, so the run exercised everything except the change
it was meant to test. The charge that never stops fired zero times in ninety
turns where its conditions held.
Working that out took file timestamps and a simulation. It should have taken one
line of the log, so three things changed:
- **Every logged turn now records `app_version` and `build`.** The log says
which bundle produced it, and a stale session is visible immediately rather
than looking exactly like a feature that does not work.
- **`src/version.js` was lying.** It hardcoded `0.3.0` through the whole of the
0.3.1 and 0.3.2 work, while playtesters were told to check the status bar to
know what they were on. A version string that lies is worse than none, because
it is trusted. A test now holds it to `package.json`.
- **A locked door is only worth showing when it is a door.** `pay_down` — "put
money against the book" — was the most-locked option in the session, shown six
times to a player who owed nothing. Options gated on a state the player is not
in and cannot choose to enter now carry `whenLocked: 'hide'`. Gates worth
bouncing off, like a skill threshold, stay visible: that is the signal the log
exists to collect.
## 36. Standing costs money to keep
Built in both packs, with no engine change, exactly as #35 predicted.
@@ -587,6 +613,42 @@ every lifestyle tier at once into a baseline that is supposed to mean "the floor
a player faces having opted into nothing." Packs now name those paths in
`tuning.baselineExcludes`, and the suite fails if one is not declared state.
**The top of the ladder was a plateau, so one charge never stops.** The first
human play of the lifestyle system — 96 turns, Corporate Ladder — found both
purchases (the car at turn 52, the address at 75) and showed the standing
pressure working exactly as intended: "Looking the part" took 56 reputation, and
standing sagged into the low seventies on the car alone before recovering to 100
once the address was bought. But from turn 84 the run had nothing left to spend
on: every charge switches off at the top tier, and the balance simply climbed.
Money stopped mattering again, one rung higher than before.
Both packs now carry a charge levied by standing itself, which no purchase ends.
They are shaped differently, and the difference is measured rather than stylistic:
- **Corporate Ladder steps on money.** A flat charge cannot flatten a slope —
late income comes from choices and scales with how well the player plays, so
the flat charge needed to stop an optimiser accumulating (-360 a week) put
ordinary archetypes below zero for 44% of a run and ended them $1,385 in debt.
Stepping on money ($1,200/-60, $2,400/-120, $3,600/-240) lands it on whoever
has it: the balance settles around $4,250 and stops climbing (-3 a week), and
ordinary play comes out *better* than before the charge existed — 13% of a run
below zero against 17%, a tier-2 run ending +$175 rather than -$25.
- **The Frontier is flat, at -4 a run.** Its late game never accumulated in the
first place — a deputy who owns everything drifts 0 a run at every charge
strength tested — so there is no slope to flatten. The charge is there to keep
money live, and break-even at the top is the intent.
**A save written before a stat existed silently loses the content gated on it.**
Found while working out how to playtest this: `loadLocal` returns the saved
state verbatim, and `conditions.js` compares numbers only — so for a career
saved before `lifestyle` existed, both `lifestyle < 2` and `lifestyle >= 1` are
false. The car lot never fires, the purchase never unlocks, the charge never
lands, and nothing says so. Resuming a save would have shown a playtester none
of this feature while reporting nothing wrong. Loading now fills in any path the
pack has gained since (`hydrate`, in `state.js`), writes the repair back, and
does the same for an imported file. This is the price of "adding content is just
adding data", and it applies to every stat any pack adds from here on.
**And a test that had passed for two releases was measuring the wrong thing.**
"The promotion leaves a player better off" compared the end balances of promoted
and unpromoted players pooled across archetypes — but which archetypes get