diff --git a/DECISIONS.md b/DECISIONS.md index 401dcfb..cd66d31 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -983,3 +983,8 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md` - **Acknowledging only clears finished jobs**; a ship still in the shop keeps its job even if its id is sent. - **The modal can open for shop news alone** (no deliveries), and the acknowledged count includes cleared upgrades. - **The HQ card only appears while a ship is in the shop**, unlike the always-on pilot rest card: the shop is an occasional action, rest is a rhythm. + +## Step 10I.9 + +- **GDD §8 is left to the designer**, as the CR says; it doesn't mention upgrades yet, so the "confirm it matches" check is flagged for the user rather than written here. +- **The manual check was scripted** (`cr009-smoke.mjs`). It found that with 10-minute shop times and 10-minute boards, the heavy job you spot before upgrading always expires before the ship leaves the shop; the script finds a fresh 21–23 t job afterwards. Whether to keep that tension is a Phase 12 call. diff --git a/memory-bank/implementation-plan.md b/memory-bank/implementation-plan.md index 33ff033..b399a91 100644 --- a/memory-bank/implementation-plan.md +++ b/memory-bank/implementation-plan.md @@ -168,6 +168,7 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple - GameConfig fields: time compression factor; game epoch as two fields (real start timestamp and the in-game ephemeris date it maps to); starting credits; tutorial payout share; contract board size; contract board period (real minutes — contracts expire at the end of their period); first-contact chance; first-contact payout multiplier; contract mass range; Long Haul distance cut-offs (one per level); XP per delivery formula inputs; XP needed per pilot level; skill points per level; hire cost per pilot; pilot pay per delivery (flat fee). - **Test:** Unit tests confirm each schema accepts a valid example and rejects an object missing a required field. - **Amended by CR-004:** GameConfig gains `dutyLimitGameHours`, `longHaulDutyBonusGameHours` and `restGameHours` (Step 10D.1). +- **Amended by CR-009:** Content gains the Upgrade schema (`upgradeSchema`, `SHIP_STATS`, per-model overrides), the five upgrades, and `upgradeLevels` cost/shop-time config (Step 10I.1). ### Step 2.2 — Add the five locations - Add data for Earth, Moon, Mars, Ceres Station, and Jupiter Cloud Platform following the destinations table in the GDD. @@ -224,6 +225,7 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple - Add a function: travel time = distance ÷ ship cruise speed + ship takeoff/landing overhead. Distance is measured at departure time (no mid-flight recalculation). - **Test:** For fixed inputs, the result matches a hand-calculated value. A faster ship always arrives sooner on the same route. Overhead dominates on Earth→Moon (overhead is more than half of total time for the Courier). - **Amended by CR-001:** Travel time also includes cargo handling: + mass × handling time per tonne (Step 10A.2, decision 0.5.31). +- **Amended by CR-009:** Travel time takes effective stats, including the ship's own handling time per tonne (Step 10I.2). ### Step 3.6 — Fuel cost - Add a function: fuel cost = distance × ship fuel cost per million km × origin location's launch multiplier. @@ -232,6 +234,7 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple ### Step 3.7 — Range and landing eligibility - Add a function that decides whether a ship can fly a route at a given time, returning either "allowed" or a specific reason: out of range, or cannot land at destination (landing class). - **Test:** A Courier can fly Earth→Moon and Moon→Earth. A Courier is out of range for Mars at its closest. A test-only vacuum ship fixture is rejected at Earth with the cannot-land reason. At Jupiter's farthest point from Earth, only the Bulk Hauler is in range. A Freighter can reach Ceres. (These confirm the Step 2.3 number choices; adjust content if they fail.) +- **Amended by CR-009:** Range checks use effective stats (Step 10I.2). ### Step 3.8 — Contract model and payout - Define a Contract shape: id, origin, destination, cargo type, tier, mass, payout, required skill and level, required Long Haul level, offered-at time, expires-at time (end of its board period), first-contact flag. @@ -264,6 +267,7 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple - **Test:** One test per failure reason, each constructing a scenario that triggers exactly that reason. One test for a fully valid dispatch. - **Amended by CR-004:** Validation (contract and deadhead) gains `pilot-resting`, checked before the other pilot checks (Step 10D.3). - **Amended by CR-007:** Validation gains `too-slow`: a Priority contract's trip must fit its delivery window (Step 10G.4). +- **Amended by CR-009:** Validation uses effective stats (capacity, range, Priority window) and gains `ship-in-shop` (Steps 10I.2, 10I.3). ### Step 3.13 — Dispatch record creation - Add a function that turns a validated dispatch into a Dispatch record: id, ship, pilot, contract (or none for reposition), origin, destination, departure real time, arrival real time (computed from travel time and clock conversion), fuel cost, expected payout, seed. @@ -323,6 +327,7 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple - **Test:** Running migrations against the empty test database succeeds; running them a second time is a no-op. - **Amended by CR-002:** `contract_boards` is keyed by player, kind (`location` / `tutorial`), location and period (plus tutorial run); one board per player, location and period (Step 10B.3). - **Amended by CR-004:** The pilots table gains `duty_hours` and `rest_ends_at` (Step 10D.4). +- **Amended by CR-009:** `ship_upgrades` table and, on ships, in-shop-until and the latest shop job (Step 10I.4). ### Step 5.4 — Test database harness - Add a test helper that resets the test database between integration tests and can seed a player in a given state (tutorial, owner with one ship, etc.). @@ -484,11 +489,13 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple - **Test:** Component test: an eligible pair shows correct numbers from the sim; an ineligible pair shows the correct reason; confirming calls dispatch; a server error message is displayed. - **Amended by CR-004:** The dispatch sheet disables resting pilots with a countdown and shows duty after the trip, warning "Will need rest on arrival" (Step 10D.7). - **Amended by CR-007:** For a Priority contract each pair shows its trip against the window; too-slow pairs are disabled with the numbers (Step 10G.9). +- **Amended by CR-009:** The dispatch sheet uses effective stats and lists "In the shop — mm:ss" for ships in the shop (Step 10I.7). ### Step 9.6 — Fleet screen - List all ships: name, model, location or route, assigned pilot, and for in-flight ships a progress bar and countdown. Idle ships at a bay location have a "Reposition" action to another bay location. - **Test:** Component test: an in-flight ship's progress bar matches sim progress for the mocked time. Reposition opens a destination picker listing only bay locations. - **Amended by CR-002:** "Reposition" becomes "Deadhead (fly empty)" for every idle ship, with fuel, time and disabled-with-reason destinations (Step 10B.8). +- **Amended by CR-009:** Fleet cards open the upgrade shop and show "In the shop — mm:ss"; the deadhead picker uses effective stats (Steps 10I.6, 10I.7). ### Step 9.7 — Pilots screen - List pilots: name, level, XP progress to next level, skill levels, available skill points, assignment, status. Actions: hire pilot (shows cost), assign to ship, spend skill point. @@ -499,6 +506,7 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple - List the three ship models with stats (speed, capacity, range, landing class, price). "Buy" is disabled with insufficient credits. - **Test:** Component test: buy is disabled when credits are below price; buying calls the endpoint and the new ship appears in Fleet. - **Amended by CR-002:** Buy opens a "Deliver to which HQ?" bay picker, preselected with one bay (Step 10B.9). +- **Amended by CR-009:** The Market lists the player's upgraded ships of each model with effective stats (Step 10I.7). ### Step 9.9 — Locations screen - List all locations. Discovered ones show type, landing requirement, current distance from Earth, produces/demands, and a "Lease bay" action with price (or "Bay owned"). Undiscovered ones show only the name and "Undiscovered — deliver here to unlock." @@ -609,6 +617,7 @@ Steps 10I.1–10I.9 are specified in `memory-bank/change-requests/CR-009-ship-up - **Amended by CR-002:** The simulated player picks up contracts at whatever location its ships are at, and only deadheads when no eligible contract exists there. Add a check: across the whole run, no ship is ever idle with no eligible contract **and** no reachable deadhead destination. - **Amended by CR-004:** The simulated player follows rest rules: it rests a pilot when no eligible contract exists at its location and deadheading isn't better. Re-check all CR-001 timing targets with rest in place; adjust content values, not thresholds. Add a check that no pilot is ever dispatched while resting. - **Amended by CR-007:** The simulated player considers Priority contracts and skips ones its ships are too slow for. Re-check all timing targets; adjust content values, not thresholds. +- **Amended by CR-009:** The simulated player may buy upgrades: when it can't yet afford its next planned ship, it buys the cheapest available upgrade on its most-used ship, preferring cargo bay and engines. Re-check all timing targets; adjust content values, not thresholds. ### Step 12.2 — Revisit the tutorial economy test - Replace the placeholder average in the Step 2.5 test with the average tutorial payout measured by the balance script. diff --git a/memory-bank/progress.md b/memory-bank/progress.md index bfc210b..dee8ce4 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -234,4 +234,4 @@ Spec: `memory-bank/change-requests/CR-009-ship-upgrades.md` (received as "CR-006 - [x] **Step 10I.6 — Client: upgrade shop.** Every Fleet card has "Upgrades" (with the count installed), opening `ShipUpgrades` (`screens/ShipUpgrades.tsx`): each of the five upgrades with level n/max, the next level as before → after from the sim's `effectiveStats` (e.g. "Speed 2.20M km/h → 2.40M km/h", "Capacity 100 t → 115 t"), cost and shop time; disabled ones show the sim's reason (Not at an HQ, In flight, In the shop, Maxed, Can't afford, Company ship, Finish the company runs first). Upgrading asks for confirmation, then calls `startUpgrade`. Ships in the shop show an "In the shop" pill and "In the shop — mm:ss" instead of their actions. Test: `fleet-upgrades.test.tsx`. - [x] **Step 10I.7 — Client: effective stats everywhere.** `game.ts` `shipStatsOf(ship)` (sim `effectiveStats` from model + upgrades) and `simShip(ship)` (sim `ShipState` with upgrades and in-shop-until). Used by: the board's Too heavy badge (`carryLimit`), Too slow (`tooSlowForAll`), the dispatch sheet (problems, trip time, Priority window, validation; an in-shop ship lists "In the shop — mm:ss" first), and the deadhead picker. The Market lists your upgraded ships of each model with their effective speed, capacity and range; the map's "Reachable with" adds "your [ship] (upgraded)" when only upgrades get it there. Test: `effective-stats-ui.test.tsx` (Cargo Bay 1 clears Too heavy on a 22 t job; Fuel Tanks 3 enables Mars in the deadhead picker near closest approach). - [x] **Step 10I.8 — Client: shop in summaries and on HQ.** The "While you were away" modal also opens for finished, unseen upgrades and lists "[Ship] is out of the shop: Engine Tuning 2"; "Got it" sends their `shipIds` with `acknowledgeSummaries`, and the server (`acknowledgeFinishedUpgrades`) clears only jobs whose shop time has passed. HQ has an "In the shop" card (when any) listing each ship, its upgrade and level, and a countdown, soonest first. Tests: `shop-summary-hq.test.tsx`, and the acknowledge case in `upgrades.test.ts`. -- [ ] Step 10I.9 — Plan amendments and regression +- [x] **Step 10I.9 — Plan amendments and regression.** CR-009 §6 amendments added to plan steps 2.1, 3.5, 3.7, 3.12, 5.3, 9.5, 9.6, 9.8 and 12.1 (§0.5.63–68 were added with the CR). Typecheck, lint, full suite with coverage and the web build are green. **GDD §8 not yet updated:** the CR says the designer updates it; it still describes ship stats with no upgrades, so there is nothing to confirm yet. Scripted manual check against a live server (scratchpad `cr009-smoke.mjs`): after the deal (899 cr), Cargo Bay Expansion 1 on the Courier costs 400 cr, capacity 20 → 23 t, 10 minutes in the shop; dispatch in the shop is refused with `ship-in-shop`; afterwards the Courier takes a 22 t job. **Gameplay note:** shop time (10 min) equals the board period, so a job seen before an upgrade has always expired when the ship comes out. **Phase 10I complete — stopped for review.**