Version 3.1.0: voice lines linked across all languages from the game data
This commit is contained in:
@@ -7,10 +7,12 @@ Survey of the installed game (buildid 3718300), 2026-10-09.
|
||||
|
||||
## Inventory
|
||||
|
||||
| where | banks | unique in-memory WEMs | in the catalog |
|
||||
|-------|-------|-----------------------|----------------|
|
||||
| loose `SFX\*.bnk` (Batman/Catwoman footsteps, 32 surfaces each, + `TST_Prep_Media`) | 65 | 1,117 | 0 |
|
||||
| banks embedded in `.upk` packages (in 1,432 of the 2,650 packages) | 3,340 | 15,641 (~276 MB) | 0 |
|
||||
| where | banks | unique in-memory WEMs |
|
||||
|-------|-------|-----------------------|
|
||||
| loose `SFX\*.bnk` (Batman/Catwoman footsteps, 32 surfaces each, + `TST_Prep_Media`) | 65 | 1,117 |
|
||||
| banks embedded in `.upk` packages (in 1,432 of the 2,650 packages) | 3,340 | 15,641 (~276 MB) |
|
||||
|
||||
All of them are in the catalog (archive `BANK`).
|
||||
|
||||
The two sets share 119 media IDs: 15,800 unique media IDs in 96,011 places (bank copies). 396 of them are
|
||||
**prefetch heads** of streamed WAD sounds (below), so there are **15,404 in-memory sounds**. All copies of a
|
||||
@@ -52,11 +54,37 @@ WAD sounds have such heads (2,101 copies); replacing one of them must rewrite th
|
||||
|
||||
## Localized banks
|
||||
Speech banks are localized inside the (language-neutral) packages: one `AkBank` export starts with a language
|
||||
list (FStrings `INT FRA ITA DEU ESN`) and then holds one complete bank per language, in that order, all with
|
||||
the same bank ID; each language's copy has its own media IDs (checked on 215 banks against the WAD languages
|
||||
of their streamed lines). ackit labels every in-memory media with its language (`BANK.csv` column `language`):
|
||||
8,098 language-neutral sounds, ~1,460 per voice language. A catalog shows the neutral sounds plus the loaded
|
||||
language's lines; names are unique per language.
|
||||
list (FStrings `INT FRA ITA DEU ESN`) and then holds one block per language, in that order: the BKPK table(s)
|
||||
of the speech WAD entry for that language (`wad.md`) and a complete bank, with the same bank ID in every
|
||||
language. ackit gives each bank and each BKPK table the language of its position in that list (an export
|
||||
whose block count differs from its language count would be reported; none does). Each in-memory media gets
|
||||
the languages of the banks that hold it (`BANK.csv` column `language`): 8,098 sounds are language-neutral,
|
||||
~1,460 belong to one voice language, 6 to several (a DLC intro line shared by INT/FRA/ITA/ESN while DEU has
|
||||
its own); a media stored in the banks of every language is listed as `''` (the same recording everywhere).
|
||||
A catalog shows the neutral sounds plus the loaded language's lines; names are unique per language.
|
||||
|
||||
## Lines: one recording per language
|
||||
Implemented in `ackit/lines.py`, checked by `ackit verify --catalog`. A voice line exists once per language,
|
||||
and the game ties the recordings together itself:
|
||||
- Every WEM of a speech WAD has exactly one row in its own language's BKPK table (media ID, offset, size):
|
||||
10,816 of 10,816 in each of the 5 languages, no row without a WEM. 657 media IDs are used by several
|
||||
languages (cinematics, emotes, Clayface), each at another position in each language's WAD, so the tables
|
||||
are kept per language and never merged.
|
||||
- Every recording, streamed, prefetched or in memory, is the source of a Wwise Sound object; Sound objects,
|
||||
events, actions and containers have the same IDs in every language, only the media differ. A *line* = the
|
||||
recordings that are sources of the same Sound objects: 12,434 lines (WAD and in-memory), each with exactly
|
||||
one recording in each of the 5 voice languages (61,510 recordings), no Sound object with two recordings in
|
||||
one language. Line identity (`line` column) = the smallest Sound object ID.
|
||||
- Prefetched sources count too: the 396 lines with a prefetch head (mostly the game-over taunts) are linked
|
||||
only through them.
|
||||
- 5 recordings per language are stored twice in that language's WAD (same media ID in two entries, byte-
|
||||
identical, e.g. `Speech_STEEL_A1_CH2_Thug_behinddoormuffled` and `DIA_SteelA1Muffled`): the second place
|
||||
is a copy of the line (same `line`, keeps its position name) and is written and reverted with it, because
|
||||
the game plays whichever place the loaded package's table names.
|
||||
- Independent checks (no BKPK involved): every WAD recording is named as a source by a Sound object of a bank
|
||||
of its own language (54,055 of 54,055); every stored prefetch head equals the start of the recording its
|
||||
line gives it (2,101 of 2,101); a line's recordings have similar lengths across languages (11,761 of 12,434
|
||||
within a factor 1.5; the others are different edits, e.g. a 0.55 s ESN line vs 5.46 s elsewhere).
|
||||
|
||||
## Banks inside packages
|
||||
- The packages are LZO-compressed UE3 packages (`upk.md`); ackit decompresses them itself and searches the
|
||||
|
||||
Reference in New Issue
Block a user