From 8f98f7a0814d0a8a2af2780d6eddb75935f4b1cf Mon Sep 17 00:00:00 2001 From: phungs Date: Tue, 14 Jul 2026 22:57:32 -0700 Subject: [PATCH] docs: correct the "Act 1 idles beneath Act 2" premise; record the launch runway MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three docs claimed Act 1 keeps running during Act 2. It does not. `main.rs:555` takes the voyage branch and `main.rs:1018` continues, while both `game_tick_with_context` call sites sit at `:1253`/`:1608` — after it. Act 1 is frozen, and permanently (`vessel_launched` is never unset). The `main.rs` comment's "Act 1 systems idle untouched beneath it" is where this started: "idles untouched" reads as "keeps running", four lines above the `continue` that proves otherwise. It propagated into the dossier and then into the Act 2 braiding exploration, whose "Act 1 output is stranded with nowhere left to go" premise is the sole justification for the "Act 1 bridges" Phase 2 item in #734. There is no stranded output, so that item has no premise and must be re-argued as new content rather than reuse. - src/main.rs: state the actual control flow, with a note against reintroducing the phrasing - docs/dossiers/act2-pilgrimage.md: fix the interrelations diagram and the "During" bullet (living doc — corrected in place) - docs/explorations/2026-07-05-act2-systems-braiding.md: prepend a correction block; the wrong paragraph is preserved verbatim as the record of how the item came to be proposed. Names the live question the exploration should have asked: is it right that the hero goes inert for a 3-7 month era? - docs/decisions.md: new entry recording the 250k PR runway as arithmetic (302 PR/hr peak -> ~828h ~= 34.5 calendar days ~= 5 weekly check-ins, per the 7-day grant cap), why no simulator can or should answer it (pure fn + integer division on wall clock, zero RNG), and the resulting scope limit on balance-sim No behavior change. fmt + clippy -D warnings clean. Co-Authored-By: Claude --- docs/decisions.md | 14 +++++++++++ docs/dossiers/act2-pilgrimage.md | 12 +++++++--- .../2026-07-05-act2-systems-braiding.md | 24 +++++++++++++++++++ src/main.rs | 13 +++++++--- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index 60b111c9..58a7bef1 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -630,6 +630,20 @@ The Act 2 launch gate is simply **holding 250,000 prestige rank at the moment of **System**: vessel (`src/vessel/`, launch gate). +### Vessel Launch Runway: ~828 Hours of Calendar Time — Arithmetic, Not a Simulation + +The 250,000 PR gate is reachable, and the answer is **closed-form rather than empirical**. The Loom's WR→PR conversion is the dominant endgame PR source: `wr_to_pr_per_hour(wr) = wr × (1 + wr/100)` (`src/loom/logic.rs:811`), documented peak **131 WR/hr → 302 PR/hr**. The grant (`src/core/tick_stages.rs:1235-1248`) computes `fill_secs = 3600 / pr_per_hour`, then adds `elapsed / fill_secs` PR, where `elapsed = (now - wr_pr_last_granted_at).min(604_800)` — **wall-clock seconds, capped at 7 days**. + +At peak: `250,000 ÷ 302 ≈ 828 hours ≈ 34.5 days` of *calendar* time, accruing with the game closed. The 7-day cap grants at most `302 × 168 ≈ 50,700` PR per catch-up, making the gate roughly **five weekly check-ins**. A player who leaves for a month and returns collects one week, not four — that cap is the only behavioral demand the runway makes. + +**Why this is not a simulator question**: there is no RNG in that path. `wr_to_pr_per_hour` is a pure function of WR; the grant is integer division on wall-clock elapsed. Nothing is emergent, so simulation can reveal nothing that division cannot. Worth recording because the headless simulator *structurally cannot* answer it: `src/bin/simulator/strategy.rs:361-363` notes the Loom's pattern sustain runs on wall clock "which doesn't advance meaningfully in the headless simulator" and injects pattern completions instead. Two 3,000-hour runs started at P50,000 and P250,000 with different seeds returned `pr_earned` of 17,995 and 17,994 — identical, because that PR came from injected challenge wins at ~6 PR/hr, not from the Loom. The simulator is not broken; it is answering a different question. + +**Scope of `balance-sim`, therefore**: it validates Act 1 progression to Z50 / Ascension X — the 28-pattern and Ascension X *prerequisites* of the gate. It does not and should not validate the PR runway. **Do not read a green balance-sim run as evidence about Act 2's entrance.** + +**Alternatives considered**: giving the simulator a virtual wall clock so the Loom economy runs headless (rejected for this purpose — it would spend real effort reproducing a closed-form constant; revisit only if the Loom gains RNG or cross-system feedback that makes its output genuinely emergent); leaving the runway unrecorded (rejected — it was mistaken for an open empirical question and briefly treated as a release blocker, which is what prompted this entry). + +**System**: vessel (launch gate) × loom (WR→PR) × simulator scope. + ### Act 2 Souls: The Covenant — Nothing Harms a Soul While You Are Away A hard, CI-enforced invariant: **no tick-driven code path may reduce the roster.** Nights, weather, drift, hold-station, and offline resolution never touch souls; a property test simulates arbitrary offline windows and asserts roster count is invariant. Souls are lost **only in authored scenes** attached to named threats — the threat was on the junction card, the road was chosen, and the scene offered a priced alternative. There is no dice-based loss. A loss is memorialized: the soul's name is carved into the hull art for the rest of the game (Act 3 included), their arc becomes a memorial manifest line, and their counsel lines go silent. diff --git a/docs/dossiers/act2-pilgrimage.md b/docs/dossiers/act2-pilgrimage.md index 5a1237ad..1334c736 100644 --- a/docs/dossiers/act2-pilgrimage.md +++ b/docs/dossiers/act2-pilgrimage.md @@ -283,7 +283,7 @@ Act 1 (everything) Act 2: launch → crossing 1 → the Ferryman 250,000 PR (burn) ─┘ │ │ (Act 3 hook #1 — Zone 50 kill ─► signal ───────┘ │ spec-normative) ▼ │ - Deep/Loom/etc. idle beneath ◄── untouched Colony founded ◄────────┘ + Deep/Loom/etc. STOP (frozen, no ticks) Colony founded ◄────────┘ │ ┌───────────────────► Reckoning: Salvage │ ─► Drive / Shipwright / Ward @@ -304,8 +304,14 @@ Act 1 (everything) Act 2: launch → crossing 1 → the Ferryman - **In**: the launch gate deliberately braids *all* of Act 1 (Loom, Ascension, PR economy, Zone 50) into one burn — the act's strongest cross-system edge. - **During**: zero mechanical interaction with Act 1 — deliberate ("one-way - passage"); Act 1 idles untouched beneath. Narrative callbacks only - (Torvald is the Deep guild's captain). + passage"). Act 1 does not *idle* beneath: it **stops**. `main.rs:555` takes + the voyage branch and `continue`s past both `game_tick_with_context` call + sites, so no zone ticks, no PR accrues, no Haven builds — and permanently, + since `vessel_launched` is never unset. The hero the player spent hundreds of + hours building is inert for the whole era. Confirmed intended (2026-07-14); + noted here because the earlier "idles untouched" phrasing was read as "keeps + running" and became the (void) premise for the "Act 1 bridges" Phase 2 idea. + Narrative callbacks only (Torvald is the Deep guild's captain). - **The ferry loop is the act's second major cross-system braid**, but an internal one: Reckoning spend (Drive/Shipwright/Ward) feeds directly back into how much of the old world the next crossing can rescue before the diff --git a/docs/explorations/2026-07-05-act2-systems-braiding.md b/docs/explorations/2026-07-05-act2-systems-braiding.md index b9a371ca..91167e37 100644 --- a/docs/explorations/2026-07-05-act2-systems-braiding.md +++ b/docs/explorations/2026-07-05-act2-systems-braiding.md @@ -82,6 +82,30 @@ most of Act 1's growth systems are already maxed.** Ascension X is the level cap. 28/28 patterns is Loom's completion state. The two hardest gates in the game are, definitionally, *finished* the moment Act 2 opens. +> **⚠️ CORRECTION (2026-07-14) — the paragraph below is factually wrong. Do +> not build on it.** +> +> Act 1 does **not** keep running during Act 2. `main.rs:555` takes the voyage +> branch on `vessel_launched && act2_enabled()` and `main.rs:1018` `continue`s, +> while both `game_tick_with_context` call sites sit at `main.rs:1253` / `:1608` +> — *after* it. Zones don't tick, Power Cores don't generate, Haven doesn't +> build, nothing is gettable. Act 1 is **frozen**, and permanently so +> (`vessel_launched` is only ever set `true`). Confirmed intended design, +> 2026-07-14. +> +> **What this voids:** there is no stranded output to redirect, so the "second +> outlet" framing below — and the "Act 1 bridges" Phase 2 item it justified +> (#734) — has no premise. Any such bridge is *new content*, not reuse, and +> must be re-argued from scratch on its own merits. +> +> **What survives:** the opening observation still holds — Ascension X and 28/28 +> patterns *are* maxed at launch. But they're not "stranded and still +> producing"; they're switched off. The real question this exploration should +> have asked: **is it right that the hero a player built over hundreds of hours +> goes inert for a 3–7 month era?** That is a live design question, unanswered. +> +> Preserved verbatim below as the record of how the item came to be proposed. + So a player deep in a 3–5-month Ferryman era who keeps playing Act 1 in parallel (zones still tick, Power Cores still generate PR, Haven rooms still build, Fishing/Challenges/Achievements are all still gettable) is diff --git a/src/main.rs b/src/main.rs index 6dd6a2ff..14b5489e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -549,9 +549,16 @@ fn main() -> io::Result<()> { 'game_loop: loop { // ── Act 2: The Crossing ───────────────────────────── // After the launch burn, the loop belongs to the - // voyage: chart, holds, junctions. Act 1 systems idle - // untouched beneath it; spec 6 (the Going-Dark) owns - // their eventual wind-down. + // voyage: chart, holds, junctions. This branch ends in + // `continue`, so everything below it — including both + // `game_tick_with_context` call sites — is skipped while + // launched. Act 1 is *frozen*, not idling: no zones + // tick, no PR accrues, no Haven builds. And because + // `vessel_launched` is only ever set true (never unset), + // that is permanent for this character. Do not write + // "Act 1 idles beneath" here — that phrasing has + // misled design docs into assuming Act 1 output keeps + // accumulating during the era. It does not. if state.vessel_launched && vessel::act2_enabled() { // The 5-beat launch transition (spec 4) plays once, // between the burn and the first Voyage frame. It