Step 3.5: add travel time
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ccd571fdd0
commit
36bdbf3af0
|
|
@ -98,3 +98,7 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md`
|
||||||
## Step 3.4
|
## Step 3.4
|
||||||
|
|
||||||
- **Route distance is the straight line between the two positions at one game time.** Orbital transfer paths are not modelled.
|
- **Route distance is the straight line between the two positions at one game time.** Orbital transfer paths are not modelled.
|
||||||
|
|
||||||
|
## Step 3.5
|
||||||
|
|
||||||
|
- **Travel time takes the distance as a number**, not two locations and a time. The caller measures the distance at departure, so the function cannot accidentally use a mid-flight distance.
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
- [x] **Step 3.2 — Seeded RNG.** `src/rng.ts`: `createRng(seed)` (mulberry32) with `next`, `int`, `pick`; `deriveSeed(parent, label)` for child seeds.
|
- [x] **Step 3.2 — Seeded RNG.** `src/rng.ts`: `createRng(seed)` (mulberry32) with `next`, `int`, `pick`; `deriveSeed(parent, label)` for child seeds.
|
||||||
- [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.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.4 — Route distance.** `src/distance.ts`: `routeDistance(from, to, gameTime)`, straight-line million km.
|
||||||
- [ ] Step 3.5 — Travel time
|
- [x] **Step 3.5 — Travel time.** `src/travel.ts`: `travelTimeGameHours(ship, distance)` = cruise time + overhead.
|
||||||
- [ ] Step 3.6 — Fuel cost
|
- [ ] Step 3.6 — Fuel cost
|
||||||
- [ ] Step 3.7 — Range and landing eligibility
|
- [ ] Step 3.7 — Range and landing eligibility
|
||||||
- [ ] Step 3.8 — Contract model and payout
|
- [ ] Step 3.8 — Contract model and payout
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@ export * from "./clock";
|
||||||
export * from "./rng";
|
export * from "./rng";
|
||||||
export * from "./positions";
|
export * from "./positions";
|
||||||
export * from "./distance";
|
export * from "./distance";
|
||||||
|
export * from "./travel";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
import type { ShipModel } from "@deadhead/content";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trip duration in game hours: cruise time plus the ship's fixed takeoff/landing
|
||||||
|
* overhead. Pass the distance at departure; it is not recalculated mid-flight.
|
||||||
|
*/
|
||||||
|
export function travelTimeGameHours(ship: ShipModel, distanceMillionKm: number): number {
|
||||||
|
const cruiseHours = (distanceMillionKm * 1e6) / ship.cruiseSpeedKmPerGameHour;
|
||||||
|
return cruiseHours + ship.overheadGameHours;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { content } from "@deadhead/content";
|
||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import { routeDistance, travelTimeGameHours } from "../src/index";
|
||||||
|
|
||||||
|
const courier = content.shipModel("courier")!;
|
||||||
|
const freighter = content.shipModel("freighter")!;
|
||||||
|
|
||||||
|
describe("travel time", () => {
|
||||||
|
it("matches a hand calculation", () => {
|
||||||
|
// 150M km at 2M km/h = 75 h cruise, plus 4 h overhead.
|
||||||
|
expect(travelTimeGameHours(freighter, 150)).toBe(79);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("gets a faster ship there sooner on the same route", () => {
|
||||||
|
for (const distance of [0.384, 50, 400]) {
|
||||||
|
expect(travelTimeGameHours(courier, distance)).toBeLessThan(
|
||||||
|
travelTimeGameHours(freighter, distance),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is mostly overhead for a Courier on Earth→Moon", () => {
|
||||||
|
const t = Date.parse("2100-01-01T00:00:00Z");
|
||||||
|
const distance = routeDistance(content.location("earth")!, content.location("moon")!, t);
|
||||||
|
const total = travelTimeGameHours(courier, distance);
|
||||||
|
expect(courier.overheadGameHours).toBeGreaterThan(total / 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue