/** * Standalone Adversarial Stress-Test Script for Milestone M2 * Diablo II Web DRLG Engine: Organic Geometry & Fractional Jitter Profiler * * Requirements: * 1. Stress-test Act 2 Oasis and Act 5 Frozen Lake radial lobe perturbations across 100+ random seeds and phase variations: * - Numerically compute P^2 / A for continuous polar contour and discrete rasterized tile cells. * - Assert P^2 / A > 4*pi * 1.15 holds 100% of the time (zero violations). * 2. Stress-test jitterFrac: sample 10,000 draws and assert all values strictly lie in [base - delta, base + delta]. * 3. Verify Act 4 Lava Fissure flood-fill reachability >= 90%. * 4. Verify Act 5 Transverse Barricade palisade orientation and choke-point gate clearance. * * Act I's outdoor levels are generated by the DRLG port (src/game/drlg), not by generateWilderness; * tests/drlg-act1-oracle.test.ts and tests/drlg-act1-invariants.test.ts cover them. * * Archetype: EMPIRICAL CHALLENGER */ import type { Ds1, Ds1Cell } from '../src/formats/ds1.ts' import { generateWilderness, type WildernessPiece, } from '../src/game/wilderness.ts' import { act2OasisRadius, act5FrozenLakeRadius, jitterFrac, type Act2TopographyStats, type Act5TopographyStats, } from '../src/game/wilderness-acts.ts' import { Rng } from '../src/game/rng.ts' /* ------------------------------------------------------------------------- * * Mathematical Helpers: Continuous & Discrete Isoperimetric Quotients * ------------------------------------------------------------------------- */ const ORGANIC_THRESHOLD = 4 * Math.PI * 1.15 // ~14.451326206513047 /** * Numerically compute continuous polar contour area, perimeter, and P^2 / A. */ function computeContinuousPolarQuotient( radiusFn: (theta: number) => number, steps = 2000, ): { area: number; perimeter: number; quotient: number } { let area = 0 let perimeter = 0 const dTheta = (2 * Math.PI) / steps for (let i = 0; i < steps; i += 1) { const t1 = i * dTheta const t2 = (i + 1) * dTheta const r1 = radiusFn(t1) const r2 = radiusFn(t2) // Sector area via cross product area += 0.5 * r1 * r2 * Math.sin(dTheta) // Arc length via Euclidean chord const x1 = r1 * Math.cos(t1) const y1 = r1 * Math.sin(t1) const x2 = r2 * Math.cos(t2) const y2 = r2 * Math.sin(t2) perimeter += Math.hypot(x2 - x1, y2 - y1) } const quotient = (perimeter * perimeter) / area return { area, perimeter, quotient } } /** * Numerically compute discrete rasterized tile cells area, perimeter, and P^2 / A. */ function computeDiscreteRasterQuotient( radiusFn: (theta: number) => number, R: number, ): { area: number; perimeter: number; quotient: number } { const maxR = Math.ceil(R * 1.5) + 3 const inside = new Set() for (let dy = -maxR; dy <= maxR; dy += 1) { for (let dx = -maxR; dx <= maxR; dx += 1) { const dist = Math.hypot(dx, dy) const theta = Math.atan2(dy, dx) const rLobe = radiusFn(theta) if (dist <= rLobe) { inside.add(`${dx},${dy}`) } } } const area = inside.size let perimeter = 0 for (const key of inside) { const comma = key.indexOf(',') const x = Number(key.slice(0, comma)) const y = Number(key.slice(comma + 1)) if (!inside.has(`${x + 1},${y}`)) perimeter += 1 if (!inside.has(`${x - 1},${y}`)) perimeter += 1 if (!inside.has(`${x},${y + 1}`)) perimeter += 1 if (!inside.has(`${x},${y - 1}`)) perimeter += 1 } const quotient = area > 0 ? (perimeter * perimeter) / area : 0 return { area, perimeter, quotient } } /* ------------------------------------------------------------------------- * * Mock DS1 and Piece Builders for Hermetic Testing * ------------------------------------------------------------------------- */ function makeMockDs1(width: number, height: number): Ds1 { const cells: Ds1Cell[][] = [] for (let y = 0; y < height; y += 1) { const row: Ds1Cell[] = [] for (let x = 0; x < width; x += 1) { row.push({ walls: [], floors: [{ prop1: 2, sequence: 0, style: 1, unknown1: 0, unknown2: 0, hidden: false }], shadows: [], substitutions: [], }) } cells.push(row) } return { version: 18, width, height, act: 1, substitutionType: 0, wallLayers: 1, floorLayers: 1, cells, objects: [], npcPathOffset: null, } } function makeMockBorderPieces(actPrefix: string): WildernessPiece[] { const ds1 = makeMockDs1(8, 8) return [ { name: `${actPrefix} - Border 1`, border: true, levels: [ds1] }, { name: `${actPrefix} - Border 2`, border: true, levels: [ds1] }, { name: `${actPrefix} - Border 3`, border: true, levels: [ds1] }, { name: `${actPrefix} - Border 4`, border: true, levels: [ds1] }, { name: `${actPrefix} - Border 5`, border: true, levels: [ds1] }, { name: `${actPrefix} - Border 6`, border: true, levels: [ds1] }, ] } /* ------------------------------------------------------------------------- * * Stress Test Harness * ------------------------------------------------------------------------- */ async function main() { console.log('======================================================================') console.log('šŸ”„ DIABLO II WEB DRLG: STANDALONE ADVERSARIAL STRESS TEST (MILESTONE M2)') console.log('======================================================================\n') let totalAssertions = 0 let passedAssertions = 0 let failedAssertions = 0 const failureLog: string[] = [] function check(condition: boolean, message: string) { totalAssertions += 1 if (condition) { passedAssertions += 1 } else { failedAssertions += 1 failureLog.push(message) console.error(` āŒ FAILED: ${message}`) } } // ------------------------------------------------------------------------- // SECTION 1: JitterFrac Sampling (10,000 Draws) // ------------------------------------------------------------------------- console.log('--- SECTION 1: STRESS-TESTING JitterFrac (10,000 Draws) ---') const jitterRng = new Rng(0xbadf00d) const testConfigs = [ { base: 0.50, delta: 0.05, count: 2000 }, { base: 0.35, delta: 0.04, count: 1500 }, { base: 0.70, delta: 0.04, count: 1500 }, { base: 0.22, delta: 0.05, count: 1500 }, { base: 0.68, delta: 0.05, count: 1500 }, { base: 0.40, delta: 0.05, count: 1000 }, // Boundary clamp checks { base: 0.03, delta: 0.05, count: 500 }, // lower clamp at 0.01 { base: 0.97, delta: 0.05, count: 500 }, // upper clamp at 0.99 ] let totalDraws = 0 for (const cfg of testConfigs) { const minAllowed = Math.max(0.01, cfg.base - cfg.delta) const maxAllowed = Math.min(0.99, cfg.base + cfg.delta) const draws: number[] = [] for (let i = 0; i < cfg.count; i += 1) { const val = jitterFrac(jitterRng, cfg.base, cfg.delta) totalDraws += 1 const inBounds = val >= minAllowed && val <= maxAllowed if (!inBounds) { check(false, `jitterFrac out of bounds: val=${val}, allowed=[${minAllowed}, ${maxAllowed}], base=${cfg.base}, delta=${cfg.delta}`) } draws.push(val) } const minObs = Math.min(...draws) const maxObs = Math.max(...draws) const meanObs = draws.reduce((a, b) => a + b, 0) / draws.length check(minObs >= minAllowed && maxObs <= maxAllowed, `All ${cfg.count} draws strictly in [${minAllowed.toFixed(4)}, ${maxAllowed.toFixed(4)}]`) console.log( ` Base: ${cfg.base.toFixed(2)} ± ${cfg.delta.toFixed(2)} (${cfg.count} draws) | ` + `Observed: [${minObs.toFixed(4)} .. ${maxObs.toFixed(4)}] | Mean: ${meanObs.toFixed(4)} | PASSED` ) } check(totalDraws === 10000, `Total jitterFrac draws reached exactly 10,000 (${totalDraws})`) console.log(` āœ“ 10,000 draws sampled: 0 violations, 100% strictly bounded.\n`) // ------------------------------------------------------------------------- // SECTION 2: Act 2 Oasis Radial Lobe Harmonic Perturbations (150+ Seeds & Phases) // ------------------------------------------------------------------------- console.log('--- SECTION 2: STRESS-TESTING Act 2 Oasis Radial Lobes (P^2 / A > 4*pi * 1.15) ---') const oasisRng = new Rng(0x0a515001) const testRadiiAct2 = [4, 5, 6, 8, 10, 14, 20, 30] let act2ContViolations = 0 let act2DiscViolations = 0 let act2TotalTests = 0 let minAct2ContQ = Infinity let maxAct2ContQ = -Infinity let minAct2DiscQ = Infinity let maxAct2DiscQ = -Infinity for (let seedIdx = 0; seedIdx < 150; seedIdx += 1) { const phi1 = oasisRng.range(0, 2 * Math.PI) const phi2 = oasisRng.range(0, 2 * Math.PI) for (const R of testRadiiAct2) { act2TotalTests += 1 const radiusFn = (theta: number) => act2OasisRadius(R, theta, phi1, phi2) // Continuous polar contour const cont = computeContinuousPolarQuotient(radiusFn, 2000) if (cont.quotient < minAct2ContQ) minAct2ContQ = cont.quotient if (cont.quotient > maxAct2ContQ) maxAct2ContQ = cont.quotient if (cont.quotient <= ORGANIC_THRESHOLD) { act2ContViolations += 1 check(false, `Act 2 continuous P^2/A violation: ${cont.quotient} <= ${ORGANIC_THRESHOLD} (R=${R}, phi1=${phi1}, phi2=${phi2})`) } // Discrete rasterized tile cells const disc = computeDiscreteRasterQuotient(radiusFn, R) if (disc.quotient < minAct2DiscQ) minAct2DiscQ = disc.quotient if (disc.quotient > maxAct2DiscQ) maxAct2DiscQ = disc.quotient if (disc.quotient <= ORGANIC_THRESHOLD) { act2DiscViolations += 1 check(false, `Act 2 discrete P^2/A violation: ${disc.quotient} <= ${ORGANIC_THRESHOLD} (R=${R}, phi1=${phi1}, phi2=${phi2})`) } } } check(act2ContViolations === 0, `Act 2 continuous P^2/A zero violations across ${act2TotalTests} configurations`) check(act2DiscViolations === 0, `Act 2 discrete P^2/A zero violations across ${act2TotalTests} configurations`) console.log(` Act 2 Oasis Tested: ${act2TotalTests} configurations across 150 seeds and ${testRadiiAct2.length} radii.`) console.log(` Continuous P^2/A range: [${minAct2ContQ.toFixed(4)} .. ${maxAct2ContQ.toFixed(4)}] (Threshold: > ${ORGANIC_THRESHOLD.toFixed(4)})`) console.log(` Discrete P^2/A range: [${minAct2DiscQ.toFixed(4)} .. ${maxAct2DiscQ.toFixed(4)}] (Threshold: > ${ORGANIC_THRESHOLD.toFixed(4)})`) console.log(` āœ“ Act 2 Oasis: 0 violations, 100% strictly exceed isoperimetric threshold.\n`) // ------------------------------------------------------------------------- // SECTION 3: Act 5 Frozen Lake Radial Lobe Harmonic Perturbations (150+ Seeds & Phases) // ------------------------------------------------------------------------- console.log('--- SECTION 3: STRESS-TESTING Act 5 Frozen Lake Radial Lobes (P^2 / A > 4*pi * 1.15) ---') const lakeRng = new Rng(0x1a7e5001) const testRadiiAct5 = [6, 7, 8, 10, 12, 16, 22] let act5ContViolations = 0 let act5DiscViolations = 0 let act5TotalTests = 0 let minAct5ContQ = Infinity let maxAct5ContQ = -Infinity let minAct5DiscQ = Infinity let maxAct5DiscQ = -Infinity for (let seedIdx = 0; seedIdx < 150; seedIdx += 1) { const phi1 = lakeRng.range(0, 2 * Math.PI) const phi2 = lakeRng.range(0, 2 * Math.PI) for (const R of testRadiiAct5) { act5TotalTests += 1 const radiusFn = (theta: number) => act5FrozenLakeRadius(R, theta, phi1, phi2) // Continuous polar contour const cont = computeContinuousPolarQuotient(radiusFn, 2000) if (cont.quotient < minAct5ContQ) minAct5ContQ = cont.quotient if (cont.quotient > maxAct5ContQ) maxAct5ContQ = cont.quotient if (cont.quotient <= ORGANIC_THRESHOLD) { act5ContViolations += 1 check(false, `Act 5 continuous P^2/A violation: ${cont.quotient} <= ${ORGANIC_THRESHOLD} (R=${R}, phi1=${phi1}, phi2=${phi2})`) } // Discrete rasterized tile cells const disc = computeDiscreteRasterQuotient(radiusFn, R) if (disc.quotient < minAct5DiscQ) minAct5DiscQ = disc.quotient if (disc.quotient > maxAct5DiscQ) maxAct5DiscQ = disc.quotient if (disc.quotient <= ORGANIC_THRESHOLD) { act5DiscViolations += 1 check(false, `Act 5 discrete P^2/A violation: ${disc.quotient} <= ${ORGANIC_THRESHOLD} (R=${R}, phi1=${phi1}, phi2=${phi2})`) } } } check(act5ContViolations === 0, `Act 5 continuous P^2/A zero violations across ${act5TotalTests} configurations`) check(act5DiscViolations === 0, `Act 5 discrete P^2/A zero violations across ${act5TotalTests} configurations`) console.log(` Act 5 Frozen Lake Tested: ${act5TotalTests} configurations across 150 seeds and ${testRadiiAct5.length} radii.`) console.log(` Continuous P^2/A range: [${minAct5ContQ.toFixed(4)} .. ${maxAct5ContQ.toFixed(4)}] (Threshold: > ${ORGANIC_THRESHOLD.toFixed(4)})`) console.log(` Discrete P^2/A range: [${minAct5DiscQ.toFixed(4)} .. ${maxAct5DiscQ.toFixed(4)}] (Threshold: > ${ORGANIC_THRESHOLD.toFixed(4)})`) console.log(` āœ“ Act 5 Frozen Lake: 0 violations, 100% strictly exceed isoperimetric threshold.\n`) // ------------------------------------------------------------------------- // SECTION 4: Real Generated Wilderness Level Audits across 100 Seeds // ------------------------------------------------------------------------- console.log('--- SECTION 4: FULL WILDERNESS ENGINE MAP AUDITS (100 Seeds) ---') const mapRng = new Rng(0x99887766) const mapSeeds: number[] = [0x301cd095, 0x416d61c5, 0xdeadbeef] for (let i = 0; i < 97; i += 1) { mapSeeds.push(mapRng.int(100000, 99999999)) } const act2Pieces = makeMockBorderPieces('Act 2') const act4Pieces = makeMockBorderPieces('Act 4') const act5Pieces = makeMockBorderPieces('Act 5') let oasisMapChecks = 0 let frozenLakeMapChecks = 0 let fissureConnectivityChecks = 0 let barricadeChecks = 0 for (const seed of mapSeeds) { // 1. Act 2 Far Oasis (Level 43) const oasisResult = generateWilderness({ levelId: 43, levelName: 'Far Oasis', levelTypeName: 'Act 2 - Desert', sizeX: 80, sizeY: 80, subType: 0, subTheme: 0, seed, pieces: act2Pieces, substitutions: [], }) const oW = oasisResult.level.width const oH = oasisResult.level.height const oCells = oasisResult.level.cells const isOasisWater = (x: number, y: number) => { if (x < 0 || x >= oW || y < 0 || y >= oH) return false return oCells[y]![x]!.floors.some(f => f.style === 2 && f.prop1 === 2) } // Find connected components of oasis water const visitedOasis = new Set() for (let y = 4; y < oH - 4; y += 1) { for (let x = 4; x < oW - 4; x += 1) { const key = `${x},${y}` if (isOasisWater(x, y) && !visitedOasis.has(key)) { // BFS component const comp: [number, number][] = [] const queue: [number, number][] = [[x, y]] visitedOasis.add(key) while (queue.length > 0) { const [cx, cy] = queue.shift()! comp.push([cx, cy]) for (const [dx, dy] of [[1, 0], [-1, 0], [0, 1], [0, -1]]) { const nx = cx + dx const ny = cy + dy const nKey = `${nx},${ny}` if (isOasisWater(nx, ny) && !visitedOasis.has(nKey)) { visitedOasis.add(nKey) queue.push([nx, ny]) } } } if (comp.length >= 10) { oasisMapChecks += 1 const compArea = comp.length let compPerim = 0 for (const [cx, cy] of comp) { if (!isOasisWater(cx + 1, cy)) compPerim += 1 if (!isOasisWater(cx - 1, cy)) compPerim += 1 if (!isOasisWater(cx, cy + 1)) compPerim += 1 if (!isOasisWater(cx, cy - 1)) compPerim += 1 } const compQ = (compPerim * compPerim) / compArea check(compQ > ORGANIC_THRESHOLD, `Map Far Oasis (seed ${seed}) pool P^2/A=${compQ.toFixed(2)} > ${ORGANIC_THRESHOLD.toFixed(2)}`) } } } } // 2. Act 5 Arreat Plateau (Level 112) const plateauResult = generateWilderness({ levelId: 112, levelName: 'Arreat Plateau', levelTypeName: 'Act 5 - Barricade', sizeX: 80, sizeY: 80, subType: 0, subTheme: 0, seed, pieces: act5Pieces, substitutions: [], }) const pH = plateauResult.level.height const pW = plateauResult.level.width const pCells = plateauResult.level.cells const isFrozenLake = (x: number, y: number) => { if (x < 0 || x >= pW || y < 0 || y >= pH) return false return pCells[y]![x]!.floors.some(f => f.style === 2 && f.sequence === 0 && f.prop1 === 2) } let lakeArea = 0 let lakePerim = 0 for (let y = 4; y < pH - 4; y += 1) { for (let x = 4; x < pW - 4; x += 1) { if (isFrozenLake(x, y)) { lakeArea += 1 if (!isFrozenLake(x + 1, y)) lakePerim += 1 if (!isFrozenLake(x - 1, y)) lakePerim += 1 if (!isFrozenLake(x, y + 1)) lakePerim += 1 if (!isFrozenLake(x, y - 1)) lakePerim += 1 } } } if (lakeArea >= 15) { frozenLakeMapChecks += 1 const lakeQ = (lakePerim * lakePerim) / lakeArea check(lakeQ > ORGANIC_THRESHOLD, `Map Arreat Plateau (seed ${seed}) lake P^2/A=${lakeQ.toFixed(2)} > ${ORGANIC_THRESHOLD.toFixed(2)}`) } // 3. Act 4 Outer Steppes (Level 104) - Lava Fissure Connectivity const steppesResult = generateWilderness({ levelId: 104, levelName: 'Outer Steppes', levelTypeName: 'Act 4 - Mesa', sizeX: 80, sizeY: 80, subType: 0, subTheme: 0, seed, pieces: act4Pieces, substitutions: [], }) const sW = steppesResult.level.width const sH = steppesResult.level.height const sCells = steppesResult.level.cells const isWalkable = (x: number, y: number) => { if (x < 8 || x >= sW - 8 || y < 8 || y >= sH - 8) return false const cell = sCells[y]![x]! return !cell.walls.some(w => w.prop1 !== 0 || w.style !== 0) } let totalWalkable = 0 let startX = -1 let startY = -1 for (let y = 8; y < sH - 8; y += 1) { for (let x = 8; x < sW - 8; x += 1) { if (isWalkable(x, y)) { totalWalkable += 1 if (startX === -1 && y < 16) { startX = x startY = y } } } } const visitedWalk = new Set() const walkQueue: [number, number][] = [[startX, startY]] visitedWalk.add(startY * sW + startX) while (walkQueue.length > 0) { const [cx, cy] = walkQueue.shift()! for (const [dx, dy] of [[1, 0], [-1, 0], [0, 1], [0, -1]]) { const nx = cx + dx const ny = cy + dy const key = ny * sW + nx if (isWalkable(nx, ny) && !visitedWalk.has(key)) { visitedWalk.add(key) walkQueue.push([nx, ny]) } } } const reachRatio = visitedWalk.size / totalWalkable fissureConnectivityChecks += 1 check(reachRatio >= 0.90, `Act 4 Level 104 (seed ${seed}) reachability=${(reachRatio * 100).toFixed(2)}% >= 90%`) // 4. Act 5 Frigid Highlands (Level 111) - Transverse Barricades const barricadeResult = generateWilderness({ levelId: 111, levelName: 'Frigid Highlands', levelTypeName: 'Act 5 - Barricade', sizeX: 48, sizeY: 160, subType: 0, subTheme: 0, seed, pieces: act5Pieces, substitutions: [], }) const bW = barricadeResult.level.width const bH = barricadeResult.level.height const bCells = barricadeResult.level.cells const bInX = Math.floor(Math.floor(48 / 8) / 2) const bHubX = bInX * 8 + 4 // Because height (160) > width (48), barricades must cut horizontally across X const hBarricadeRows: number[] = [] for (let y = 8; y < bH - 8; y += 1) { let palisadeCount = 0 for (let x = 8; x < bW - 8; x += 1) { if (bCells[y]![x]!.walls.some(w => w.style === 2 && w.prop1 === 129)) { palisadeCount += 1 } } if (palisadeCount >= 15) { hBarricadeRows.push(y) } } barricadeChecks += 1 check(hBarricadeRows.length >= 2, `Act 5 Level 111 (seed ${seed}) horizontal barricades: ${hBarricadeRows.length} >= 2`) for (const by of hBarricadeRows) { const gate = bCells[by]![bHubX]! const hasWall = gate.walls.some(w => w.prop1 !== 0 || w.style !== 0) const hasFloor = gate.floors.some(f => f.style === 5 && f.prop1 === 194) check(!hasWall && hasFloor, `Act 5 Level 111 (seed ${seed}, y=${by}) gate at hubX=${bHubX} open`) } } console.log(` Map Audits completed across 100 seeds:`) console.log(` - Oasis pool components audited: ${oasisMapChecks} checks (all P^2/A > 14.45)`) console.log(` - Frozen lake components audited: ${frozenLakeMapChecks} checks (all P^2/A > 14.45)`) console.log(` - Act 4 fissure reachability audited: ${fissureConnectivityChecks} checks (all >= 90.00%)`) console.log(` - Act 5 transverse barricade audited: ${barricadeChecks} checks (all perpendicular + open gate)`) console.log(` āœ“ Real level generation stress tests: 0 violations.\n`) // ------------------------------------------------------------------------- // FINAL REPORT // ------------------------------------------------------------------------- console.log('\n======================================================================') console.log('šŸ“Š M2 ADVERSARIAL STRESS TEST RESULTS') console.log('======================================================================') console.log(`Total Assertions Executed: ${totalAssertions}`) console.log(`Passed Assertions: ${passedAssertions}`) console.log(`Failed Assertions: ${failedAssertions}`) if (failedAssertions > 0) { console.error('\nāŒ FAILURES ENCOUNTERED:') for (const f of failureLog) { console.error(` - ${f}`) } process.exit(1) } console.log('\nāœ… ALL MILESTONE M2 GEOMETRIC, ISOPERIMETRIC & TOPOLOGICAL INVARIANTS CONFIRMED:') console.log('1. JitterFrac: 10,000 draws strictly in [base - delta, base + delta] with 0 violations.') console.log(`2. Act 2 Oasis: Continuous and discrete P^2/A strictly > 4pi * 1.15 across all seeds/phases.`) console.log(`3. Act 5 Frozen Lake: Continuous and discrete P^2/A strictly > 4pi * 1.15 across all seeds/phases.`) console.log(`4. Full Map Generation (100 seeds): 100% of water/lake bodies satisfy P^2/A > 4pi * 1.15.`) console.log(`5. Act 4 Lava Fissure: 100% of tested maps maintain >= 90% flood-fill reachability.`) console.log(`6. Act 5 Barricades: Transverse direction invariance & open choke-point gates verified.`) console.log('======================================================================\n') } main().catch(err => { console.error('Fatal stress test runner error:', err) process.exit(1) })