From 352ef31625cd991585457635ea21ad4b9cebd9ce Mon Sep 17 00:00:00 2001 From: Kamil Krzywda Date: Sun, 4 Oct 2026 21:20:27 +0000 Subject: [PATCH] test(game): pin RECRUIT_CHANCE_BASE === CREW_CHANCE so the no-trait recruit path can't silently diverge (#43) --- lib/game/save.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/game/save.test.ts b/lib/game/save.test.ts index 8a6941d..b75ed42 100644 --- a/lib/game/save.test.ts +++ b/lib/game/save.test.ts @@ -5,7 +5,7 @@ import { afterAll, describe, expect, it } from 'vitest' import { and, eq } from 'drizzle-orm' import { openGameDb, type GameDb } from '@/lib/db/client' import * as schema from '@/lib/db/schema' -import { ROLES, generateStartingCrew, rollCrewMember, startingCrewRng } from './crew' +import { CREW_CHANCE, ROLES, generateStartingCrew, rollCrewMember, startingCrewRng } from './crew' import { RECRUIT_CHANCE_BASE, RECRUIT_CHANCE_TALKER, STARTING_LEVELS, XP_THRESHOLDS, type SkillName } from './crew-costs' import { MIN_AVAILABLE } from './missions' import { BASE_CAPACITY, BASE_LEVEL, SHIP_TYPES } from './ship-costs' @@ -577,6 +577,10 @@ describe('resolveExploreTask (A/B against explorePlanet)', () => { // 1. Pin the constants. expect(RECRUIT_CHANCE_BASE).toBe(0.18) expect(RECRUIT_CHANCE_TALKER).toBe(0.30) + // Guard the two separately-declared 0.18 constants: the no-trait recruit path passes + // RECRUIT_CHANCE_BASE explicitly while rollCrewMember's default uses CREW_CHANCE — if + // they ever diverge the no-trait outcome would silently drift from its bit-identity pin. + expect(RECRUIT_CHANCE_BASE).toBe(CREW_CHANCE) // 2. Prove the constant is consumed by rollCrewMember: a fixed rng in [0.18, 0.30) // (a member is found iff rng() < chance).