import { describe, it, expect } from 'vitest'; import { createWorld, advance } from '../src/sim/world.js'; describe('world', () => { it('creates a populated world with player at a planet', () => { const w = createWorld('alpha', { systemCount: 12, npcCount: 30 }); expect(w.npcs).toHaveLength(30); expect(w.galaxy.systems).toHaveLength(12); expect(w.player.loc.kind).toBe('docked'); expect(w.player.credits).toBeGreaterThan(0); for (const npc of w.npcs) { expect(npc.alive).toBe(true); expect(w.galaxy.planets[npc.planetId]).toBeTruthy(); } }); it('advance processes events; NPCs actually trade', () => { const w = createWorld('alpha', { systemCount: 12, npcCount: 30 }); advance(w, 40); expect(w.t).toBe(40); expect(w.stats.trades).toBeGreaterThan(30); // every npc averages >1 completed trade }); it('is deterministic end-to-end', () => { const run = () => { const w = createWorld('alpha', { systemCount: 12, npcCount: 30 }); advance(w, 40); return w.npcs.map((n) => [n.credits, n.planetId, n.alive]); }; expect(JSON.stringify(run())).toBe(JSON.stringify(run())); }); it('different seeds diverge', () => { const w1 = createWorld('alpha', { systemCount: 12, npcCount: 30 }); const w2 = createWorld('beta', { systemCount: 12, npcCount: 30 }); advance(w1, 20); advance(w2, 20); expect(JSON.stringify(w1.npcs.map((n) => n.credits))) .not.toBe(JSON.stringify(w2.npcs.map((n) => n.credits))); }); it('advance is incremental: many small steps equal one big step', () => { const a = createWorld('alpha', { systemCount: 12, npcCount: 30 }); const b = createWorld('alpha', { systemCount: 12, npcCount: 30 }); advance(a, 20); for (let t = 0.5; t <= 20.0001; t += 0.5) advance(b, t); expect(JSON.stringify(b.npcs.map((n) => [n.credits, n.planetId]))) .toBe(JSON.stringify(a.npcs.map((n) => [n.credits, n.planetId]))); }); });