From ace0d8502d88621eb36d4e050a9607bc4e486acb Mon Sep 17 00:00:00 2001 From: fireshaper Date: Fri, 2 Oct 2026 18:42:47 -0400 Subject: [PATCH] Step 3.6: add fuel cost Co-Authored-By: Claude Opus 5.5 --- memory-bank/progress.md | 2 +- packages/sim/src/fuel.ts | 6 ++++++ packages/sim/src/index.ts | 1 + packages/sim/test/fuel.test.ts | 25 +++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 packages/sim/src/fuel.ts create mode 100644 packages/sim/test/fuel.test.ts diff --git a/memory-bank/progress.md b/memory-bank/progress.md index 394f65b..c81f167 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -24,7 +24,7 @@ - [x] **Step 3.3 — Location positions.** `src/positions.ts`: heliocentric ecliptic positions (million km) from `astronomy-engine` for Earth, Mars and Jupiter; Moon = Earth + fixed offset; Ceres on a circular orbit. - [x] **Step 3.4 — Route distance.** `src/distance.ts`: `routeDistance(from, to, gameTime)`, straight-line million km. - [x] **Step 3.5 — Travel time.** `src/travel.ts`: `travelTimeGameHours(ship, distance)` = cruise time + overhead. -- [ ] Step 3.6 — Fuel cost +- [x] **Step 3.6 — Fuel cost.** `src/fuel.ts`: `fuelCost(ship, origin, distance)` = distance × cost per million km × origin launch multiplier. - [ ] Step 3.7 — Range and landing eligibility - [ ] Step 3.8 — Contract model and payout - [ ] Step 3.9 — Contract board generation diff --git a/packages/sim/src/fuel.ts b/packages/sim/src/fuel.ts new file mode 100644 index 0000000..42e71c8 --- /dev/null +++ b/packages/sim/src/fuel.ts @@ -0,0 +1,6 @@ +import type { Location, ShipModel } from "@deadhead/content"; + +/** Fuel cost in credits: distance × the ship's cost per million km × the origin's launch multiplier. */ +export function fuelCost(ship: ShipModel, origin: Location, distanceMillionKm: number): number { + return distanceMillionKm * ship.fuelCostPerMillionKm * origin.launchCostMultiplier; +} diff --git a/packages/sim/src/index.ts b/packages/sim/src/index.ts index 5ddcd31..9c17246 100644 --- a/packages/sim/src/index.ts +++ b/packages/sim/src/index.ts @@ -3,3 +3,4 @@ export * from "./rng"; export * from "./positions"; export * from "./distance"; export * from "./travel"; +export * from "./fuel"; diff --git a/packages/sim/test/fuel.test.ts b/packages/sim/test/fuel.test.ts new file mode 100644 index 0000000..2137e07 --- /dev/null +++ b/packages/sim/test/fuel.test.ts @@ -0,0 +1,25 @@ +import { content } from "@deadhead/content"; +import { describe, expect, it } from "vitest"; +import { fuelCost, routeDistance } from "../src/index"; + +const courier = content.shipModel("courier")!; +const earth = content.location("earth")!; +const moon = content.location("moon")!; + +describe("fuel cost", () => { + it("costs more Earth→Moon than Moon→Earth for the same ship", () => { + const t = Date.parse("2100-01-01T00:00:00Z"); + const distance = routeDistance(earth, moon, t); + expect(fuelCost(courier, earth, distance)).toBeGreaterThan(fuelCost(courier, moon, distance)); + }); + + it("scales linearly with distance", () => { + expect(fuelCost(courier, earth, 2)).toBe(2 * fuelCost(courier, earth, 1)); + expect(fuelCost(courier, earth, 10)).toBe(10 * fuelCost(courier, earth, 1)); + }); + + it("matches a hand calculation", () => { + // 0.5M km × 200 credits/M km × Earth multiplier 3. + expect(fuelCost(courier, earth, 0.5)).toBe(300); + }); +});