From d6ba26a9c1876d8e8f8d806f95de0167550dd970 Mon Sep 17 00:00:00 2001 From: fireshaper Date: Sat, 10 Oct 2026 16:07:18 -0400 Subject: [PATCH] Step 17.3: sim: tutorial timing The tutorial timing test now sums the slowest job on each of the five runs' boards and keeps the total under 7 real minutes. Co-Authored-By: Claude Opus 5.5 --- memory-bank/progress.md | 2 +- packages/sim/test/tutorial.test.ts | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/memory-bank/progress.md b/memory-bank/progress.md index 8850c5a..7fcafc1 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -416,7 +416,7 @@ Spec: `memory-bank/change-requests/CR-017-tutorial-xp-skill-prompt.md` (received - [x] **Step 17.1 — Content: tutorial settings.** GameConfig: `tutorialRunsBeforeDeal` 5 (was 4) and a new `tutorialXpMultiplier` 2 (at least 1; used from 17.2). Pulled forward so the game keeps working: the deal no longer waits for the loaner to be back at Earth (decision 0.5.108) in the engine (`isDealAvailable`) and the balance simulator, since five runs end at the Moon; accepting it already puts the avatar on the Courier at the Earth bay. Balance medians: deal 3.7 min, first purchase 92.6 (45–95), discovery 49.6, loan 138.5, four ships 136 vs 138. Tests: `packages/content/test/config.test.ts` (five runs at double XP; a multiplier under 1 is rejected); the engine's deal tests now expect the deal after five runs ending at the Moon (not after four), after three with the three-run config, and accepting with the loaner at the Moon to put the avatar and the Courier at Earth. - [x] **Step 17.2 — Sim: tutorial XP and the level-1 guarantee.** `deliveryXpFor(record, tier, content)` in `resolution.ts`: a delivery's XP, × `tutorialXpMultiplier` (rounded) on tutorial runs; `resolveDispatch` uses it. The multiplier stays at 2: an Earth–Moon Standard run is 10 XP, so the cheapest five runs make exactly 100 XP, the level-1 threshold (a level gives 2 points). Tests (`packages/sim/test/tutorial-xp.test.ts`): a tutorial run pays exactly 2 × a normal run's XP for the same route and cargo; over 50 board periods, taking the lowest-XP job on every board for five runs (the scripted "Unmarked crates" board included) always reaches level 1 with at least one point. -- [ ] Step 17.3 — Sim: tutorial timing +- [x] **Step 17.3 — Sim: tutorial timing.** The CR-001 Step 10A.3 timing test now covers five runs (Earth → Moon → Earth → Moon → Earth → Moon), each taking the slowest job on its board, and requires the total under 7 real minutes (it was four runs under 6), keeping "own a ship in under 10 minutes". Test: `packages/sim/test/tutorial.test.ts`. - [ ] Step 17.4 — Engine: deal availability and placement - [ ] Step 17.5 — Client: Pilots tab badge - [ ] Step 17.6 — Client: skill point pop-up diff --git a/packages/sim/test/tutorial.test.ts b/packages/sim/test/tutorial.test.ts index 7ef2025..a89ab83 100644 --- a/packages/sim/test/tutorial.test.ts +++ b/packages/sim/test/tutorial.test.ts @@ -120,11 +120,16 @@ describe("tutorial board v2", () => { expect(full!.payout / tripMinutes(full!)).toBeGreaterThan(light!.payout / tripMinutes(light!)); }); - it("keeps the four slowest possible tutorial runs under 6 real minutes in total", () => { - const slowest = Math.max( - ...[atEarth, atMoon].map((input) => tripMinutes(generateTutorialBoard(input, content)[2]!)), - ); - expect(4 * slowest).toBeLessThan(6); + it("keeps the five slowest possible tutorial runs under 7 real minutes in total (CR-017)", () => { + // Five runs: Earth → Moon → Earth → Moon → Earth → Moon, each taking its slowest (full) job. + expect(content.config.tutorialRunsBeforeDeal).toBe(5); + let total = 0; + for (let run = 0; run < content.config.tutorialRunsBeforeDeal; run++) { + const input = { ...(run % 2 === 0 ? atEarth : atMoon), runsCompleted: run }; + total += Math.max(...generateTutorialBoard(input, content).map(tripMinutes)); + } + // Leaves room to own a ship in under 10 minutes (CR-001 Step 10A.3). + expect(total).toBeLessThan(7); }); });