Step 10H.1: pay variance setting and five more early goods

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
fireshaper 2026-10-04 17:59:25 -04:00
parent 394fc1b0db
commit 6e427e52f7
6 changed files with 65 additions and 0 deletions

View File

@ -217,3 +217,4 @@ Spec: `memory-bank/change-requests/CR-007-cargo-goods.md` (supplied as "CR-005 /
## Phase 10H — Boards That Feel Fresh (CR-008)
Spec: `memory-bank/change-requests/CR-008-fresh-boards.md`. New decisions recorded as plan §0.5.60–0.5.62.
- [x] **Step 10H.1 — Content: pay variance and new goods.** Config `contractPayVariance` 0.15. Five Standard goods (decision 0.5.61): Water Recyclers, Spare Parts (Priority-eligible) and Lunar Base Supplies Earth → Moon; Crew Personal Effects and Recycled Alloys Moon → Earth (locations' goods lists update from the catalog). Earth → Moon now has 6 Standard goods, Moon → Earth 4. All existing tests still pass (tutorial masses unchanged: goods on both routes still hold 5/12/20 t). Test: `goods.test.ts` (route variety, variance is a fraction).

View File

@ -32,6 +32,8 @@ export const gameConfig: GameConfig = {
restGameHours: 10,
firstContactChance: 0.1,
firstContactPayoutMultiplier: 2,
// Each board contract pays its own market rate, ±15% (CR-008).
contractPayVariance: 0.15,
// Priority contracts (CR-007): 15% of eligible goods, ×1.5 pay, a window as
// long as a Freighter's trip.
priorityChance: 0.15,

View File

@ -94,6 +94,58 @@ export const goods: Good[] = [
demandedAt: [EARTH, MARS, CERES],
},
// More early Standard goods (CR-008, decision 0.5.61).
{
id: "water-recyclers",
name: "Water Recyclers",
cargoClassId: "standard",
massTonnes: { min: 3, max: 18 },
payMultiplier: 1.1,
priorityEligible: false,
producedAt: [EARTH],
demandedAt: [MOON, MARS, CERES],
},
{
id: "spare-parts",
name: "Spare Parts",
cargoClassId: "standard",
massTonnes: { min: 1, max: 12 },
payMultiplier: 1.05,
priorityEligible: true,
producedAt: [EARTH, MARS],
demandedAt: [MOON, CERES, JUPITER],
},
{
id: "lunar-base-supplies",
name: "Lunar Base Supplies",
cargoClassId: "standard",
massTonnes: { min: 2, max: 20 },
payMultiplier: 1,
priorityEligible: false,
producedAt: [EARTH],
demandedAt: [MOON],
},
{
id: "crew-effects",
name: "Crew Personal Effects",
cargoClassId: "standard",
massTonnes: { min: 0.5, max: 5 },
payMultiplier: 1.2,
priorityEligible: false,
producedAt: [MOON, MARS, CERES],
demandedAt: [EARTH],
},
{
id: "recycled-alloys",
name: "Recycled Alloys",
cargoClassId: "standard",
massTonnes: { min: 5, max: 30 },
payMultiplier: 0.95,
priorityEligible: false,
producedAt: [MOON],
demandedAt: [EARTH, MARS],
},
// High-Value: Expensive Cargo skill; tier from the good.
{
id: "medical-supplies",

View File

@ -173,6 +173,8 @@ export const gameConfigSchema = z
restGameHours: z.number().positive(),
firstContactChance: fraction,
firstContactPayoutMultiplier: z.number().positive(),
/** Each board contract's pay rate varies within ± this share of 1 (decision 0.5.60). */
contractPayVariance: fraction,
/** Share of Priority-eligible contracts that become Priority (decision 0.5.56). */
priorityChance: fraction,
/** Payout multiplier for a Priority contract. */

View File

@ -56,6 +56,13 @@ describe("goods catalog (CR-007)", () => {
expect(standardOn("moon", "earth").length).toBeGreaterThanOrEqual(2);
});
it("offers variety on the early route: ≥ 5 Standard goods Earth→Moon, ≥ 4 back (CR-008)", () => {
expect(standardOn("earth", "moon").length).toBeGreaterThanOrEqual(5);
expect(standardOn("moon", "earth").length).toBeGreaterThanOrEqual(4);
expect(gameConfig.contractPayVariance).toBeGreaterThan(0);
expect(gameConfig.contractPayVariance).toBeLessThan(1);
});
it("keeps each location's produces and demands in sync with the catalog", () => {
for (const location of locations) {
expect(location.produces).toEqual(goodsProducedAt(location.id));

View File

@ -83,6 +83,7 @@ const validGameConfig = {
restGameHours: 60,
firstContactChance: 0.1,
firstContactPayoutMultiplier: 2,
contractPayVariance: 0.15,
priorityChance: 0.15,
priorityPayoutMultiplier: 1.5,
priorityReferenceShipModelId: "freighter",