Config: 10-minute board period and 10-hour rest
CI / check (push) Successful in 4m25s Details

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
fireshaper 2026-10-04 00:13:49 -04:00
parent f4ddf1dc04
commit 81e71e8436
4 changed files with 16 additions and 7 deletions

View File

@ -868,3 +868,9 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md`
- **Final screenshots are palette-quantized** (sharp `palette: true`, quality 90): 24 shots in 6 MB instead of 18 MB, with no visible banding in the art.
- **The 500 KB chunk warning is accepted for now.** The UI kit and screens added about 27 KB to the main chunk; route-level code splitting (like the map's) can take it back under when the PWA work in Phase 11 looks at load size.
## Config change: shorter board period and rest
- **`contractBoardPeriodRealMinutes` 60 → 10 and `restGameHours` 60 → 10** (user request, after Phase 10D). At 60× compression a rest is now 10 real minutes, exactly one board period, so decision 0.5.46 still holds and its content test (rest in real time ≥ board period) is unchanged and passing.
- **Effects:** boards refresh every 10 real minutes and every contract expires at the end of its period, so offers turn over six times as fast. A rested pilot is back in 10 minutes instead of an hour. This also resolves the earlier note that the CR-004 example expected a short rest.
- **Two tests assumed a 60-minute period** and now derive their timing from config instead: the server's `testContract` helper (expiry = end of the board period) and the board-refresh countdown test. No game code changed.

View File

@ -3,6 +3,7 @@ import { content } from "@deadhead/content";
import { createGuestResponseSchema, playerStateSchema, type PlayerState } from "@deadhead/schema";
import {
boardPeriodIndex,
boardPeriodMs,
createDispatchRecord,
createRepositionRecord,
type Contract,
@ -105,7 +106,8 @@ export function testContract(overrides: Partial<Contract> = {}): Contract {
requiredSkill: null,
requiredLongHaulLevel: 0,
offeredAt: TEST_NOW,
expiresAt: TEST_NOW + 3_600_000,
// Contracts expire at the end of their board period (TEST_NOW is a period start).
expiresAt: TEST_NOW + boardPeriodMs(content.config),
firstContact: false,
...overrides,
};

View File

@ -5,11 +5,12 @@ import { screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { useClock } from "../src/clock/clock";
import { formatClock } from "../src/format";
import { fakeApi, renderApp, samplePlayerState } from "./render";
const period = boardPeriodMs(content.config);
// 17.5 minutes into a board period.
const NOW = Math.ceil(Date.parse("2100-01-01T00:00:00Z") / period) * period + 17.5 * 60_000;
// A quarter of the way into a board period (derived from config, whatever its length).
const NOW = Math.ceil(Date.parse("2100-01-01T00:00:00Z") / period) * period + period / 4;
const periodEndsAt = (boardPeriodIndex(NOW, content.config) + 1) * period;
const courier: Ship = {
@ -79,7 +80,7 @@ describe("board refresh and the nothing-here case (Step 10D.8)", () => {
it("counts down to the next board period", async () => {
renderApp(api([heavyJob]), "/contracts?location=earth");
expect(await screen.findByLabelText("Board refresh")).toHaveTextContent(
"New contracts in 42:30",
`New contracts in ${formatClock(periodEndsAt - NOW)}`,
);
});

View File

@ -23,13 +23,13 @@ export const gameConfig: GameConfig = {
loanRepaymentShare: 0.3,
// Courier price + Earth bay lease.
dealLoanAmount: 5000,
contractBoardPeriodRealMinutes: 60,
contractBoardPeriodRealMinutes: 10,
// Duty and rest (CR-004): about three Moon round trips, then rest.
dutyLimitGameHours: 12,
longHaulDutyBonusGameHours: 2,
// One board period (60 real minutes at 60× compression), so a rested pilot
// One board period (10 real minutes at 60× compression), so a rested pilot
// always wakes to a fresh board (decision 0.5.46).
restGameHours: 60,
restGameHours: 10,
firstContactChance: 0.1,
firstContactPayoutMultiplier: 2,
// One band per ship size, so every board has work for every ship (playtest fix):