Following up the incidental gap from the DEMO_* work. Resolving every VOICE_* token the way the engine does -- token, then eng\sounds.tbl for its directory, then sound.pak -- gives 4175 resolved and 268 unresolved of 4443 distinct. The gap is in the manifest, not the archive: the unresolved tokens are not listed in sounds.tbl at all, and of the 4175 that ARE listed, every one is present in the pak. Nothing is listed-then-missing. By family, script-used ids against sounds.tbl-listed ids: VOICE_A_ 696 [0..772] listed 683 missing 14 VOICE_B_ 391 [0..422] listed 383 missing 8 VOICE_C_ 429 [0..489] listed 366 missing 63 VOICE_D_ 508 [0..598] listed 387 missing 126 VOICE_E_ 44 [0..43] listed 0 missing 44 <- the whole family Two different shapes, and the distinction matters. A/B/C/D lose short runs scattered through an otherwise dense range -- 11,12,13 / 56,57 / 181,182,183 / 389-392 -- which is what cut dialogue looks like. VOICE_E_ is absent entirely: 44 ids used, none listed, no VOICE_E_* anywhere in the manifest. A whole speaker or category, cut. For the port: a missing voice bank is a RETAIL condition, not a decode bug. A reimplementation must tolerate an unresolvable VOICE_* reference, the same way it must tolerate SUBTITLE_S12B.tbl resolving in no language. Limit stated: measured on GP_MAIN_GAME_E.pak and eng\sounds.tbl only; whether the other five languages drop the same ids is untested. An earlier probe of mine checked only three sound.pak directories and would have mis-attributed this; sounds.tbl lists five, including Briefing. Resolving through the manifest rather than guessing directories is what makes the 268 trustworthy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE