/** * Milestone 3 Challenger Empirical Stress & Parity Verification Suite * * Exhaustive Empirical Verification: * 1. Drop Placement Quadrant Scatter Parity: * - 10,000 multi-item drops using findSafeDropPosition across 4 diverse map collision matrices: * * Narrow Corridors (Tower / Arcane) * * Chaos Sanctuary Star / Cross (lava borders & diagonal halls) * * Catacombs (pillars, rooms, doors) * * Maggot Lair (1-cell winding tunnels & dead ends) * - Invariants: Zero wall penetration (COLLIDE_WALL), zero void penetration (COLLIDE_BLANK, * COLLIDE_MASK_INVALID), valid floor grounding, anti-stacking burst dispersal, and quadrant symmetry. * 2. Gold Pile Monte Carlo Distribution: * - 100,000 gold drops across Normal, Nightmare, Hell difficulties. * - Invariants: 100% conformance to 3-tier graphic cutoffs (flpgld_0: 1-49, flpgld_1: 50-499, * flpgld_2: 500+), zero occurrences of artificial 5,000 clamp, presence of piles > 5,000. * 3. Monster Seed PRNG Determinism with Queued Drops: * - Verification of monster pendingDrop isolation from player movement, skill cast RNG, * and runtime equipment/MF changes. * - Out-of-order death animation completion and lockstep multi-session determinism. * * Usage: npx tsx scripts/verify-challenger-m3-stress.ts */ import { getEmbeddedDropTables } from '../src/game/embedded-drop-tables.ts' import { executeDropPipeline } from '../src/game/drop-pipeline.ts' import { findSafeDropPosition, getIsometricRingCandidates, } from '../src/game/ground-items.ts' import { getGoldFlippyRect, getInventoryGoldLimit, resolveGroundItemSpriteRect, } from '../src/ui/inventory.ts' import { BAKED_UI_MANIFEST } from '../src/ui/baked-ui-meta.ts' import { COLLIDE_NONE, COLLIDE_WALL, COLLIDE_BLANK, COLLIDE_MASK_INVALID, COLLIDE_DOOR, type CollisionGrid, } from '../src/game/d2map.ts' import { D2Rng } from '../src/game/d2-rng.ts' import { Rng } from '../src/game/rng.ts' import { GameEngine, type WorldMapProvider } from '../src/game/engine.ts' import type { Monster } from '../src/game/combat.ts' import { goldItem } from '../src/game/items.ts' const dropTables = getEmbeddedDropTables() const problems: string[] = [] let checks = 0 function assert(condition: boolean, message: string): void { checks += 1 if (!condition) { problems.push(message) console.error(`❌ FAILED: ${message}`) } } console.log('======================================================================') console.log('⚔️ CHALLENGER M3-2: EMPIRICAL STRESS & MONTE CARLO HARNESS') console.log('======================================================================\n') // ============================================================================ // PART 1: DROP PLACEMENT QUADRANT SCATTER PARITY (10,000 MULTI-ITEM DROPS) // ============================================================================ console.log('--- PART 1: QUADRANT SCATTER STRESS (10,000 Multi-Item Drops) ---') // 1.1 Helper to create a CollisionGrid function makeGrid(width: number, height: number, filler: number = COLLIDE_NONE): { cellsX: number cellsY: number gridWidth: number collisionMasks: Uint16Array blocked: Uint8Array } { const subWidth = width * 5 const subHeight = height * 5 const collisionMasks = new Uint16Array(subWidth * subHeight) const blocked = new Uint8Array(subWidth * subHeight) if (filler !== COLLIDE_NONE) { collisionMasks.fill(filler) blocked.fill(1) } return { cellsX: width, cellsY: height, gridWidth: subWidth, collisionMasks, blocked, } } function setCellMask(grid: any, cx: number, cy: number, mask: number): void { if (cx < 0 || cy < 0 || cx >= grid.cellsX || cy >= grid.cellsY) return const startX = cx * 5 const startY = cy * 5 const isBlock = (mask & (COLLIDE_WALL | COLLIDE_BLANK | COLLIDE_MASK_INVALID)) !== 0 for (let dy = 0; dy < 5; dy++) { for (let dx = 0; dx < 5; dx++) { const idx = (startY + dy) * grid.gridWidth + (startX + dx) grid.collisionMasks[idx] = mask grid.blocked[idx] = isBlock ? 1 : 0 } } } function getCellCenterMask(grid: any, cx: number, cy: number): number { if (cx < 0 || cy < 0 || cx >= grid.cellsX || cy >= grid.cellsY) return COLLIDE_MASK_INVALID const subX = cx * 5 + 2 const subY = cy * 5 + 2 const idx = subY * grid.gridWidth + subX return grid.collisionMasks[idx] ?? COLLIDE_NONE } // Map 1: Narrow Corridors (Tower / Arcane) - 50x50 cells const corridorGrid = makeGrid(50, 50, COLLIDE_WALL) // Carve horizontal corridor at y = 10, 20, 30 (width = 2 cells) for (let y of [10, 11, 20, 21, 30, 31]) { for (let x = 5; x < 45; x++) setCellMask(corridorGrid, x, y, COLLIDE_NONE) } // Carve vertical connecting corridors at x = 10, 25, 40 (width = 2 cells) for (let x of [10, 11, 25, 26, 40, 41]) { for (let y = 5; y < 45; y++) setCellMask(corridorGrid, x, y, COLLIDE_NONE) } // Map 2: Chaos Sanctuary Star / Cross - 60x60 cells const sanctuaryGrid = makeGrid(60, 60, COLLIDE_BLANK) // Lava void background // Carve central hub (25..35, 25..35) for (let y = 25; y <= 35; y++) { for (let x = 25; x <= 35; x++) setCellMask(sanctuaryGrid, x, y, COLLIDE_NONE) } // 4 cardinal wings for (let i = 10; i < 25; i++) { for (let w = -2; w <= 2; w++) { setCellMask(sanctuaryGrid, 30 + w, i, COLLIDE_NONE) // North setCellMask(sanctuaryGrid, 30 + w, 60 - i, COLLIDE_NONE) // South setCellMask(sanctuaryGrid, i, 30 + w, COLLIDE_NONE) // West setCellMask(sanctuaryGrid, 60 - i, 30 + w, COLLIDE_NONE) // East } } // Diagonal corridors with wall boundaries for (let d = 5; d < 18; d++) { setCellMask(sanctuaryGrid, 25 - d, 25 - d, COLLIDE_NONE) setCellMask(sanctuaryGrid, 35 + d, 25 - d, COLLIDE_NONE) setCellMask(sanctuaryGrid, 25 - d, 35 + d, COLLIDE_NONE) setCellMask(sanctuaryGrid, 35 + d, 35 + d, COLLIDE_NONE) } // Map 3: Catacombs (Pillar room & doors) - 50x50 cells const catacombsGrid = makeGrid(50, 50, COLLIDE_NONE) // Perimeter wall for (let i = 0; i < 50; i++) { setCellMask(catacombsGrid, i, 0, COLLIDE_WALL) setCellMask(catacombsGrid, i, 49, COLLIDE_WALL) setCellMask(catacombsGrid, 0, i, COLLIDE_WALL) setCellMask(catacombsGrid, 49, i, COLLIDE_WALL) } // Dividing walls with doors for (let i = 1; i < 49; i++) { setCellMask(catacombsGrid, 25, i, i === 15 || i === 35 ? COLLIDE_DOOR : COLLIDE_WALL) } // Dense pillars inside rooms for (let py of [10, 20, 30, 40]) { for (let px of [10, 18, 32, 42]) { setCellMask(catacombsGrid, px, py, COLLIDE_WALL) setCellMask(catacombsGrid, px + 1, py, COLLIDE_WALL) setCellMask(catacombsGrid, px, py + 1, COLLIDE_WALL) setCellMask(catacombsGrid, px + 1, py + 1, COLLIDE_WALL) } } // Map 4: Maggot Lair (Tight winding 1-cell tunnels) - 50x50 cells const maggotGrid = makeGrid(50, 50, COLLIDE_WALL) let curX = 5, curY = 5 setCellMask(maggotGrid, curX, curY, COLLIDE_NONE) const pathRng = new D2Rng(0xCAFEF00D) for (let step = 0; step < 800; step++) { const dir = pathRng.rand(4) if (dir === 0 && curX < 45) curX++ else if (dir === 1 && curX > 5) curX-- else if (dir === 2 && curY < 45) curY++ else if (dir === 3 && curY > 5) curY-- setCellMask(maggotGrid, curX, curY, COLLIDE_NONE) } const testMaps = [ { name: 'Narrow Corridors', grid: corridorGrid }, { name: 'Chaos Sanctuary Star', grid: sanctuaryGrid }, { name: 'Catacombs with Pillars & Doors', grid: catacombsGrid }, { name: 'Maggot Lair 1-Cell Tunnels', grid: maggotGrid }, ] let totalMultiItemDrops = 0 let totalPlacedItems = 0 let wallPenetrations = 0 let voidPenetrations = 0 let outOfBoundsDrops = 0 let unexpectedOverlapCount = 0 // Run 2,500 multi-item drops per map (total 10,000 multi-item drops) for (const map of testMaps) { const grid = map.grid const walkableCells: { x: number; y: number }[] = [] for (let cy = 0; cy < grid.cellsY; cy++) { for (let cx = 0; cx < grid.cellsX; cx++) { const mask = getCellCenterMask(grid, cx, cy) if ((mask & (COLLIDE_WALL | COLLIDE_BLANK | COLLIDE_MASK_INVALID)) === 0) { walkableCells.push({ x: cx, y: cy }) } } } assert(walkableCells.length > 50, `${map.name} must have sufficient walkable cells`) const dropRng = new D2Rng(0x5EED1000 + totalMultiItemDrops) for (let dropIdx = 0; dropIdx < 2500; dropIdx++) { totalMultiItemDrops++ // Pick an origin from walkable cells const origin = walkableCells[dropRng.rand(walkableCells.length)]! const itemCount = 4 + dropRng.rand(5) // 4 to 8 items per burst const occupied: { cellX: number; cellY: number }[] = [] for (let itemIdx = 0; itemIdx < itemCount; itemIdx++) { totalPlacedItems++ const pos = findSafeDropPosition(grid, origin.x, origin.y, 4, occupied) // 1. Out of bounds check if (pos.cellX < 0 || pos.cellY < 0 || pos.cellX >= grid.cellsX || pos.cellY >= grid.cellsY) { outOfBoundsDrops++ } // 2. Wall & Void check const placedMask = getCellCenterMask(grid, pos.cellX, pos.cellY) if ((placedMask & COLLIDE_WALL) !== 0) { wallPenetrations++ } if ((placedMask & (COLLIDE_BLANK | COLLIDE_MASK_INVALID)) !== 0) { voidPenetrations++ } occupied.push(pos) } // Check anti-stacking: if available free cells within maxRadius >= itemCount, // all placed items must be in distinct cells! let freeNeighbors = 0 for (let dy = -4; dy <= 4; dy++) { for (let dx = -4; dx <= 4; dx++) { const cx = origin.x + dx const cy = origin.y + dy if (cx >= 0 && cy >= 0 && cx < grid.cellsX && cy < grid.cellsY) { const m = getCellCenterMask(grid, cx, cy) if ((m & (COLLIDE_WALL | COLLIDE_BLANK | COLLIDE_MASK_INVALID)) === 0) { freeNeighbors++ } } } } const uniqueOccupied = new Set(occupied.map(p => `${p.cellX},${p.cellY}`)) if (freeNeighbors >= itemCount && uniqueOccupied.size !== itemCount) { unexpectedOverlapCount++ } } } console.log(`- Total Multi-Item Drop Events: ${totalMultiItemDrops}`) console.log(`- Total Items Placed: ${totalPlacedItems}`) console.log(`- Wall Penetrations: ${wallPenetrations}`) console.log(`- Void Penetrations: ${voidPenetrations}`) console.log(`- Out of Bounds Drops: ${outOfBoundsDrops}`) console.log(`- Unexpected Overlaps (when free cells available): ${unexpectedOverlapCount}`) assert(wallPenetrations === 0, 'Must have exactly ZERO wall penetrations') assert(voidPenetrations === 0, 'Must have exactly ZERO void penetrations') assert(outOfBoundsDrops === 0, 'Must have exactly ZERO out-of-bounds drops') assert(unexpectedOverlapCount === 0, 'Must have ZERO unexpected overlaps when candidate cells are free') // 1.2 Quadrant Ring Symmetry Invariant Check console.log('\nTesting Concentric Quadrant Ring Symmetry & Ordering Invariant:') for (let r = 1; r <= 5; r++) { const ring = getIsometricRingCandidates(r) const l1Values = ring.map(c => c.l1) // Check that L1 values are monotonically non-decreasing for (let i = 1; i < l1Values.length; i++) { assert(l1Values[i]! >= l1Values[i - 1]!, `Ring ${r} candidates must be sorted by Manhattan distance L1`) } // Check quadrant balance: count of +x, -x, +y, -y const posX = ring.filter(c => c.dx > 0).length const negX = ring.filter(c => c.dx < 0).length const posY = ring.filter(c => c.dy > 0).length const negY = ring.filter(c => c.dy < 0).length assert(posX === negX, `Ring ${r} must have balanced X axis symmetry (+X:${posX}, -X:${negX})`) assert(posY === negY, `Ring ${r} must have balanced Y axis symmetry (+Y:${posY}, -Y:${negY})`) } console.log('✓ Concentric quadrant ring symmetry invariant holds strictly.') // ============================================================================ // PART 2: GOLD PILE MONTE CARLO DISTRIBUTION (100,000 GOLD DROPS) // ============================================================================ console.log('\n--- PART 2: GOLD PILE MONTE CARLO (100,000 Drops Across Difficulties) ---') const flippyRects = BAKED_UI_MANIFEST.flippyRects ?? {} assert(Boolean(flippyRects['flpgld_0']), 'flpgld_0 flippy rect must exist') assert(Boolean(flippyRects['flpgld_1']), 'flpgld_1 flippy rect must exist') assert(Boolean(flippyRects['flpgld_2']), 'flpgld_2 flippy rect must exist') let tier0Count = 0 // 1..49 let tier1Count = 0 // 50..499 let tier2Count = 0 // 500+ let pilesOver5000 = 0 let maxGoldAmount = 0 let minGoldAmount = Infinity let invalidTierResolutions = 0 let clamped5000Count = 0 // Test scenarios: // Normal: Fallen (lvl 1..5), Zombie (lvl 3..8), Blood Raven (lvl 10), Andariel (lvl 12) // Nightmare: Flayer (lvl 50), Council Member (lvl 55), Mephisto (lvl 59) // Hell: Council Member (lvl 85), Chaos Sanctuary (lvl 85), Diablo (lvl 94), Baal (lvl 99) // With GF = 0%, 50%, 150%, 300% const goldScenarios = [ { diff: 'normal', tc: 'Act 1 Junk', lvl: 3, gf: 0, weight: 15 }, { diff: 'normal', tc: 'Act 1 Junk', lvl: 8, gf: 25, weight: 15 }, { diff: 'normal', tc: 'Act 2 Junk', lvl: 16, gf: 50, weight: 10 }, { diff: 'nightmare', tc: 'Act 3 (N) Junk', lvl: 52, gf: 0, weight: 15 }, { diff: 'nightmare', tc: 'Act 3 (N) Junk', lvl: 55, gf: 100, weight: 10 }, { diff: 'nightmare', tc: 'Act 4 (N) Junk', lvl: 60, gf: 150, weight: 10 }, { diff: 'hell', tc: 'Act 3 (H) Junk', lvl: 83, gf: 100, weight: 10 }, { diff: 'hell', tc: 'Act 4 (H) Junk', lvl: 85, gf: 200, weight: 10 }, { diff: 'hell', tc: 'Act 5 (H) Junk', lvl: 88, gf: 350, weight: 5 }, ] const totalTargetGoldDrops = 100000 const goldRng = new D2Rng(0xB16601D) for (let dropIdx = 0; dropIdx < totalTargetGoldDrops; dropIdx++) { // Select scenario const scen = goldScenarios[dropIdx % goldScenarios.length]! const effectiveIlvl = scen.lvl const minGold = effectiveIlvl const maxGoldAdd = 5 * effectiveIlvl const baseGold = Math.max(1, goldRng.rand(maxGoldAdd) + minGold) const multiplier = 1 + goldRng.rand(3) // 1x to 3x multiplier let goldAmount = Math.max(1, baseGold * multiplier) if (scen.gf > 0) { goldAmount = Math.max(1, Math.floor((goldAmount * (100 + scen.gf)) / 100)) } // Create gold item const item = goldItem(goldAmount) const stack = item.stack ?? 0 if (stack < minGoldAmount) minGoldAmount = stack if (stack > maxGoldAmount) maxGoldAmount = stack if (stack > 5000) pilesOver5000++ if (stack === 5000) clamped5000Count++ // Check 3-tier classification const rect = getGoldFlippyRect(stack, flippyRects) const spriteRect = resolveGroundItemSpriteRect( { isGold: true, amount: stack, code: 'gld' }, flippyRects, ) if (stack < 50) { tier0Count++ if (rect !== flippyRects['flpgld_0'] || spriteRect !== flippyRects['flpgld_0']) { invalidTierResolutions++ } } else if (stack < 500) { tier1Count++ if (rect !== flippyRects['flpgld_1'] || spriteRect !== flippyRects['flpgld_1']) { invalidTierResolutions++ } } else { tier2Count++ if (rect !== flippyRects['flpgld_2'] || spriteRect !== flippyRects['flpgld_2']) { invalidTierResolutions++ } } } console.log(`- Total Gold Drops Sampled: ${totalTargetGoldDrops}`) console.log(`- Min Gold Pile Amount: ${minGoldAmount}`) console.log(`- Max Gold Pile Amount: ${maxGoldAmount}`) console.log(`- Piles in Tier 0 (1–49 gold / flpgld_0): ${tier0Count} (${((tier0Count / totalTargetGoldDrops) * 100).toFixed(2)}%)`) console.log(`- Piles in Tier 1 (50–499 gold / flpgld_1): ${tier1Count} (${((tier1Count / totalTargetGoldDrops) * 100).toFixed(2)}%)`) console.log(`- Piles in Tier 2 (500+ gold / flpgld_2): ${tier2Count} (${((tier2Count / totalTargetGoldDrops) * 100).toFixed(2)}%)`) console.log(`- Piles > 5,000 Gold: ${pilesOver5000} (${((pilesOver5000 / totalTargetGoldDrops) * 100).toFixed(2)}%)`) console.log(`- Invalid Tier Resolutions: ${invalidTierResolutions}`) assert(tier0Count > 0, 'Tier 0 (flpgld_0) must be populated') assert(tier1Count > 0, 'Tier 1 (flpgld_1) must be populated') assert(tier2Count > 0, 'Tier 2 (flpgld_2) must be populated') assert(pilesOver5000 > 0, 'Must have gold piles > 5,000 (proving absence of 5,000 clamp)') assert(maxGoldAmount > 5000, `Max gold pile (${maxGoldAmount}) must exceed 5,000`) assert(invalidTierResolutions === 0, 'All 100,000 gold piles must resolve to exact authentic 3-tier flippy rects') // Character inventory gold capacity checks for (let lvl = 1; lvl <= 99; lvl++) { const cap = getInventoryGoldLimit(lvl) assert(cap === lvl * 10000, `Level ${lvl} gold limit must be exactly ${lvl * 10000}`) } console.log('✓ Gold inventory capacity limit strictly conforms to level * 10,000 across all 99 levels.') // ============================================================================ // PART 3: MONSTER SEED PRNG DETERMINISM WITH QUEUED DROPS // ============================================================================ console.log('\n--- PART 3: MONSTER SEED PRNG DETERMINISM (Queued vs Immediate) ---') function createTestEngine(seed = 42, equippedItems: any[] = []): GameEngine { const engine = new GameEngine( { widthPx: 2000, heightPx: 2000, overlap: () => 0 }, { spawn: { x: 500, y: 500 }, stats: [], xpTable: [0, 500, 1500], skills: [ { id: 1, name: 'Fire Bolt', manaCost: 2, cooldownTicks: 5, radius: 20, range: 300, speed: 10, damage: 10, } as any, ], npcDefs: [], questDefs: [], combatOptions: { playerSpeed: 4, playerReach: 50, playerCooldownTicks: 10, playerDamage: 100, playerManaPerAttack: 1, respawnTicks: 100, }, talkRadius: 50, pickupRadius: 30, inventoryCols: 10, inventoryRows: 4, lootSeed: seed, dropTables, equippedItems, }, ) engine.setDropTables(dropTables) return engine } function makeMonster(index: number, id: string, x: number, y: number, lvl = 15): Monster { return { index, stats: { id, name: id, hp: 50, damage: 1, cooldownTicks: 10, reach: 20, aggroRadius: 100, speed: 10, xp: 10, level: lvl, rank: 'normal', }, x, y, hp: 50, cooldown: 0, state: 'idle', facing: 0, hitFlash: 0, corpseTicks: 0, dropRolled: false, } } // Scenario 3.1: Isolated PRNG Stream Invariance // Verify that intermediate gameplay ticks (casting skills, moving, swapping gear) // do NOT alter the pending drop output rolled upon death animation completion. console.log('Testing Scenario 3.1: Immediate Drop vs Delayed Queued Drop Determinism') const TEST_SEEDS = [101, 777, 1337, 0xCAFE, 0x12345678] for (const testSeed of TEST_SEEDS) { // Run 1: Immediate drop (no death gating) const engineImmediate = createTestEngine(testSeed, [ { name: 'MF Ring', stats: [{ text: '30% Better Chance of Getting Magic Items' }] }, ]) const monster1 = makeMonster(0, 'fallen1', 520, 500, 15) engineImmediate.world.monsters.push(monster1) engineImmediate.damageMonster(0, 999) engineImmediate.tick({ movement: { x: 0, y: 0 }, attacking: false, pickingUp: false, talking: false, digits: [], saving: false, loading: false }) const immediateDrops = engineImmediate.groundItems.all.map(g => ({ name: g.name, code: g.item.code, quality: g.quality, amount: g.amount, })) // Run 2: Gated drop (deathGated = true, deathTicks = 20) // During the 20 ticks, the player moves, casts spells (advancing castRng), and unequips MF ring! const engineGated = createTestEngine(testSeed, [ { name: 'MF Ring', stats: [{ text: '30% Better Chance of Getting Magic Items' }] }, ]) const monster2 = makeMonster(0, 'fallen1', 520, 500, 15) monster2.deathGated = true monster2.deathTicks = 20 engineGated.world.monsters.push(monster2) engineGated.damageMonster(0, 999) // Lethal tick: drop is queued into pendingDrop engineGated.tick({ movement: { x: 0, y: 0 }, attacking: false, pickingUp: false, talking: false, digits: [], saving: false, loading: false }) assert(engineGated.groundItems.count === 0, 'No drops should appear while death animation is ticking') // Unequip MF ring during death animation! (Player un-equips gear before monster hits ground) ;(engineGated.opts as any).equippedItems = [] // Simulate 19 ticks with movement and spell casting for (let t = 0; t < 19; t++) { engineGated.tick({ movement: { x: t % 2 === 0 ? 1 : -1, y: 0 }, attacking: t % 4 === 0, // Cast spell, consuming castRng pickingUp: false, talking: false, digits: [1], saving: false, loading: false, }) } // Final tick: death animation completes, drop triggers! engineGated.tick({ movement: { x: 0, y: 0 }, attacking: false, pickingUp: false, talking: false, digits: [], saving: false, loading: false }) assert(monster2.dropRolled === true, 'Drop must be rolled upon death animation completion') const gatedDrops = engineGated.groundItems.all.map(g => ({ name: g.name, code: g.item.code, quality: g.quality, amount: g.amount, })) assert( immediateDrops.length === gatedDrops.length, `Seed ${testSeed}: Item count mismatch (immediate: ${immediateDrops.length}, gated: ${gatedDrops.length})`, ) for (let i = 0; i < immediateDrops.length; i++) { const imm = immediateDrops[i]! const gat = gatedDrops[i]! assert(imm.name === gat.name, `Seed ${testSeed}: Item ${i} name mismatch ("${imm.name}" vs "${gat.name}")`) assert(imm.code === gat.code, `Seed ${testSeed}: Item ${i} code mismatch ("${imm.code}" vs "${gat.code}")`) assert(imm.quality === gat.quality, `Seed ${testSeed}: Item ${i} quality mismatch ("${imm.quality}" vs "${gat.quality}")`) assert(imm.amount === gat.amount, `Seed ${testSeed}: Item ${i} amount mismatch (${imm.amount} vs ${gat.amount})`) } } console.log('✓ Queued drop determinism strictly matches immediate drop bit-for-bit, immune to mid-animation input/casting/swaps.') // Scenario 3.2: Multi-Monster Lockstep Queue Integrity console.log('\nTesting Scenario 3.2: Multi-Monster Parallel Death Queue Race Conditions') const engineA = createTestEngine(0x998877) const engineB = createTestEngine(0x998877) // 3 monsters with different death durations dying in staggered ticks for (let i = 0; i < 3; i++) { const mA = makeMonster(i, i === 0 ? 'zombie1' : i === 1 ? 'skeleton1' : 'fallen1', 520 + i * 20, 500, 10 + i * 5) const mB = makeMonster(i, i === 0 ? 'zombie1' : i === 1 ? 'skeleton1' : 'fallen1', 520 + i * 20, 500, 10 + i * 5) mA.deathGated = true mB.deathGated = true mA.deathTicks = (3 - i) * 5 // Monster 0: 15 ticks, Monster 1: 10 ticks, Monster 2: 5 ticks (finishes first!) mB.deathTicks = (3 - i) * 5 engineA.world.monsters.push(mA) engineB.world.monsters.push(mB) } // Kill all 3 on tick 0 engineA.damageMonster(0, 999) engineA.damageMonster(1, 999) engineA.damageMonster(2, 999) engineB.damageMonster(0, 999) engineB.damageMonster(1, 999) engineB.damageMonster(2, 999) // Tick both engines for 25 frames for (let t = 0; t < 25; t++) { engineA.tick({ movement: { x: 0, y: 0 }, attacking: false, pickingUp: false, talking: false, digits: [], saving: false, loading: false }) engineB.tick({ movement: { x: 0, y: 0 }, attacking: false, pickingUp: false, talking: false, digits: [], saving: false, loading: false }) } const dropsA = engineA.groundItems.all.map(g => `${g.name}:${g.quality}:${g.cellX},${g.cellY}`) const dropsB = engineB.groundItems.all.map(g => `${g.name}:${g.quality}:${g.cellX},${g.cellY}`) assert(dropsA.length > 0, 'Drops must have spawned in Engine A') assert(dropsA.length === dropsB.length, 'Engine A and B must have identical drop counts') assert(JSON.stringify(dropsA) === JSON.stringify(dropsB), 'Engine A and B must maintain 100% lockstep parity in queued drops') console.log('✓ Multi-monster staggered death queues maintain 100% lockstep parity across independent engines.') console.log('\n======================================================================') console.log(`TOTAL CHECKS EXECUTED: ${checks}`) console.log(`PROBLEMS ENCOUNTERED: ${problems.length}`) if (problems.length > 0) { console.log('FAILED CONDITIONS:') for (const p of problems) console.log(` - ${p}`) process.exit(1) } else { console.log('🎉 ALL EMPIRICAL CHALLENGER STRESS TESTS PASSED WITH 0 PROBLEMS!') console.log('======================================================================') }