/** * Challenger M3_2 Empirical Verification & Adversarial Stress Suite * * Tests: * 1. Schema 2 alias parity and bugfix validation (walk/stand offset vs frame count). * 2. Complete 11-mode player animation metadata integrity. * 3. 68-monster R8 atlas validity, 6-tuple bounding boxes, and sprite-space anchor offsets. * 4. Act 1..5 PNG atlas valid PNG signatures and dimensions. * 5. Deterministic index ordering and global metadata consistency. * 6. Concurrency error resilience and atomic write cleanliness (zero orphaned .tmp files). */ import { describe, it, expect } from 'vitest' import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs' import { join } from 'node:path' describe('Challenger M3_2: Entity Asset Packing Concurrency & Schema Parity', () => { const packsDir = 'samples/d2-packs' const entitiesDir = join(packsDir, 'entities') const charSoJsonPath = join(entitiesDir, 'char-so.json') const charSoR8Path = join(entitiesDir, 'char-so.r8') const indexJsonPath = join(entitiesDir, 'index.json') it('verifies char-so.json Schema 2 alias fix: walk and stand match group offsets, not frame counts', () => { expect(existsSync(charSoJsonPath)).toBe(true) const meta = JSON.parse(readFileSync(charSoJsonPath, 'utf8')) expect(meta.schema).toBe(2) expect(meta.clips).toBeDefined() expect(meta.clips.wl).toBeDefined() expect(meta.clips.nu).toBeDefined() // The bug was assigning frame count (8) instead of group offset (0 and 16) // walk must match clips.wl.group (0) expect(meta.walk).toBe(meta.clips.wl.group) expect(meta.walk).toBe(0) // stand must match clips.nu.group (16) expect(meta.stand).toBe(meta.clips.nu.group) expect(meta.stand).toBe(16) // walkOffset and standOffset expect(meta.walkOffset).toBe(meta.clips.wl.group) expect(meta.standOffset).toBe(meta.clips.nu.group) // Frame counts inside clips must be 8 expect(meta.clips.wl.frames).toBe(8) expect(meta.clips.nu.frames).toBe(8) }) it('verifies char-so 11-mode player animations and R8 atlas binary consistency', () => { const meta = JSON.parse(readFileSync(charSoJsonPath, 'utf8')) const requiredModes = ['wl', 'nu', 'rn', 'a1', 'a2', 'sc', 'gh', 'dt', 'dd', 'tn', 'tw'] for (const mode of requiredModes) { expect(meta.clips[mode], `Missing mode ${mode}`).toBeDefined() expect(meta.clips[mode].frames).toBeGreaterThan(0) expect(meta.clips[mode].group).toBeGreaterThanOrEqual(0) expect(typeof meta.clips[mode].speed).toBe('number') } // Verify groups structure expect(Array.isArray(meta.groups)).toBe(true) expect(meta.groups.length).toBe(176) // 11 modes * 16 directions // Check 6-tuple format [x, y, w, h, ax, ay] for (const group of meta.groups) { expect(Array.isArray(group)).toBe(true) for (const frame of group) { expect(frame.length).toBe(6) const [x, y, w, h, ax, ay] = frame expect(x).toBeGreaterThanOrEqual(0) expect(y).toBeGreaterThanOrEqual(0) expect(w).toBeGreaterThan(0) expect(h).toBeGreaterThan(0) expect(typeof ax).toBe('number') expect(typeof ay).toBe('number') } } // Verify R8 atlas file expect(existsSync(charSoR8Path)).toBe(true) const stat = statSync(charSoR8Path) expect(stat.size).toBe(meta.width * meta.height) expect(meta.width).toBe(4096) expect(meta.height).toBe(1929) }) it('verifies all 70 monster R8 atlases and metadata schemas', () => { expect(existsSync(indexJsonPath)).toBe(true) const index = JSON.parse(readFileSync(indexJsonPath, 'utf8')) expect(index.schema).toBe(2) expect(index.character).toBe('char-so') expect(Array.isArray(index.entities)).toBe(true) // 69 + EC (Hell Bovine, Moo Moo Farm) expect(index.entities.length).toBe(70) for (const entity of index.entities) { expect(entity.key).toBeDefined() expect(entity.token).toBeDefined() expect(entity.weapon).toBeDefined() expect(entity.file).toBe(`monster-${entity.key}.r8`) expect(entity.format).toBe('r8') expect(entity.width).toBeGreaterThan(0) expect(entity.height).toBeGreaterThan(0) const r8Path = join(entitiesDir, entity.file) expect(existsSync(r8Path), `Missing ${r8Path}`).toBe(true) const stat = statSync(r8Path) expect(stat.size).toBe(entity.width * entity.height) const jsonPath = join(entitiesDir, `monster-${entity.key}.json`) expect(existsSync(jsonPath), `Missing ${jsonPath}`).toBe(true) const monsterMeta = JSON.parse(readFileSync(jsonPath, 'utf8')) expect(monsterMeta.schema).toBe(2) expect(monsterMeta.clips.nu).toBeDefined() expect(monsterMeta.standOffset).toBe(monsterMeta.clips.nu.group) expect(monsterMeta.standFrames).toBe(monsterMeta.clips.nu.frames) } }) it('verifies Act 1..5 per-act PNG atlases have valid RFC 2083 signatures', () => { const pngSignature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]) for (let act = 1; act <= 5; act += 1) { const actEntitiesDir = join(packsDir, `act${act}`, 'entities') expect(existsSync(actEntitiesDir), `Missing act${act} entities dir`).toBe(true) const charPngPath = join(actEntitiesDir, 'char-so.png') expect(existsSync(charPngPath)).toBe(true) const charBuf = readFileSync(charPngPath) expect(charBuf.subarray(0, 8)).toEqual(pngSignature) const files = readdirSync(actEntitiesDir) const pngFiles = files.filter(f => f.endsWith('.png') && f.startsWith('monster-')) expect(pngFiles.length).toBeGreaterThan(15) for (const pngFile of pngFiles) { const fullPath = join(actEntitiesDir, pngFile) const buf = readFileSync(fullPath) expect(buf.subarray(0, 8)).toEqual(pngSignature) } } }) it('verifies atomic write cleanliness: zero orphaned .tmp files in entity output directories', () => { const checkDir = (dir: string) => { if (!existsSync(dir)) return const files = readdirSync(dir) const tmpFiles = files.filter(f => f.includes('.tmp.')) expect(tmpFiles, `Found orphaned tmp files in ${dir}: ${tmpFiles.join(', ')}`).toEqual([]) } checkDir(entitiesDir) for (let act = 1; act <= 5; act += 1) { checkDir(join(packsDir, `act${act}`, 'entities')) } }) })