/** * Comprehensive Empirical Stress-Testing Harness for Milestone 1 * Ghost Interaction Decoupling & Combat Safety (Requirement R1) * * Playbook: solution_stress_testing (SKILL.md) * Archetype: EMPIRICAL CHALLENGER */ import { KeyboardInput } from '../src/sim/input.ts' import { HudManager } from '../src/ui/hud-manager.ts' import { GameEngine, type GameEngineOptions, type WorldMapProvider } from '../src/game/engine.ts' // Mock DOM Environment for Node class MockWindow extends EventTarget { innerWidth = 1920 innerHeight = 1080 devicePixelRatio = 1 } class MockCanvas extends EventTarget { clientWidth = 1920 clientHeight = 1080 width = 1920 height = 1080 style = { pointerEvents: 'none' } getBoundingClientRect() { return { left: 0, top: 0, width: 1920, height: 1080 } } getContext() { return null } } class SyntheticKeyboardEvent extends Event { readonly code: string readonly key: string constructor(type: string, init: { code: string; key: string }) { super(type, { cancelable: true }) this.code = init.code this.key = init.key } } // Global DOM shims for HudManager const mockWin = new MockWindow() // @ts-ignore globalThis.window = mockWin // @ts-ignore globalThis.HTMLInputElement = class HTMLInputElement {} // @ts-ignore globalThis.HTMLSelectElement = class HTMLSelectElement {} let totalAssertions = 0 let passedAssertions = 0 let failedAssertions = 0 function assert(condition: boolean, message: string): void { totalAssertions++ if (condition) { passedAssertions++ } else { failedAssertions++ console.error(`❌ ASSERTION FAILED: ${message}`) throw new Error(`Assertion failed: ${message}`) } } async function runTestSuite(): Promise { console.log('=================================================================') console.log('🚀 RUNNING EMPIRICAL CHALLENGER STRESS-TEST HARNESS (M1 / R1)') console.log('=================================================================') // ----------------------------------------------------------------------------- // SUITE 1: Ghost Interaction Decoupling: KeyT & KeyB // ----------------------------------------------------------------------------- console.log('\n--- [Suite 1] Ghost Interaction Decoupling: KeyT & KeyB ---') { const win = new MockWindow() const input = new KeyboardInput(win as unknown as Window) input.attach() // 1.1 Initial state assert(input.talking === false, 'Initial input.talking must be false') assert(input.takeWaypoint() === false, 'Initial input.takeWaypoint() must be false') // 1.2 KeyT dispatch (single, held, repeated) win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'KeyT', key: 't' })) assert(input.talking === false, 'KeyT down must NOT set input.talking to true') for (let tick = 0; tick < 100; tick++) { assert(input.talking === false, `input.talking must remain false across 100 ticks of KeyT held (tick ${tick})`) } win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'KeyT', key: 't' })) // repeat assert(input.talking === false, 'Repeated KeyT keydown must NOT set input.talking') win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'KeyT', key: 't' })) assert(input.talking === false, 'KeyT keyup must leave input.talking false') // 1.3 KeyB dispatch (single, held, repeated) win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'KeyB', key: 'b' })) assert(input.takeWaypoint() === false, 'KeyB down must NOT trigger input.takeWaypoint()') for (let tick = 0; tick < 100; tick++) { assert(input.takeWaypoint() === false, `input.takeWaypoint() must remain false across 100 ticks of KeyB held (tick ${tick})`) } win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'KeyB', key: 'b' })) assert(input.takeWaypoint() === false, 'Repeated KeyB keydown must NOT trigger input.takeWaypoint()') win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'KeyB', key: 'b' })) assert(input.takeWaypoint() === false, 'KeyB keyup must leave input.takeWaypoint() false') // 1.4 Test every printable key on the keyboard to ensure TALK_KEYS and WAYPOINT_KEYS are 100% empty const testCodes = [ 'KeyA', 'KeyB', 'KeyC', 'KeyD', 'KeyE', 'KeyF', 'KeyG', 'KeyH', 'KeyI', 'KeyJ', 'KeyK', 'KeyL', 'KeyM', 'KeyN', 'KeyO', 'KeyP', 'KeyQ', 'KeyR', 'KeyS', 'KeyT', 'KeyU', 'KeyV', 'KeyW', 'KeyX', 'KeyY', 'KeyZ', 'Digit1', 'Digit2', 'Digit3', 'Digit4', 'Space', 'Enter', 'Tab', 'Escape', 'Backspace' ] for (const code of testCodes) { win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code, key: code.toLowerCase() })) assert(input.talking === false, `Key ${code} must NOT set input.talking to true`) assert(input.takeWaypoint() === false, `Key ${code} must NOT trigger input.takeWaypoint()`) win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code, key: code.toLowerCase() })) } } // ----------------------------------------------------------------------------- // SUITE 2: Combat Safety: Space vs Combat Swings & Panel Dismissal // ----------------------------------------------------------------------------- console.log('\n--- [Suite 2] Combat Safety: Space Removal from ATTACK_KEYS & Panel Dismissal ---') { const win = new MockWindow() const input = new KeyboardInput(win as unknown as Window) input.attach() // 2.1 Space does not set input.attacking win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Space', key: ' ' })) assert(input.attacking === false, 'Space down must NOT set input.attacking to true') for (let tick = 0; tick < 100; tick++) { assert(input.attacking === false, `Space held must remain attacking=false across 100 ticks (tick ${tick})`) } win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'Space', key: ' ' })) assert(input.attacking === false, 'Space up must remain attacking=false') // 2.2 Legitimate attack keys DO set input.attacking (Positive Control) win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'KeyJ', key: 'j' })) assert(input.attacking === true, 'KeyJ down MUST set input.attacking to true') win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'KeyJ', key: 'j' })) assert(input.attacking === false, 'KeyJ up must clear input.attacking') win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Enter', key: 'Enter' })) assert(input.attacking === true, 'Enter down MUST set input.attacking to true') win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'Enter', key: 'Enter' })) assert(input.attacking === false, 'Enter up must clear input.attacking') // 2.3 GameEngine combat verification: Space does not swing or damage monsters const dummyTerrain: WorldMapProvider = { widthPx: 1000, heightPx: 1000, overlap: () => 0, } const dummyOpts: GameEngineOptions = { spawn: { x: 100, y: 100 }, stats: [ { id: 'mon1', name: 'Demon', hp: 100, damage: 0, cooldownTicks: 100, reach: 20, aggroRadius: 100, speed: 0, xp: 5 } ], xpTable: [0, 0, 10, 30, 60], itemBases: [ { id: 'sword', name: 'Sword', kind: 'weapon', invWidth: 1, invHeight: 3, maxStack: 1, value: 10, damage: 10, defense: 0, tags: ['weap'], level: 1 } ], prefixAffixes: [], suffixAffixes: [], skills: [ { id: 'attack', name: 'Attack', manaCost: 0, cooldownTicks: 1, range: 48, projectile: false, speed: 0, baseMinDamage: 10, baseMaxDamage: 15, damagePerLevel: 1, radius: 20 }, ], npcDefs: [ { id: 'akara', name: 'Akara', questId: null, offerLines: [], progressLines: [], doneLines: [] } ], questDefs: [], combatOptions: { playerSpeed: 100, playerReach: 50, playerCooldownTicks: 1, playerDamage: 10, playerManaPerAttack: 0, respawnTicks: 100, }, lootSeed: 12345, talkRadius: 50, pickupRadius: 50, inventoryCols: 10, inventoryRows: 4, } const engine = new GameEngine(dummyTerrain, dummyOpts) // Place monster right next to player (player at 100, 100; monster at 110, 100) assert(engine.world.monsters.length > 0, 'Engine must have spawned monsters') engine.world.monsters[0]!.x = 110 engine.world.monsters[0]!.y = 100 const initialMonsterHp = engine.world.monsters[0]!.hp const initialHits = engine.metrics.playerHits // Tick engine with Space held via KeyboardInput win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Space', key: ' ' })) for (let tick = 0; tick < 50; tick++) { engine.tick({ movement: input.movement(), attacking: input.attacking, pickingUp: input.pickingUp, talking: input.talking, digits: input.digits, saving: input.saving, loading: input.loading, }) } win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'Space', key: ' ' })) assert(engine.world.monsters[0]!.hp === initialMonsterHp, `Space key MUST NOT cause damage to monster (HP was ${initialMonsterHp}, now ${engine.world.monsters[0]!.hp})`) assert(engine.metrics.playerHits === initialHits, `Space key MUST NOT register combat hits (hits was ${initialHits}, now ${engine.metrics.playerHits})`) // Compare with KeyJ: ticking with KeyJ MUST damage monster win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'KeyJ', key: 'j' })) for (let tick = 0; tick < 10; tick++) { engine.tick({ movement: input.movement(), attacking: input.attacking, pickingUp: input.pickingUp, talking: input.talking, digits: input.digits, saving: input.saving, loading: input.loading, }) } win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'KeyJ', key: 'j' })) assert(engine.world.monsters[0]!.hp < initialMonsterHp, 'KeyJ attack MUST inflict damage on adjacent monster (Positive Control)') assert(engine.metrics.playerHits > initialHits, 'KeyJ attack MUST register combat hits in metrics (Positive Control)') // 2.4 Panel Dismissal in HudManager: Space and Escape const hudCanvas = new MockCanvas() as unknown as HTMLCanvasElement const hud = new HudManager(hudCanvas, { onToggleAutomap: () => {}, onWaypointTeleport: () => {}, }) hud['bindEvents']() // Test Space closing Character Sheet hud.toggleLeftPanel('char') assert(hud.leftPanel === 'char', 'Left panel should be char') mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Space', key: ' ' })) assert(hud.leftPanel === 'none', 'Space MUST close Character Sheet') // Test Space closing Inventory Panel hud.toggleRightPanel('inv') assert(hud.rightPanel === 'inv', 'Right panel should be inv') mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Space', key: ' ' })) assert(hud.rightPanel === 'none', 'Space MUST close Inventory Panel') // Test Space closing Skill Tree Panel hud.toggleRightPanel('skill') assert(hud.rightPanel === 'skill', 'Right panel should be skill') mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Space', key: ' ' })) assert(hud.rightPanel === 'none', 'Space MUST close Skill Tree Panel') // Test Space closing both panels + belt + popup concurrently hud.toggleLeftPanel('quest') hud.toggleRightPanel('skill') hud.belt.lockedOpen = true hud.hotkeys.openPopup = 'right' assert(hud.leftPanel === 'quest' && hud.rightPanel === 'skill', 'Panels should be open') mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Space', key: ' ' })) assert(hud.leftPanel === 'none', 'Space MUST close leftPanel') assert(hud.rightPanel === 'none', 'Space MUST close rightPanel') assert((hud.belt.lockedOpen as boolean) === false, 'Space MUST close lockedOpen belt') assert(hud.hotkeys.openPopup === null, 'Space MUST close hotkey popup') // Test Escape parity with Space hud.toggleLeftPanel('waypoint') hud.toggleRightPanel('inv') assert(hud.leftPanel === 'waypoint' && hud.rightPanel === 'inv', 'Panels open before Escape') mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Escape', key: 'Escape' })) assert(hud.leftPanel === 'none', 'Escape MUST close leftPanel') assert(hud.rightPanel === 'none', 'Escape MUST close rightPanel') } // ----------------------------------------------------------------------------- // SUITE 3: Belt Potion Drinking & Skill Preservation (Keys 1..4) // ----------------------------------------------------------------------------- console.log('\n--- [Suite 3] Belt Drinking & Skill Preservation (Keys 1..4) ---') { const win = new MockWindow() const input = new KeyboardInput(win as unknown as Window) input.attach() // 3.1 Digit keys on KeyboardInput return [] for (const code of ['Digit1', 'Digit2', 'Digit3', 'Digit4']) { win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code, key: code.slice(-1) })) assert(input.digits.length === 0, `input.digits MUST return [] when ${code} is pressed`) } assert(input.digits.length === 0, 'input.digits must be [] when all 1..4 are held') for (const code of ['Digit1', 'Digit2', 'Digit3', 'Digit4']) { win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code, key: code.slice(-1) })) } // 3.2 GameEngine skill selection invariance const dummyTerrain: WorldMapProvider = { widthPx: 1000, heightPx: 1000, overlap: () => 0 } const dummyOpts: GameEngineOptions = { spawn: { x: 100, y: 100 }, stats: [], xpTable: [0, 0, 10, 30, 60], itemBases: [], prefixAffixes: [], suffixAffixes: [], skills: [ { id: 'sk0', name: 'Skill 0', manaCost: 0, cooldownTicks: 1, range: 48, projectile: false, speed: 0, baseMinDamage: 1, baseMaxDamage: 2, damagePerLevel: 1, radius: 20 }, { id: 'sk1', name: 'Skill 1', manaCost: 0, cooldownTicks: 1, range: 48, projectile: false, speed: 0, baseMinDamage: 1, baseMaxDamage: 2, damagePerLevel: 1, radius: 20 }, { id: 'sk2', name: 'Skill 2', manaCost: 0, cooldownTicks: 1, range: 48, projectile: false, speed: 0, baseMinDamage: 1, baseMaxDamage: 2, damagePerLevel: 1, radius: 20 }, { id: 'sk3', name: 'Skill 3', manaCost: 0, cooldownTicks: 1, range: 48, projectile: false, speed: 0, baseMinDamage: 1, baseMaxDamage: 2, damagePerLevel: 1, radius: 20 }, ], npcDefs: [], questDefs: [], combatOptions: { playerSpeed: 100, playerReach: 50, playerCooldownTicks: 1, playerDamage: 10, playerManaPerAttack: 0, respawnTicks: 100 }, lootSeed: 12345, talkRadius: 50, pickupRadius: 50, inventoryCols: 10, inventoryRows: 4, } const engine = new GameEngine(dummyTerrain, dummyOpts) engine.selectedSkill = 2 // Choose Skill 2 assert(engine.selectedSkill === 2, 'Initial selectedSkill should be 2') // Tick engine with Digit1..Digit4 pressed win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Digit1', key: '1' })) engine.tick({ movement: input.movement(), attacking: input.attacking, pickingUp: input.pickingUp, talking: input.talking, digits: input.digits, saving: input.saving, loading: input.loading, }) assert(engine.selectedSkill === 2, 'engine.selectedSkill MUST remain 2 after Digit1 tick') win.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Digit4', key: '4' })) engine.tick({ movement: input.movement(), attacking: input.attacking, pickingUp: input.pickingUp, talking: input.talking, digits: input.digits, saving: input.saving, loading: input.loading, }) assert(engine.selectedSkill === 2, 'engine.selectedSkill MUST remain 2 after Digit4 tick') win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'Digit1', key: '1' })) win.dispatchEvent(new SyntheticKeyboardEvent('keyup', { code: 'Digit4', key: '4' })) // 3.3 HudManager Potion Drinking & Skill Preservation const hudCanvas = new MockCanvas() as unknown as HTMLCanvasElement const hud = new HudManager(hudCanvas, { onToggleAutomap: () => {}, onWaypointTeleport: () => {}, }) hud['bindEvents']() // Configure distinct active skills: Left = 47 (Fire Ball), Right = 64 (Frozen Orb) hud.hotkeys.leftSkillId = 47 hud.hotkeys.rightSkillId = 64 hud.syncPublishedState() assert(hud.state.leftSkillId === 47, 'Initial published leftSkillId should be 47') assert(hud.state.rightSkillId === 64, 'Initial published rightSkillId should be 64') // Lower HP and Mana to verify drinking effects hud.hp = 300 hud.mana = 200 hud.syncPublishedState() const initialTotalPotions = hud.belt.countTotalPotions() assert(initialTotalPotions === 16, 'Full belt should have 16 potions (4 cols x 4 rows)') // --- Drink Column 0 (Key '1') --- const hpBefore1 = hud.hp mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Digit1', key: '1' })) assert(hud.hp > hpBefore1, `Key 1 MUST consume health potion and heal HP (was ${hpBefore1}, now ${hud.hp})`) assert(hud.hotkeys.leftSkillId === 47, 'Key 1 MUST NOT alter hotkeys.leftSkillId (remains 47)') assert(hud.hotkeys.rightSkillId === 64, 'Key 1 MUST NOT alter hotkeys.rightSkillId (remains 64)') assert(hud.state.leftSkillId === 47, 'Key 1 MUST NOT alter state.leftSkillId (remains 47)') assert(hud.state.rightSkillId === 64, 'Key 1 MUST NOT alter state.rightSkillId (remains 64)') assert(hud.belt.countTotalPotions() === initialTotalPotions - 1, 'Belt potion count must decrement by 1') // --- Drink Column 1 (Key '2') --- const hpBefore2 = hud.hp mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Digit2', key: '2' })) assert(hud.hp >= hpBefore2, `Key 2 MUST consume column 1 potion (was ${hpBefore2}, now ${hud.hp})`) assert(hud.hotkeys.leftSkillId === 47, 'Key 2 MUST NOT alter leftSkillId') assert(hud.hotkeys.rightSkillId === 64, 'Key 2 MUST NOT alter rightSkillId') assert(hud.state.leftSkillId === 47, 'Key 2 MUST NOT alter state leftSkillId') assert(hud.state.rightSkillId === 64, 'Key 2 MUST NOT alter state rightSkillId') assert(hud.belt.countTotalPotions() === initialTotalPotions - 2, 'Belt potion count must decrement by 2') // --- Drink Column 2 (Key '3') --- const manaBefore3 = hud.mana mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Digit3', key: '3' })) assert(hud.mana > manaBefore3, `Key 3 MUST consume mana potion and restore Mana (was ${manaBefore3}, now ${hud.mana})`) assert(hud.hotkeys.leftSkillId === 47, 'Key 3 MUST NOT alter leftSkillId') assert(hud.hotkeys.rightSkillId === 64, 'Key 3 MUST NOT alter rightSkillId') assert(hud.state.leftSkillId === 47, 'Key 3 MUST NOT alter state leftSkillId') assert(hud.state.rightSkillId === 64, 'Key 3 MUST NOT alter state rightSkillId') assert(hud.belt.countTotalPotions() === initialTotalPotions - 3, 'Belt potion count must decrement by 3') // --- Drink Column 3 (Key '4') --- hud.hp = 500 hud.mana = 200 mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: 'Digit4', key: '4' })) assert(hud.hp === 500 + 400 && hud.mana === 200 + 400, `Key 4 MUST consume rejuv potion and heal 400 HP & Mana (hp: ${hud.hp}, mana: ${hud.mana})`) assert(hud.hotkeys.leftSkillId === 47, 'Key 4 MUST NOT alter leftSkillId') assert(hud.hotkeys.rightSkillId === 64, 'Key 4 MUST NOT alter rightSkillId') assert(hud.state.leftSkillId === 47, 'Key 4 MUST NOT alter state leftSkillId') assert(hud.state.rightSkillId === 64, 'Key 4 MUST NOT alter state rightSkillId') assert(hud.belt.countTotalPotions() === initialTotalPotions - 4, 'Belt potion count must decrement by 4') // 3.4 Exhaust remaining belt slots (drink all 12 remaining potions) for (let c = 0; c < 4; c++) { for (let r = 0; r < 3; r++) { hud.drinkBeltSlot(c) } } assert(hud.belt.countTotalPotions() === 0, 'Belt should now be completely empty (0 potions)') // Adversarial test: pressing 1..4 on empty belt for (const key of ['1', '2', '3', '4']) { const consumed = hud.drinkBeltSlot(Number(key) - 1) assert(consumed === false, `Drinking from empty slot column ${Number(key) - 1} must return false`) mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', { code: `Digit${key}`, key })) assert(hud.hotkeys.leftSkillId === 47, `Empty belt press ${key} must NOT alter leftSkillId`) assert(hud.hotkeys.rightSkillId === 64, `Empty belt press ${key} must NOT alter rightSkillId`) assert(!Number.isNaN(hud.hp) && !Number.isNaN(hud.mana), `Empty belt press ${key} must NOT cause NaN`) } // Boundary column tests: out-of-range columns assert(hud.drinkBeltSlot(-1) === false, 'drinkBeltSlot(-1) must return false') assert(hud.drinkBeltSlot(4) === false, 'drinkBeltSlot(4) must return false') assert(hud.drinkBeltSlot(100) === false, 'drinkBeltSlot(100) must return false') assert(hud.hotkeys.leftSkillId === 47 && hud.hotkeys.rightSkillId === 64, 'Out-of-range drinkBeltSlot must not mutate skills') } // ----------------------------------------------------------------------------- // SUITE 4: Adversarial Fuzzing & Differential Invariant Testing (5,000 Iterations) // ----------------------------------------------------------------------------- console.log('\n--- [Suite 4] Adversarial Fuzzing & Differential Testing (5,000 Iterations) ---') { const win = new MockWindow() const input = new KeyboardInput(win as unknown as Window) input.attach() const hudCanvas = new MockCanvas() as unknown as HTMLCanvasElement const hud = new HudManager(hudCanvas, { onToggleAutomap: () => {}, onWaypointTeleport: () => {}, }) hud['bindEvents']() hud.hotkeys.leftSkillId = 47 hud.hotkeys.rightSkillId = 64 hud.syncPublishedState() const candidateKeys = [ { code: 'KeyT', key: 't' }, { code: 'KeyB', key: 'b' }, { code: 'Space', key: ' ' }, { code: 'Digit1', key: '1' }, { code: 'Digit2', key: '2' }, { code: 'Digit3', key: '3' }, { code: 'Digit4', key: '4' }, { code: 'KeyW', key: 'w' }, { code: 'KeyA', key: 'a' }, { code: 'KeyS', key: 's' }, { code: 'KeyD', key: 'd' }, { code: 'KeyC', key: 'c' }, { code: 'KeyJ', key: 'j' }, { code: 'Enter', key: 'Enter' }, { code: 'ShiftLeft', key: 'Shift' }, { code: 'ShiftRight', key: 'Shift' }, { code: 'ArrowUp', key: 'ArrowUp' }, { code: 'ArrowDown', key: 'ArrowDown' }, { code: 'ArrowLeft', key: 'ArrowLeft' }, { code: 'ArrowRight', key: 'ArrowRight' }, { code: 'Escape', key: 'Escape' }, ] const currentlyHeld = new Set() // Run 5,000 randomized state transitions const NUM_ITERATIONS = 5000 for (let i = 0; i < NUM_ITERATIONS; i++) { const candidate = candidateKeys[Math.floor(Math.random() * candidateKeys.length)]! const isDown = Math.random() > 0.45 // 55% keydown, 45% keyup if (isDown) { currentlyHeld.add(candidate.code) win.dispatchEvent(new SyntheticKeyboardEvent('keydown', candidate)) mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', candidate)) } else { currentlyHeld.delete(candidate.code) win.dispatchEvent(new SyntheticKeyboardEvent('keyup', candidate)) mockWin.dispatchEvent(new SyntheticKeyboardEvent('keyup', candidate)) } // --- INVARIANT ORACLE VERIFICATIONS --- // Invariant 1: input.talking is ALWAYS false (KeyT decoupled) assert(input.talking === false, `[Fuzz Step ${i}] input.talking MUST be false (held: ${Array.from(currentlyHeld).join(',')})`) // Invariant 2: input.takeWaypoint() is ALWAYS false (KeyB decoupled) assert(input.takeWaypoint() === false, `[Fuzz Step ${i}] input.takeWaypoint() MUST be false (held: ${Array.from(currentlyHeld).join(',')})`) // Invariant 3: Space NEVER contributes to attacking const expectedAttacking = currentlyHeld.has('KeyJ') || currentlyHeld.has('Enter') assert(input.attacking === expectedAttacking, `[Fuzz Step ${i}] input.attacking mismatch: expected ${expectedAttacking}, got ${input.attacking}`) // Invariant 4: input.digits is ALWAYS [] assert(input.digits.length === 0, `[Fuzz Step ${i}] input.digits MUST be empty array`) // Invariant 5: WASD NEVER contributes to movement const mov = input.movement() if (!currentlyHeld.has('ArrowUp') && !currentlyHeld.has('ArrowDown') && !currentlyHeld.has('ArrowLeft') && !currentlyHeld.has('ArrowRight')) { assert(mov.x === 0 && mov.y === 0, `[Fuzz Step ${i}] Movement must be {0,0} when no arrow keys held, even if WASD are held. Got {${mov.x}, ${mov.y}}`) } // Invariant 6: Shift tracking const expectedShift = currentlyHeld.has('ShiftLeft') || currentlyHeld.has('ShiftRight') assert(input.shiftHeld === expectedShift, `[Fuzz Step ${i}] ShiftHeld mismatch: expected ${expectedShift}, got ${input.shiftHeld}`) // Invariant 7: Active skill IDs in HudManager remain strictly untouched assert(hud.hotkeys.leftSkillId === 47, `[Fuzz Step ${i}] leftSkillId mutated! Got ${hud.hotkeys.leftSkillId}`) assert(hud.hotkeys.rightSkillId === 64, `[Fuzz Step ${i}] rightSkillId mutated! Got ${hud.hotkeys.rightSkillId}`) assert(hud.state.leftSkillId === 47, `[Fuzz Step ${i}] state.leftSkillId mutated! Got ${hud.state.leftSkillId}`) assert(hud.state.rightSkillId === 64, `[Fuzz Step ${i}] state.rightSkillId mutated! Got ${hud.state.rightSkillId}`) } console.log(`✅ Passed 5,000 randomized fuzzing iterations with 7 live invariant checks per step (${NUM_ITERATIONS * 7} assertions)`) } // ----------------------------------------------------------------------------- // SUITE 5: Simultaneous Chord Stress (All problematic keys pressed at once) // ----------------------------------------------------------------------------- console.log('\n--- [Suite 5] Simultaneous Chord Stress (Space + KeyT + KeyB + 1..4 + WASD) ---') { const win = new MockWindow() const input = new KeyboardInput(win as unknown as Window) input.attach() const hudCanvas = new MockCanvas() as unknown as HTMLCanvasElement const hud = new HudManager(hudCanvas, { onToggleAutomap: () => {}, onWaypointTeleport: () => {}, }) hud['bindEvents']() hud.hotkeys.leftSkillId = 47 hud.hotkeys.rightSkillId = 64 hud.syncPublishedState() const chord = [ { code: 'KeyA', key: 'a' }, { code: 'KeyT', key: 't' }, { code: 'KeyB', key: 'b' }, { code: 'Digit1', key: '1' }, { code: 'Digit2', key: '2' }, { code: 'Digit3', key: '3' }, { code: 'Digit4', key: '4' }, { code: 'KeyW', key: 'w' }, { code: 'KeyS', key: 's' }, { code: 'KeyD', key: 'd' }, { code: 'Space', key: ' ' }, ] for (const evt of chord) { win.dispatchEvent(new SyntheticKeyboardEvent('keydown', evt)) mockWin.dispatchEvent(new SyntheticKeyboardEvent('keydown', evt)) } assert(input.talking === false, 'Simultaneous chord: talking MUST be false') assert(input.takeWaypoint() === false, 'Simultaneous chord: takeWaypoint MUST be false') assert(input.attacking === false, 'Simultaneous chord: attacking MUST be false (Space does not attack)') assert(input.digits.length === 0, 'Simultaneous chord: digits MUST be []') assert(input.movement().x === 0 && input.movement().y === 0, 'Simultaneous chord: movement MUST be {0, 0}') assert(input.active === false, 'Simultaneous chord: active MUST be false') assert(hud.leftPanel === 'none', 'Simultaneous chord: Space closes leftPanel') assert(hud.rightPanel === 'none', 'Simultaneous chord: Space closes rightPanel') assert(hud.hotkeys.leftSkillId === 47, 'Simultaneous chord: leftSkillId is 47') assert(hud.hotkeys.rightSkillId === 64, 'Simultaneous chord: rightSkillId is 64') for (const evt of chord) { win.dispatchEvent(new SyntheticKeyboardEvent('keyup', evt)) mockWin.dispatchEvent(new SyntheticKeyboardEvent('keyup', evt)) } } console.log('\n=================================================================') console.log(`🎉 EMPIRICAL STRESS TEST RESULTS:`) console.log(`Total Assertions Executed: ${totalAssertions}`) console.log(`Assertions Passed: ${passedAssertions}`) console.log(`Assertions Failed: ${failedAssertions}`) console.log('Verdict: EMPIRICAL PROOF OF CORRECTNESS CONFIRMED') console.log('=================================================================') } runTestSuite().catch((err) => { console.error('Fatal error in stress test harness:', err) process.exit(1) })