import { content } from "@deadhead/content"; import { describe, expect, it } from "vitest"; import { GameEngine, MemoryBackend, SaveStorage, type RandomSource } from "../src/index"; import { companyName } from "../src/game/names"; import { TEST_NOW } from "./support"; /** Deterministic ids and seeds, so the starting state can be compared exactly. */ function fixedRandom(seed: number): RandomSource { let n = 0; return { id: () => `id-${++n}`, seed: () => seed }; } function engineOn(backend: MemoryBackend, seed = 1234) { return new GameEngine({ storage: new SaveStorage(backend), clock: { now: () => TEST_NOW }, random: fixedRandom(seed), }); } describe("company creation on the device (Step 14.8)", () => { it("starts from empty storage with exactly CR-001's starting state", async () => { const backend = new MemoryBackend(); const engine = engineOn(backend); await expect(engine.call("getPlayerState", {})).rejects.toMatchObject({ code: "unauthorized" }); const { state } = await engine.call("createGuest", {}); expect(state).toEqual({ playerId: "id-1", company: { id: "id-2", name: companyName(1234), credits: content.config.startingCredits, loanBalance: 0, }, ships: [], pilots: [ { id: "id-3", name: "Captain", isAvatar: true, isVeteran: false, xp: 0, level: 0, skills: {}, skillPointsAvailable: 0, assignedShipId: null, status: "idle", locationId: "earth", dutyHours: 0, dutyLimit: content.config.dutyLimitGameHours, resting: false, restEndsAt: null, mode: "manual", orders: { destinationIds: null, cargoClassIds: content.cargoTypes.map((c) => c.id), takePriority: true, minProfit: 0, homeLocationId: "earth", }, }, ], bays: [], locations: content.locations.map((l) => ({ id: l.id, discovered: l.startsDiscovered })), tutorial: { loanerLocationId: "earth", runInFlight: false, runsCompleted: 0, dealAvailable: false, }, activeDispatches: [], summaries: [], goals: [], dispatchOffice: { owned: false, spendingFloor: content.config.independentPilots.defaultSpendingFloor, }, }); }); it("opens the same company after a reload", async () => { const backend = new MemoryBackend(); const created = await engineOn(backend).call("createGuest", {}); // A new engine on the same storage: the app reloaded. const reopened = engineOn(backend, 9999); expect(await reopened.call("getPlayerState", {})).toEqual(created.state); expect(await reopened.call("createGuest", {})).toEqual(created); }); it("gives each new company its own world seed", async () => { const a = await engineOn(new MemoryBackend(), 1).call("createGuest", {}); const b = await engineOn(new MemoryBackend(), 2).call("createGuest", {}); expect(a.state.company.name).toBe(companyName(1)); expect(b.state.company.name).toBe(companyName(2)); }); }); describe("welcome cards in the save (Step 22.1, decision 0.5.131)", () => { it("starts a new company with its welcome not yet seen", async () => { const backend = new MemoryBackend(); const engine = engineOn(backend); await engine.call("createGuest", {}); const save = await new SaveStorage(backend).load(); if (save.status !== "loaded") throw new Error(save.status); expect(save.save.player.welcomeSeen).toBe(false); }); });