CR-007: cargo goods, Priority and shippers (Phase 10G) plan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
540690590c
commit
bdd5fd8509
|
|
@ -894,3 +894,10 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md`
|
||||||
|
|
||||||
- **Found while checking deadhead end to end** (user request): a deadhead's "While you were away" entry read "+0 cr +0 XP" in success green. `ResolutionSummary` gains `deadhead` (the dispatch had no contract) and `fuelCost` (paid at departure); the entry now reads "Deadhead · 230 cr fuel" with a flight icon. Tests: `away-summary.test.tsx`, `reposition.test.ts`, `loan.test.ts`.
|
- **Found while checking deadhead end to end** (user request): a deadhead's "While you were away" entry read "+0 cr +0 XP" in success green. `ResolutionSummary` gains `deadhead` (the dispatch had no contract) and `fuelCost` (paid at departure); the entry now reads "Deadhead · 230 cr fuel" with a flight icon. Tests: `away-summary.test.tsx`, `reposition.test.ts`, `loan.test.ts`.
|
||||||
- **The missing favicon (a harmless 404) is left for later**, by the user's choice; Phase 11's PWA icons are the natural place.
|
- **The missing favicon (a harmless 404) is left for later**, by the user's choice; Phase 11's PWA icons are the natural place.
|
||||||
|
|
||||||
|
## CR-007 — Cargo Goods, Priority Contracts and Shippers (Phase 10G)
|
||||||
|
|
||||||
|
- **Supplied by the user as "CR-005 / Phase 10E" with decisions 0.5.39–0.5.44**, all of which were already taken. Recorded as CR-007, Phase 10G (steps 10G.1–10G.11), decisions 0.5.54–0.5.59; `too_slow` is `too-slow`.
|
||||||
|
- **Mass: the band wins** (asked; the user chose it). The CR draws mass from each good's range, but boards draw it from ship-size bands, and no Standard good weighs over 60 t, so a Bulk Hauler would lose its unskilled job and CR-006's fit guarantees would break. A contract now picks a good of its class overlapping its band and draws inside both; with no overlap it uses the class's largest-range good and the band's range (a bulk lot). The lightest band has no floor for goods, so sub-5 t goods can appear.
|
||||||
|
- **Class mix kept by keeping the class-level lists** (not asked: the CR requires it twice and tests it). Switching `produces`/`demands` to goods and deriving classes from them would make Earth produce all four classes and move its mix far beyond ±3 points. Locations keep the old lists as `cargoClassMix` for class selection only.
|
||||||
|
- **Tutorial contracts are never Priority**: the CR doesn't say, and the tutorial is about learning the loop, not deadlines.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
# Change Request CR-007 — Cargo Goods, Priority Contracts, and Shippers
|
||||||
|
|
||||||
|
> **Implementation notes (added when implemented).** The user supplied this CR as "CR-005, Phase 10E", written before the UI overhaul (CR-005) and fleet-fitted boards (CR-006) existed. It is recorded and built as **CR-007, Phase 10G**, after Phase 10F.
|
||||||
|
>
|
||||||
|
> - **Numbering:** decisions 0.5.39–0.5.44 below are recorded as **0.5.54 Goods, 0.5.55 Tier from goods, 0.5.56 Priority, 0.5.57 Board mix unchanged, 0.5.58 Shippers, 0.5.59 Tutorial goods**. Steps 10E.1–10E.11 are **10G.1–10G.11**. The error code `too_slow` is `too-slow` (the API's kebab-case convention).
|
||||||
|
> - **Mass: the band wins** (user decision). Boards draw mass from per-ship-size bands (`contractMassBands`, playtest fix and CR-006). A contract picks a good of its class whose mass range overlaps its slot's band and draws mass inside both; if no good of that class overlaps, it uses the class's good with the largest maximum and draws from the band (e.g. a 300 t bulk lot of Packaged Food). The lightest band has no floor for goods, so light goods (Research Samples, Antimatter Traps) still appear. Masses under 10 t are drawn to 0.1 t, heavier ones to whole tonnes.
|
||||||
|
> - **Class mix:** to keep decision 0.5.57 (and the ±3-point test), class selection still uses the class-level lists. They are kept on each location as `cargoClassMix` (`produces`/`demands` of class ids, unchanged values), while `produces`/`demands` now list goods, derived from the catalog. Baseline before the change (1,000 Earth boards, all discovered, seed 12345, no fleet): **Standard 76.79 %, High-Value 23.21 %, Heavy 0 %, Dangerous 0 %**.
|
||||||
|
> - **Fleet-fitted boards (CR-006):** fit jobs pick goods too: High-Value and Dangerous goods only up to the pilot's skill, mass within the ship's capacity, and Priority only when the ship meets the window.
|
||||||
|
> - **Tutorial contracts are never Priority.**
|
||||||
|
> - **Database:** contracts live in JSONB (stored boards and dispatch records), so no column changes; migration `0005` backfills existing rows with a default good, shipper and no Priority so saves survive.
|
||||||
|
|
||||||
|
**Project:** Deadhead: Space Freight Tycoon
|
||||||
|
**Applies to:** a build with Phases 1–10 and CR-001 through CR-004 complete
|
||||||
|
**Do this:** as **Phase 10E**, after Phase 10D and before Phase 11 *(built as Phase 10G, see notes)*
|
||||||
|
**Related docs:** `implementation-plan.md`, the earlier change requests, `game-design-document.md`, `DECISIONS.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Why
|
||||||
|
|
||||||
|
Contract cards currently say only "Standard · 14 t". The board already mixes cargo classes well, but nothing says what is being shipped, who is shipping it, or why.
|
||||||
|
|
||||||
|
This change:
|
||||||
|
|
||||||
|
- Adds a **catalog of named goods** (Medical Supplies, Lunar Titanium, Helium-3 Canisters…). Each good belongs to a cargo class, has its own mass range and pay, and is produced and demanded at specific locations. Contracts carry a good, which is pillar 3 of the GDD: every load goes somewhere for a reason.
|
||||||
|
- Adds **Priority** contracts: a time-sensitive good that must arrive within a delivery window, paying a bonus. It needs no skill, only a fast enough ship, which gives the Courier a real role.
|
||||||
|
- Adds **shipper names** as flavor (no mechanics yet; reputation later can use them).
|
||||||
|
|
||||||
|
**The existing board mix stays as it is.** The generator keeps choosing cargo classes the way it does now; this change only picks a named good within the chosen class and may mark it Priority.
|
||||||
|
|
||||||
|
## 2. Concepts
|
||||||
|
|
||||||
|
| Term | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| Cargo class | The existing four: Standard, Heavy, High-Value, Dangerous. Classes keep their skill requirements. |
|
||||||
|
| Good | A named item in the catalog. Has a class, mass range, pay multiplier, origins, destinations, and optional Priority eligibility. |
|
||||||
|
| Tier | 1–5 for non-Standard classes, the required skill level. High-Value and Dangerous now take their tier from the good; Heavy keeps its current tier rule (see §4). |
|
||||||
|
| Priority | A modifier on a Priority-eligible good. The contract has a delivery window; the ship's trip time must fit inside it. Pays a bonus. |
|
||||||
|
| Shipper | A flavor company name per location shown on the card. |
|
||||||
|
|
||||||
|
## 3. Goods catalog
|
||||||
|
|
||||||
|
Numbers are starting values for balance. All of them live in `packages/content`. Pay × multiplies the class's base pay per tonne per million km.
|
||||||
|
|
||||||
|
### Standard (no skill)
|
||||||
|
|
||||||
|
| Id | Name | Mass (t) | Pay × | Priority | Produced at | Demanded at |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| `mail` | Mail & Parcels | 1–8 | 1.2 | Yes | Earth, Mars | Moon, Mars, Ceres, Jupiter, Earth |
|
||||||
|
| `packaged-food` | Packaged Food | 10–60 | 1.0 | No | Earth | Moon, Mars, Ceres, Jupiter |
|
||||||
|
| `consumer-goods` | Consumer Goods | 5–40 | 1.0 | No | Earth | Moon, Mars, Ceres, Jupiter |
|
||||||
|
| `optical-glass` | Lunar Optical Glass | 4–25 | 1.1 | No | Moon | Earth, Mars |
|
||||||
|
| `moon-souvenirs` | Moon Dust Souvenirs | 1–6 | 0.9 | No | Moon | Earth |
|
||||||
|
| `hydroponic-produce` | Hydroponic Produce | 5–30 | 1.1 | Yes | Mars | Moon, Ceres, Jupiter |
|
||||||
|
| `salvaged-components` | Salvaged Components | 5–30 | 0.9 | No | Ceres | Moon, Mars |
|
||||||
|
| `bioplastics` | Atmospheric Bioplastics | 5–40 | 1.0 | No | Jupiter | Earth, Mars, Ceres |
|
||||||
|
|
||||||
|
### High-Value (Expensive Cargo skill)
|
||||||
|
|
||||||
|
| Id | Name | Mass (t) | Pay × | Tier | Priority | Produced at | Demanded at |
|
||||||
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| `medical-supplies` | Medical Supplies | 1–10 | 1.0 | 1 | Yes | Earth | Moon, Mars, Ceres, Jupiter |
|
||||||
|
| `electronics` | Electronics | 2–15 | 1.0 | 1 | No | Earth | Moon, Mars, Ceres, Jupiter |
|
||||||
|
| `seed-stock` | Seed Stock & Embryos | 0.5–4 | 1.3 | 2 | Yes | Earth | Moon, Mars, Ceres |
|
||||||
|
| `low-g-pharma` | Low-G Pharmaceuticals | 0.5–5 | 1.4 | 2 | Yes | Moon | Earth, Mars |
|
||||||
|
| `research-samples` | Research Samples | 0.2–3 | 1.5 | 2 | Yes | Moon, Mars, Ceres | Earth |
|
||||||
|
| `rare-earths` | Martian Rare Earths | 5–30 | 1.4 | 3 | No | Mars | Earth |
|
||||||
|
| `platinum` | Platinum Ingots | 2–20 | 1.8 | 4 | No | Ceres | Earth |
|
||||||
|
|
||||||
|
### Heavy (Heavy Cargo skill)
|
||||||
|
|
||||||
|
Tier follows the generator's existing Heavy tier rule.
|
||||||
|
|
||||||
|
| Id | Name | Mass (t) | Pay × | Priority | Produced at | Demanded at |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| `machine-parts` | Machine Parts | 20–90 | 1.0 | Yes ("Emergency Parts") | Earth, Mars | Moon, Mars, Ceres, Jupiter |
|
||||||
|
| `habitat-prefabs` | Habitat Prefabs | 40–180 | 1.0 | No | Earth | Moon, Mars, Ceres |
|
||||||
|
| `lunar-titanium` | Lunar Titanium | 30–120 | 1.1 | No | Moon | Earth, Mars |
|
||||||
|
| `iron-ingots` | Iron Ingots | 50–200 | 0.9 | No | Mars | Moon, Ceres |
|
||||||
|
| `nickel-iron-ore` | Nickel-Iron Ore | 80–300 | 0.8 | No | Ceres | Earth, Mars, Moon |
|
||||||
|
| `water-ice` | Water Ice | 60–250 | 0.8 | No | Ceres | Mars, Moon, Jupiter |
|
||||||
|
|
||||||
|
### Dangerous (Dangerous Cargo skill)
|
||||||
|
|
||||||
|
Tier is the good's hazard class.
|
||||||
|
|
||||||
|
| Id | Name | Mass (t) | Pay × | Tier | Priority | Produced at | Demanded at |
|
||||||
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| `industrial-chemicals` | Industrial Chemicals | 5–40 | 1.0 | 1 | No | Earth | Moon, Mars, Ceres, Jupiter |
|
||||||
|
| `liquid-oxygen` | Liquid Oxygen | 20–100 | 1.0 | 1 | No | Moon | Mars, Ceres, Jupiter |
|
||||||
|
| `mining-charges` | Mining Charges | 2–20 | 1.3 | 2 | No | Earth, Mars | Moon, Ceres |
|
||||||
|
| `methane-fuel` | Methane Fuel | 20–80 | 1.1 | 2 | No | Mars | Moon, Ceres |
|
||||||
|
| `liquid-hydrogen` | Liquid Hydrogen | 30–150 | 1.1 | 2 | No | Jupiter | Mars, Ceres, Earth |
|
||||||
|
| `helium-3` | Helium-3 Canisters | 1–10 | 2.0 | 3 | Yes | Jupiter | Earth, Moon |
|
||||||
|
| `reactor-cores` | Fusion Reactor Cores | 10–40 | 1.8 | 4 | No | Earth | Ceres, Jupiter |
|
||||||
|
| `antimatter-traps` | Antimatter Containment Traps | 0.1–1 | 4.0 | 5 | No | Jupiter | Earth |
|
||||||
|
|
||||||
|
### Shippers (flavor only)
|
||||||
|
|
||||||
|
| Location | Shippers |
|
||||||
|
|---|---|
|
||||||
|
| Earth | Pacific Orbital Logistics, Meridian Health, Atlas Heavy Industries, Hollis & Crane Consumer |
|
||||||
|
| Moon | Shackleton Mining Co., Tranquility Labs, Copernicus Glassworks |
|
||||||
|
| Mars | Jezero Agricultural Co-op, Red Line Metals, Tharsis Chemical |
|
||||||
|
| Ceres | Belt Ore Consolidated, Piazzi Station Authority |
|
||||||
|
| Jupiter Cloud Platform | Galilean Fuel Combine, Zephyr Gas Works |
|
||||||
|
|
||||||
|
All names are invented for this game.
|
||||||
|
|
||||||
|
## 4. Decisions
|
||||||
|
|
||||||
|
Record these in `DECISIONS.md` and `implementation-plan.md` §0.5. *(Recorded as 0.5.54–0.5.59.)*
|
||||||
|
|
||||||
|
- **0.5.39 Goods.** Contracts carry a good from the catalog. A location's produces and demands lists now name goods, not cargo classes. After the generator picks a contract's cargo class (unchanged logic), it picks a good of that class produced at the origin and demanded at the destination, and draws the mass from that good's range. If no good of that class fits the route, fall back to a Standard good that does; if none does (for example a first-contact destination), use any Standard good produced at the origin. *(Mass: see the implementation notes, the band wins.)*
|
||||||
|
- **0.5.40 Tier from goods.** For High-Value and Dangerous contracts, the tier is the good's tier, replacing the random tier. Standard stays tier 0. Heavy keeps its current tier rule.
|
||||||
|
- **0.5.41 Priority.** A Priority-eligible good becomes a Priority contract with the configured chance. Its delivery window is the trip time of the configured reference ship model (default: Freighter) carrying this cargo on this route at offer time, times the window factor (default 1.0). At dispatch, the chosen ship's trip time must be no longer than the window, or validation fails with `too_slow`. Priority pays the configured bonus (default ×1.5). No skill is required.
|
||||||
|
- **0.5.42 Board mix unchanged.** Class selection, board size, and first-contact chance keep their current logic and config.
|
||||||
|
- **0.5.43 Shippers.** Each contract gets a shipper name drawn from its origin's list. No mechanics.
|
||||||
|
- **0.5.44 Tutorial goods.** The tutorial board uses Standard goods produced at the loaner's location and demanded at the other end (Earth→Moon: mail, packaged food, consumer goods; Moon→Earth: optical glass, souvenirs). The scripted "Unmarked crates" contract is unchanged.
|
||||||
|
|
||||||
|
## 5. Rules for this change
|
||||||
|
|
||||||
|
- All rules in `implementation-plan.md` §0.1 apply: steps in order, one commit per step, each step's test must pass, `packages/sim` stays pure, all numbers live in `packages/content`.
|
||||||
|
- Resetting the dev and test databases is fine (stored boards and contract snapshots change shape). Schema migrations are still required.
|
||||||
|
- Update existing tests whose expectations change. Update `architecture.md` for schema or API changes and `progress.md` after every step.
|
||||||
|
- Stop for the user's review at the end of Phase 10E.
|
||||||
|
|
||||||
|
## 6. Steps — Phase 10E *(built as 10G)*
|
||||||
|
|
||||||
|
### Step 10E.1 — Content: goods catalog
|
||||||
|
- Add a Good schema: id, name, class, mass min and max, pay multiplier, tier (High-Value and Dangerous only), Priority eligible (with optional Priority display name), produced at, demanded at.
|
||||||
|
- Add all goods from §3. Change each location's produces and demands lists to good ids (derived from the catalog's produced-at and demanded-at, or kept in sync by a test).
|
||||||
|
- Add config: Priority chance (default 15% of contracts whose good is Priority-eligible), Priority bonus, Priority reference ship model, Priority window factor. Add the shipper lists.
|
||||||
|
- **Test:** Every good validates and references existing classes and locations. Mass min ≤ max. High-Value and Dangerous goods have a tier from 1 to 5; Standard and Heavy goods don't. Every location produces at least one Standard good. Earth→Moon and Moon→Earth each have at least two Standard goods. Every location has at least one shipper. Location produces/demands match the catalog.
|
||||||
|
|
||||||
|
### Step 10E.2 — Sim: contracts carry goods
|
||||||
|
- Contract shape gains: good id, shipper name, Priority flag, and delivery window (game hours, Priority only).
|
||||||
|
- Tier is derived per decision 0.5.40.
|
||||||
|
- Payout becomes: class base pay × good pay multiplier × tier multiplier × mass × distance × first-contact multiplier (if flagged) × Priority bonus (if flagged).
|
||||||
|
- **Test:** A High-Value or Dangerous contract's tier equals its good's tier. A Heavy contract's tier follows the existing rule. Doubling the good's pay multiplier doubles payout. A Priority contract pays exactly the bonus times an otherwise identical non-Priority contract.
|
||||||
|
|
||||||
|
### Step 10E.3 — Sim: goods, Priority, and shippers in board generation
|
||||||
|
- Keep the existing class selection. After a class is chosen, pick the good, mass, Priority flag and window, and shipper per decisions 0.5.39, 0.5.41, and 0.5.43.
|
||||||
|
- Keep everything deterministic from the existing inputs.
|
||||||
|
- **Test:** Same inputs give identical boards. Every contract's good is produced at the origin and (except first-contact and fallbacks) demanded at the destination, and its mass is within the good's range. Over 1,000 boards from Earth with all locations discovered: the share of each cargo class is within ±3 percentage points of what the pre-change generator produces for the same inputs (record the baseline before changing the generator); Priority appears only on eligible goods and on 10–20% of eligible contracts; every contract has a shipper from its origin's list. First-contact rate is still 5–15%. *(Mass within the good's range except band fallbacks, per the implementation notes.)*
|
||||||
|
|
||||||
|
### Step 10E.4 — Sim: Priority validation
|
||||||
|
- Dispatch validation gains `too_slow`: for a Priority contract, the ship's trip time (with handling time, at departure) must not exceed the delivery window.
|
||||||
|
- **Test:** On a Priority Earth→Moon contract with the default reference (Freighter), a Courier passes and a Bulk Hauler fails with `too_slow`. A non-Priority contract never fails with `too_slow`.
|
||||||
|
|
||||||
|
### Step 10E.5 — Sim: tutorial goods
|
||||||
|
- The tutorial board picks goods per decision 0.5.44. The three mass tiers from CR-001 still apply, clamped to each good's range.
|
||||||
|
- **Test:** With the loaner at Earth, every tutorial good is a Standard good produced at Earth and demanded at the Moon; at the Moon, the reverse. "Unmarked crates" still appears on the scripted run.
|
||||||
|
|
||||||
|
### Step 10E.6 — Schema and database
|
||||||
|
- Stored boards and dispatch contract snapshots include good id, shipper, Priority flag, and window.
|
||||||
|
- Add the `too_slow` error code. API contract shape gains the new fields.
|
||||||
|
- Update `architecture.md`.
|
||||||
|
- **Test:** Migrations run on a fresh database and are a no-op the second time. Changed schemas accept valid examples and reject invalid ones.
|
||||||
|
|
||||||
|
### Step 10E.7 — Server: pass-through and validation
|
||||||
|
- Boards and dispatch use the new sim functions; no new endpoints.
|
||||||
|
- **Test:** A Priority contract dispatched with a too-slow ship returns `too_slow` and changes nothing; with a fast ship it succeeds. A fetched board's contracts all include a good name and shipper.
|
||||||
|
|
||||||
|
### Step 10E.8 — Client: contract card redesign
|
||||||
|
- Card layout, top to bottom:
|
||||||
|
- Route and payout (as now).
|
||||||
|
- **Good name** as the headline, with a class chip showing tier (for example "HIGH-VALUE · T1") and, for Priority, a chip "PRIORITY · within 5h" (game hours, with real minutes on tap or hover).
|
||||||
|
- Shipper · mass · distance.
|
||||||
|
- Requirement ("No skills needed", "Expensive Cargo 1") and expiry.
|
||||||
|
- Status badges as now, plus "TOO SLOW" when no idle ship at the origin can meet the window.
|
||||||
|
- **Test:** Component test: a card shows good name, class and tier chip, shipper, mass, and requirement; a Priority card shows the window chip; a Priority card with only slow idle ships at the origin shows "TOO SLOW".
|
||||||
|
|
||||||
|
### Step 10E.9 — Client: Priority in the dispatch sheet
|
||||||
|
- For a Priority contract, each ship+pilot pair shows its trip time against the window. Pairs that don't fit are disabled with "Too slow — 7h vs 5h window".
|
||||||
|
- **Test:** Component test: a fast enough pair is enabled and shows its margin; a slow pair is disabled with the correct numbers from the sim.
|
||||||
|
|
||||||
|
### Step 10E.10 — Client: goods in summaries
|
||||||
|
- Delivery summaries name the good and shipper, for example "Delivered 6 t Medical Supplies for Meridian Health to the Moon".
|
||||||
|
- **Test:** Component test: a seeded summary shows the good, mass, shipper, and destination.
|
||||||
|
|
||||||
|
### Step 10E.11 — Plan amendments and regression
|
||||||
|
- Apply the amendments in §7 to `implementation-plan.md`.
|
||||||
|
- Run the full suite.
|
||||||
|
- **Test:** CI is green. Manual check: an Earth board after the CR-001 deal shows the same kind of class mix as before, now with named goods and shippers, and at least one Priority contract appears within a few board refreshes.
|
||||||
|
|
||||||
|
## 7. Amendments to `implementation-plan.md`
|
||||||
|
|
||||||
|
| Step | Change |
|
||||||
|
|---|---|
|
||||||
|
| 0.5.6 | Amended by 0.5.40 (High-Value and Dangerous tiers come from goods). |
|
||||||
|
| 0.5.17 | Cargo fallback now uses goods (0.5.39). |
|
||||||
|
| 2.2 | Location produces/demands list good ids (10E.1). |
|
||||||
|
| 2.4 | Cargo types become cargo classes; goods catalog added (10E.1). |
|
||||||
|
| 3.8 | Contract shape and payout include goods and Priority (10E.2). |
|
||||||
|
| 3.9 | Class selection unchanged; goods, Priority, and shippers added (10E.3). |
|
||||||
|
| 3.12 | Validation gains `too_slow` (10E.4). |
|
||||||
|
| CR-001 10A.3 | Tutorial board uses named goods (10E.5). |
|
||||||
|
| 9.4, 9.5 | Card redesign and Priority in dispatch (10E.8, 10E.9). |
|
||||||
|
| 12.1 | 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. |
|
||||||
|
|
||||||
|
## 8. Out of scope
|
||||||
|
|
||||||
|
Changes to how the board mixes cargo classes, board filters, Fragile cargo and the Fragile skill, the Urgent Delivery skill, fixed "deliver by" clock deadlines, late-delivery penalties, cargo damage, supply and demand prices that react to deliveries, and shipper reputation. Anything else in `implementation-plan.md` §0.3.
|
||||||
|
|
@ -109,6 +109,12 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple
|
||||||
51. **Presentation only** (CR-005). The overhaul changes no game rules, API calls, copy or accessible names.
|
51. **Presentation only** (CR-005). The overhaul changes no game rules, API calls, copy or accessible names.
|
||||||
52. **Boards fit the fleet** (CR-006). Location boards are generated with the player's fleet (ship models and pilot skills) as input. Bands the fleet can't carry shrink to a preview; in bands it can, all but a configured number of contracts are ones some ship-and-pilot pair can take.
|
52. **Boards fit the fleet** (CR-006). Location boards are generated with the player's fleet (ship models and pilot skills) as input. Bands the fleet can't carry shrink to a preview; in bands it can, all but a configured number of contracts are ones some ship-and-pilot pair can take.
|
||||||
53. **Weight warning** (CR-006). The board highlights a contract's mass when none of the player's ships at that location (or in the fleet, when none are there) can carry it. Display only.
|
53. **Weight warning** (CR-006). The board highlights a contract's mass when none of the player's ships at that location (or in the fleet, when none are there) can carry it. Display only.
|
||||||
|
54. **Goods** (CR-007). Contracts carry a named good from the catalog; a location's produces and demands lists name goods. After the generator picks a contract's class (unchanged), it picks a good of that class produced at the origin and demanded at the destination, falling back to a Standard good on the route, else any Standard good produced at the origin. Mass comes from the slot's ship-size band, inside the good's range when they overlap.
|
||||||
|
55. **Tier from goods** (CR-007). High-Value and Dangerous contracts take their tier from the good; Standard is tier 0; Heavy keeps the random tier.
|
||||||
|
56. **Priority** (CR-007). A Priority-eligible good becomes Priority with the configured chance. Its delivery window is the reference ship model's trip time for the cargo and route at offer time × the window factor; a ship whose trip time exceeds it fails dispatch with `too-slow`. Priority pays the configured bonus; no skill is required.
|
||||||
|
57. **Board mix unchanged** (CR-007). Class selection (by each location's class-level `cargoClassMix`), board size and first-contact chance keep their logic and config.
|
||||||
|
58. **Shippers** (CR-007). Each contract gets a shipper name from its origin's list. Flavor only.
|
||||||
|
59. **Tutorial goods** (CR-007). Tutorial contracts use Standard goods produced at the loaner's location and demanded at the other end; never Priority. The scripted "Unmarked crates" contract is unchanged.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -543,6 +549,12 @@ Steps 10F.1–10F.5 are specified in `memory-bank/change-requests/CR-006-boards-
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Phase 10G — Cargo Goods, Priority Contracts and Shippers (CR-007)
|
||||||
|
|
||||||
|
Steps 10G.1–10G.11 are specified in `memory-bank/change-requests/CR-007-cargo-goods.md` §6 (written there as 10E.1–10E.11), with its §7 amendments to earlier steps. Done after Phase 10F and before Phase 11; stop for review at the end.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Phase 11 — PWA
|
## Phase 11 — PWA
|
||||||
|
|
||||||
### Step 11.1 — Installable PWA
|
### Step 11.1 — Installable PWA
|
||||||
|
|
|
||||||
|
|
@ -198,3 +198,7 @@ Spec: `memory-bank/change-requests/CR-006-boards-that-fit.md`. New decisions rec
|
||||||
- [x] **Step 10F.3 — Sim: fleet-aware boards.** `BoardInput.fleet?: FleetMember[]` (`{ modelId, skills }`, exported). `planSlots` (board.ts): with no usable fleet, the old plan (each band's count, first slot guaranteed); otherwise bands no ship can carry keep `boardPreviewSlots` (their first is guaranteed), freed slots go to flyable bands largest-first round-robin, and flyable bands are fit slots but for `boardOpenSlotsPerBand` open ones. `fitJob` picks a crew that can carry the band (random start, then the next), a discovered destination it can reach and land at with its Long Haul, cargo the origin produces and the destination demands that the pilot is skilled for (else Standard), tier 1..pilot level, mass up to the ship's capacity; never first contact. A fit slot no crew can fill falls back to a guaranteed slot. No fleet: identical boards and RNG order (existing tests unchanged). Test: `board-fleet.test.ts` (empty fleet = old board; determinism; a lone Courier gets ≥ 5 flyable jobs on every one of 200 boards plus a preview per bigger band; skill cargo never above the pilot's level; a full fleet keeps band counts with fit jobs per band; expiry).
|
- [x] **Step 10F.3 — Sim: fleet-aware boards.** `BoardInput.fleet?: FleetMember[]` (`{ modelId, skills }`, exported). `planSlots` (board.ts): with no usable fleet, the old plan (each band's count, first slot guaranteed); otherwise bands no ship can carry keep `boardPreviewSlots` (their first is guaranteed), freed slots go to flyable bands largest-first round-robin, and flyable bands are fit slots but for `boardOpenSlotsPerBand` open ones. `fitJob` picks a crew that can carry the band (random start, then the next), a discovered destination it can reach and land at with its Long Haul, cargo the origin produces and the destination demands that the pilot is skilled for (else Standard), tier 1..pilot level, mass up to the ship's capacity; never first contact. A fit slot no crew can fill falls back to a guaranteed slot. No fleet: identical boards and RNG order (existing tests unchanged). Test: `board-fleet.test.ts` (empty fleet = old board; determinism; a lone Courier gets ≥ 5 flyable jobs on every one of 200 boards plus a preview per bigger band; skill cargo never above the pilot's level; a full fleet keeps band counts with fit jobs per band; expiry).
|
||||||
- [x] **Step 10F.4 — Server: pass the fleet.** `playerFleet(tx, playerId)` (`game/boards.ts`): the player's ships left-joined to their assigned pilots' skills, ordered by creation then id; `locationBoard` passes it as `fleet` when generating a board. Like discoveries, the fleet is read once per (player, location, period) and the stored board doesn't change afterwards. Test: `location-board.test.ts` — a new owner with one Courier gets ≥ 5 Earth contracts that pass sim `validateDispatch` for that Courier and the avatar.
|
- [x] **Step 10F.4 — Server: pass the fleet.** `playerFleet(tx, playerId)` (`game/boards.ts`): the player's ships left-joined to their assigned pilots' skills, ordered by creation then id; `locationBoard` passes it as `fleet` when generating a board. Like discoveries, the fleet is read once per (player, location, period) and the stored board doesn't change afterwards. Test: `location-board.test.ts` — a new owner with one Courier gets ≥ 5 Earth contracts that pass sim `validateDispatch` for that Courier and the avatar.
|
||||||
- [x] **Step 10F.5 — Regression.** CR-006 §6 amendments added to plan steps 3.9, 6.9 and 9.4. Typecheck, lint, full suite with coverage (102 files, 693 tests; `board.ts` 100 % lines) and the web build are green. **Manual check:** a fresh owner with one Courier at Earth (`docs/screenshots/10f5-lone-courier-earth-board-desktop.png`) sees 5 Standard Earth→Moon jobs of 8–20 t, 1 open High-Value tier 5 job and 2 bigger-ship previews (37 t, 366 t) marked "Too heavy"; before, the same player typically had one job they could fly. **Balance note for Phase 12:** a lone Courier can now chain several Moon runs per 10-minute board, so early income per real hour rises; watch the payout curve and the loan payoff time. **Phase 10F complete — stopped for review.**
|
- [x] **Step 10F.5 — Regression.** CR-006 §6 amendments added to plan steps 3.9, 6.9 and 9.4. Typecheck, lint, full suite with coverage (102 files, 693 tests; `board.ts` 100 % lines) and the web build are green. **Manual check:** a fresh owner with one Courier at Earth (`docs/screenshots/10f5-lone-courier-earth-board-desktop.png`) sees 5 Standard Earth→Moon jobs of 8–20 t, 1 open High-Value tier 5 job and 2 bigger-ship previews (37 t, 366 t) marked "Too heavy"; before, the same player typically had one job they could fly. **Balance note for Phase 12:** a lone Courier can now chain several Moon runs per 10-minute board, so early income per real hour rises; watch the payout curve and the loan payoff time. **Phase 10F complete — stopped for review.**
|
||||||
|
|
||||||
|
## Phase 10G — Cargo Goods, Priority Contracts and Shippers (CR-007)
|
||||||
|
|
||||||
|
Spec: `memory-bank/change-requests/CR-007-cargo-goods.md` (supplied as "CR-005 / Phase 10E"; renumbered, see its implementation notes). New decisions recorded as plan §0.5.54–0.5.59. Baseline class mix before the change (1,000 Earth boards, all discovered): Standard 76.79 %, High-Value 23.21 %.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue