import { describe, it, expect, vi } from 'vitest' import { getEmbeddedDropTables } from '../src/game/embedded-drop-tables.ts' import { getMonsterTreasureClass, } from '../src/game/monsters.ts' import { executeDropPipeline, loadDropTables, } from '../src/game/drop-pipeline.ts' import * as dropPipeline from '../src/game/drop-pipeline.ts' import * as treasureClass from '../src/game/treasure-class.ts' import { GameEngine } from '../src/game/engine.ts' import { auditDropParity, openDropDataArchives } from '../scripts/pack-canonical-drop-data.ts' import * as fs from 'node:fs' const hasD2 = fs.existsSync('samples/d2/d2data.mpq') describe('Adversarial Reviewer Verification - Drop Parity & SuperUnique Contracts', () => { const dropTables = getEmbeddedDropTables() const dummyTerrain = { widthPx: 1000, heightPx: 1000, overlap: () => 0, } function createTestEngine(difficulty: 'normal' | 'nightmare' | 'hell' = 'normal') { return new GameEngine(dummyTerrain, { spawn: { x: 0, y: 0 }, stats: [], xpTable: [0, 100, 200], dropTables, difficulty, skills: [], npcDefs: [], questDefs: [], combatOptions: {} as any, talkRadius: 50, pickupRadius: 50, inventoryCols: 10, inventoryRows: 4, }) } function lastDropArgs(spy: any) { expect(spy).toHaveBeenCalled() const calls = spy.mock.calls return calls[calls.length - 1][1] } it('Requirement R1: dropTables.monsterKinds has exactly 734 kinds conforming to 1.13c', () => { expect(dropTables.monsterKinds.size).toBe(734) // Key iconic 1.13c entities expect(dropTables.monsterKinds.has('fallen1')).toBe(true) expect(dropTables.monsterKinds.has('andariel')).toBe(true) expect(dropTables.monsterKinds.has('duriel')).toBe(true) expect(dropTables.monsterKinds.has('mephisto')).toBe(true) expect(dropTables.monsterKinds.has('diablo')).toBe(true) expect(dropTables.monsterKinds.has('baalcrab')).toBe(true) expect(dropTables.monsterKinds.has('Expansion')).toBe(true) // Verify all 734 monster kinds define valid TCs that exist in tcTable for (const [id, kind] of dropTables.monsterKinds) { expect(kind.id).toBe(id) for (const diff of ['normal', 'nightmare', 'hell'] as const) { for (const type of [1, 2, 3, 4] as const) { const tc = getMonsterTreasureClass(kind, diff, type) if (tc) { expect( Boolean(dropTables.tcTable.get(tc)), `TC "${tc}" from monster "${id}" (${diff}, type ${type}) must exist in tcTable`, ).toBe(true) } } } } }) it('Requirement R1: MonStats noRatio contract correctly hydrates across summons and suppresses TC upgrade', () => { const noRatioMonsters = [ 'claygolem', 'bloodgolem', 'irongolem', 'firegolem', 'valkyrie', 'necroskeleton', 'necromage', 'wakeofdestruction', ] for (const id of noRatioMonsters) { const kind = dropTables.monsterKinds.get(id) expect(kind, `Monster ${id} should exist`).toBeDefined() expect(kind!.noRatio, `Monster ${id} should have noRatio: true`).toBe(true) } // Standard monsters must NOT have noRatio expect(dropTables.monsterKinds.get('fallen1')!.noRatio).toBeUndefined() expect(dropTables.monsterKinds.get('andariel')!.noRatio).toBeUndefined() // Test that isNoRatio strictly gates TC upgrade in executeDropPipeline const upgradeSpy = vi.spyOn(treasureClass, 'resolveTreasureClassGroup') dropPipeline.executeDropPipeline({ tcName: 'Act 1 H2H A', nLevel: 90, difficulty: 'hell', isNoRatio: true, dropTables, }) expect(upgradeSpy).not.toHaveBeenCalled() upgradeSpy.mockRestore() }) it('Requirement R2: dropTables.superUniques has exactly 66 SuperUniques with authentic 3-difficulty TCs', () => { expect(dropTables.superUniques.size).toBe(66) expect(dropTables.superUniques.has('Expansion')).toBe(false) for (const [id, su] of dropTables.superUniques) { expect(su.id).toBe(id) expect(su.monsterId, `SuperUnique ${id} must specify a monsterId`).toBeTruthy() expect( dropTables.monsterKinds.has(su.monsterId), `SuperUnique ${id} monsterId "${su.monsterId}" must exist in monsterKinds`, ).toBe(true) for (const diff of ['normal', 'nightmare', 'hell'] as const) { const tc = typeof su.getTreasureClass === 'function' ? su.getTreasureClass(diff) : su.treasureClass if (id.startsWith('Ancient Barbarian')) { expect(tc, `Ancient Barbarian ${id} on ${diff} must have empty TC`).toBe('') } else { expect(tc, `SuperUnique ${id} on ${diff} must have non-empty TC`).toBeTruthy() expect( Boolean(dropTables.tcTable.get(tc)), `SuperUnique ${id} TC "${tc}" on ${diff} must exist in tcTable`, ).toBe(true) } } } }) it('Requirement R2: SuperUnique minion inheritance and case-insensitive resolution under extreme inputs', () => { const engine = createTestEngine('hell') const dropSpy = vi.spyOn(dropPipeline, 'executeDropPipeline') // Adversarial whitespace, mixed casing, and minion rank engine.world.pendingKills = [ { kind: 'kill', x: 100, y: 100, subjectId: '', // missing subjectId monsterRank: 'minion', superUniqueId: '\r\n\t BiShIbOsH \t ', monsterLevel: 85, monsterType: 1, // Adversarial: tries to downgrade minion to normal type 1 } as any, ] engine.tick({ movement: { x: 0, y: 0 }, attacking: false, pickingUp: false, talking: false, saving: false, loading: false, digits: [], }) expect(engine.metrics.dropsRolled).toBe(1) const minionArgs = lastDropArgs(dropSpy) // Bishibosh host monster is fallenshaman1. On Hell, fallenshaman1 TreasureClass3 is 'Act 1 (H) Unique A' expect(minionArgs.tcName).toBe('Act 1 (H) Unique A') expect(minionArgs.monsterType).toBe(3) // Minion strictly resolves to 3 expect(minionArgs.isBoss).toBe(false) expect(minionArgs.difficulty).toBe('hell') dropSpy.mockRestore() }) it('Requirement R2: loadDropTables throws explicit Error when SuperUniques.txt fails to load', async () => { if (!hasD2) return const archives = await openDropDataArchives('samples/d2') const realRead = archives.read.bind(archives) archives.read = async (path: string) => { if (path.includes('SuperUniques.txt')) { throw new Error('Simulated I/O disk failure reading SuperUniques.txt') } return realRead(path) } await expect(loadDropTables(archives)).rejects.toThrow( /Failed to load SuperUniques\.txt: Simulated I\/O disk failure/, ) }) it('Requirement R1: pack-canonical-drop-data audit achieves 100% 1.13c parity', async () => { if (!hasD2) return const audit = await auditDropParity() expect(audit.monstatsMatch).toBe(true) expect(audit.superUniquesMatch).toBe(true) expect(audit.monsterKindsCount).toBe(734) expect(audit.superUniquesCount).toBe(66) }) })