diff --git a/src/game/monster-mapping.ts b/src/game/monster-mapping.ts index 236f66d..54b5a6c 100644 --- a/src/game/monster-mapping.ts +++ b/src/game/monster-mapping.ts @@ -738,7 +738,7 @@ export const MONSTER_ART_MAP: Record = { * used by the offline entity baker to pre-pack all level monsters per act. */ export const ACT_MONSTER_SPECS: Record = { - 1: [{ token: "FA", weapon: "hth" }, { token: "ZM", weapon: "hth" }, { token: "SI", weapon: "hth" }, { token: "YE", weapon: "hth" }, { token: "SK", weapon: "hth" }, { token: "CW", weapon: "hth" }, { token: "CR", weapon: "1hs" }, { token: "FS", weapon: "hth" }, { token: "CR", weapon: "2ht" }, { token: "SK", weapon: "1hs" }, { token: "BN", weapon: "hth" }, { token: "GM", weapon: "2hs" }, { token: "CR", weapon: "bow" }, { token: "SK", weapon: "bow" }, { token: "BH", weapon: "hth" }, { token: "WR", weapon: "hth" }, { token: "FE", weapon: "1hs" }, { token: "SP", weapon: "hth" }, { token: "VA", weapon: "hth" }], + 1: [{ token: "FA", weapon: "hth" }, { token: "ZM", weapon: "hth" }, { token: "SI", weapon: "hth" }, { token: "YE", weapon: "hth" }, { token: "SK", weapon: "hth" }, { token: "CW", weapon: "hth" }, { token: "CR", weapon: "1hs" }, { token: "FS", weapon: "hth" }, { token: "CR", weapon: "2ht" }, { token: "SK", weapon: "1hs" }, { token: "BN", weapon: "hth" }, { token: "GM", weapon: "2hs" }, { token: "CR", weapon: "bow" }, { token: "SK", weapon: "bow" }, { token: "BH", weapon: "hth" }, { token: "WR", weapon: "hth" }, { token: "FE", weapon: "1hs" }, { token: "SP", weapon: "hth" }, { token: "VA", weapon: "hth" }, { token: "EC", weapon: "hth" }], 2: [{ token: "FA", weapon: "hth" }, { token: "ZM", weapon: "hth" }, { token: "SI", weapon: "hth" }, { token: "YE", weapon: "hth" }, { token: "SK", weapon: "hth" }, { token: "CW", weapon: "hth" }, { token: "SL", weapon: "hth" }, { token: "PW", weapon: "hth" }, { token: "SC", weapon: "hth" }, { token: "VD", weapon: "hth" }, { token: "PW", weapon: "1ht" }, { token: "BN", weapon: "hth" }, { token: "SM", weapon: "hth" }, { token: "SW", weapon: "hth" }, { token: "SR", weapon: "hth" }, { token: "SD", weapon: "hth" }, { token: "MM", weapon: "hth" }, { token: "GY", weapon: "hth" }, { token: "SK", weapon: "1hs" }, { token: "SK", weapon: "bow" }, { token: "BB", weapon: "hth" }, { token: "PN", weapon: "hth" }, { token: "BT", weapon: "hth" }, { token: "WR", weapon: "hth" }, { token: "VA", weapon: "hth" }, { token: "GM", weapon: "2hs" }], 3: [{ token: "FA", weapon: "hth" }, { token: "ZM", weapon: "hth" }, { token: "SI", weapon: "hth" }, { token: "YE", weapon: "hth" }, { token: "SK", weapon: "hth" }, { token: "CW", weapon: "hth" }, { token: "BB", weapon: "hth" }, { token: "MO", weapon: "hth" }, { token: "TH", weapon: "hth" }, { token: "FE", weapon: "1hs" }, { token: "FC", weapon: "hth" }, { token: "BK", weapon: "hth" }, { token: "FD", weapon: "hth" }, { token: "FW", weapon: "hth" }, { token: "WW", weapon: "hth" }, { token: "VD", weapon: "hth" }, { token: "SL", weapon: "hth" }, { token: "ZZ", weapon: "hth" }, { token: "SW", weapon: "hth" }, { token: "ZP", weapon: "hth" }, { token: "SR", weapon: "hth" }, { token: "VA", weapon: "hth" }, { token: "SP", weapon: "hth" }, { token: "BT", weapon: "hth" }, { token: "SM", weapon: "hth" }, { token: "MM", weapon: "hth" }, { token: "FK", weapon: "1hs" }, { token: "WR", weapon: "hth" }, { token: "GY", weapon: "hth" }, { token: "CR", weapon: "1hs" }, { token: "SD", weapon: "hth" }, { token: "SC", weapon: "hth" }, { token: "CR", weapon: "bow" }, { token: "PN", weapon: "hth" }], 4: [{ token: "FA", weapon: "hth" }, { token: "ZM", weapon: "hth" }, { token: "SI", weapon: "hth" }, { token: "YE", weapon: "hth" }, { token: "SK", weapon: "hth" }, { token: "CW", weapon: "hth" }, { token: "SL", weapon: "hth" }, { token: "VM", weapon: "hth" }, { token: "FR", weapon: "hth" }, { token: "CS", weapon: "hth" }, { token: "UM", weapon: "fgt" }, { token: "DM", weapon: "hth" }, { token: "WW", weapon: "hth" }, { token: "BH", weapon: "hth" }, { token: "BT", weapon: "hth" }, { token: "UM", weapon: "hth" }, { token: "SM", weapon: "hth" }, { token: "PN", weapon: "hth" }, { token: "UM", weapon: "mgk" }], diff --git a/tests/challenger-m3-entity-concurrency.test.ts b/tests/challenger-m3-entity-concurrency.test.ts index d981878..85d8294 100644 --- a/tests/challenger-m3-entity-concurrency.test.ts +++ b/tests/challenger-m3-entity-concurrency.test.ts @@ -86,14 +86,15 @@ describe('Challenger M3_2: Entity Asset Packing Concurrency & Schema Parity', () expect(meta.height).toBe(1929) }) - it('verifies all 69 monster R8 atlases and metadata schemas', () => { + 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) - expect(index.entities.length).toBe(69) + // 69 + EC (Hell Bovine, Moo Moo Farm) + expect(index.entities.length).toBe(70) for (const entity of index.entities) { expect(entity.key).toBeDefined() diff --git a/tests/challenger-m4-determinism-parity.test.ts b/tests/challenger-m4-determinism-parity.test.ts index 4ba90a8..102184a 100644 --- a/tests/challenger-m4-determinism-parity.test.ts +++ b/tests/challenger-m4-determinism-parity.test.ts @@ -38,14 +38,16 @@ describe('Challenger M4_2: Asset Baking Pipeline Determinism & 365-Scene Parity' expect(existsSync(ENTITIES_INDEX_PATH)).toBe(true) const baselineHash = sha256File(ENTITIES_INDEX_PATH) - // Expected canonical SHA-256 for Schema 2 69-monster entity index (including vk-hth Valkyrie) - expect(baselineHash).toBe('51da3628b0cb049f5f5bb1282a101cbe0c793f52ed5d91e45077cd91e93a4074') + // Expected canonical SHA-256 for Schema 2 70-monster entity index (including vk-hth Valkyrie + // and ec-hth Hell Bovine: MonStats.txt hellbovine Code=EC, level 39 Moo Moo Farm). Adding + // ec-hth is the only change against the previous 69-monster index (51da3628…). + expect(baselineHash).toBe('675757cffde277b24e2aec11b7440243654282cbb743424ef02ce1d253b41c66') const baselineContent = readFileSync(ENTITIES_INDEX_PATH, 'utf8') const parsed = JSON.parse(baselineContent) expect(parsed.schema).toBe(2) expect(parsed.character).toBe('char-so') - expect(parsed.entities).toHaveLength(69) + expect(parsed.entities).toHaveLength(70) // Compare against /tmp/stress-entity-run1 and /tmp/stress-entity-run2 if present const testDirs = ['/tmp/stress-entity-run1', '/tmp/stress-entity-run2'] diff --git a/tests/packed-entity-art.test.ts b/tests/packed-entity-art.test.ts index e423c79..918d214 100644 --- a/tests/packed-entity-art.test.ts +++ b/tests/packed-entity-art.test.ts @@ -104,14 +104,14 @@ describe('offline pre-baked entity atlases & full Act 1..5 pack index (Issues #3 const charR8 = readFileSync(charR8Path) expect(charR8.byteLength).toBe(charMeta.width * charMeta.height) - // Check all 65 unique monster specs exist as global .r8 files + // Check all 66 unique monster specs exist as global .r8 files (EC = Hell Bovine, Moo Moo Farm) const uniqueSpecs = new Set() for (let act = 1; act <= 5; act += 1) { for (const spec of ACT_MONSTER_SPECS[act] ?? []) { uniqueSpecs.add(`${spec.token.toLowerCase()}-${spec.weapon.toLowerCase()}`) } } - expect(uniqueSpecs.size).toBe(65) + expect(uniqueSpecs.size).toBe(66) for (const key of uniqueSpecs) { const slug = `monster-${key}`