Version 3.1.0: voice lines linked across all languages from the game data

This commit is contained in:
2026-10-10 14:10:03 +02:00
parent ea3e44000a
commit fbde809370
56 changed files with 74728 additions and 73360 deletions

View File

@@ -6,7 +6,8 @@ the UE3 packages (`upk.md`), holding the subtitle text of all 11 languages. acki
## Inventory (buildid 3718300)
- 14,743 dialogue objects in the packages for 9,016 speech lines (a line's object is copied into every package
that uses it; all copies are identical).
that uses it; all copies are identical), plus 41 scripted subtitles (below): ~9,400 subtitle strings and
168,688 stored copies.
- 11 languages: INT, FRA, ITA, DEU, ESN, ESM, POL, POR, RUS, JPN, KOR (the speech WADs exist only for INT, FRA,
ITA, DEU, ESN; the other languages play the INT voices with their own subtitles).
- ~9,400 subtitle strings per language: 94 % of the subtitles have one line, the rest up to 5 lines.
@@ -29,21 +30,25 @@ or property name from the name table, i32 byte size, i32 array index, then `size
| field | content |
|-------|---------|
| `0x10` @ `0x2C` | the speech event this line plays, e.g. export `Speech_CHURCH_B1_Ch2_POST_Explosion_BM_Cash_04` |
| `0x0D` @ `0x34` | speaker, e.g. `Batman` |
| `0x0D` @ `0x34` | speaker, e.g. `Batman` (`ackit verify --catalog` compares it with the curated speaker labels) |
| `0x09 LocalizedSubtitles` | u32 count, then per language: `0D 00 00 00` FString language code, `09 00 0C 00 Subtitles` struct, `00 00` |
| `Subtitles` | u32 line count, then per line: `0D 00 00 00` FString text, `04 00 0C 00` 4-byte value, `00 00` |
The sizes add up exactly in all 14,743 objects (checked by the parser: `SubtitleError` otherwise).
## Link to the speech sound
The speech event name is hashed (FNV-1) to the Wwise event ID, followed through the soundbanks (event ->
action -> containers -> Sound) to the streamed media, and that media ID is looked up in the per-language
BKPK tables (`banks.md`) to find the WAD entry and variation of each language. This is exact; the `_NN`
suffix of the event name does **not** match the variation order inside the WAD entry (WEMs are stored in
media-ID order). Lines kept in memory link to the localized BANK sound of their language. Linked: ~99 % of
the strings (e.g. INT 9,265 / 9,379); the rest have no event that reaches a sound (unused or placeholder
lines such as `..._TEMP_29`) and stay editable without a sound link.
Event names with a number (`Speech_X_04`) exist only as export names, not in the name table.
The speech event name is hashed (FNV-1) to the Wwise event ID and followed through the soundbanks (event ->
action -> containers -> Sound objects, the same in every language) to that language's recording of the line
(`banks.md`, *Lines*): a WAD variation or a localized in-memory sound. This is exact; the `_NN` suffix of the
event name does **not** match the variation order inside the WAD entry (WEMs are stored in media-ID order).
The names come from the packages' name and export tables (numbered names like `Speech_X_04` exist only as
export names) and from the subtitle objects themselves: some events are listed in no name table, but their
dialogue / RSubtitle object names them (Vicki Vale's radio reports, the Hush tape reveal).
An event that plays two versions of a line (105 subtitled events, e.g. Mr. Freeze's lines) links its subtitle
to both (`sound` = `key1;key2`). Linked: 103,304 of 103,658 strings in the 11 languages (INT 9,373 / 9,404),
each to the same line in every language. The rest (29 speech names, ~32 strings per language: Riddler trophy
texts, Arkham City Stories, radio reports and tapes the game does not ship audio events for) have no event in
any bank and stay editable without a sound link.
## How ackit writes them
- In place, into **every copy** (`data/catalog/SUB_locations.csv.gz`): the new text replaces the FString's