Version 3.2.1: whole bank copies of voice lines, unique names, docs figures checked by tools/check_docs.py

This commit is contained in:
2026-10-10 19:30:06 +02:00
parent 1586abb8e9
commit cac52e7597
29 changed files with 919 additions and 188 deletions

View File

@@ -75,11 +75,13 @@ tables): high risk for little gain, not done.
replacements applied now", so reverting the last one restores the original bytes exactly, and an interrupted
operation is repaired by the next one. Conflicts: the whole-file SHA-1 must be the original's or the last one
ackit wrote.
- **Prefetch heads:** 396 speech lines (about 79 per language) have their first bytes copied into banks; a
replacement of such a line rewrites those heads too, otherwise the start would play the old line.
- **Prefetch heads and whole copies:** 396 voice recordings (81 lines, 78-80 recordings per language) have
their first bytes copied into banks, and 49 more are stored whole in banks (same media ID, identical bytes);
a replacement of such a recording rewrites those copies too, otherwise the game could play the old line.
They are not listed as sounds of their own.
- **Names:** no list names these media. Names come from Wwise events whose names are in the
packages' name and export tables (FNV-1 of the name = event ID), following event -> action -> containers ->
sounds (6,456 sounds); the rest are numbered per bank. Categories use the bank name. A localized speech line
sounds (13,501 of 15,355, voice lines included); the other 1,854 are numbered per bank. Categories use the bank name. A localized speech line
has the same name in every language (its line, section 5).
- **Localized speech:** speech banks hold one copy per voice language (4d); every media is labelled with the
language(s) whose banks hold it (a few recordings are shared by several languages) and the catalog shows
@@ -119,11 +121,11 @@ copy per voice language) is filtered the same way, so the sound list never mixes
*Lines*): the recordings that are sources of the same Wwise Sound objects are one line, with exactly one
recording per language (12,434 lines, all 5 languages). The catalog stores that identity (`line`), and
speaker labels, mod packages (another language: the same `line`) and subtitles follow it. Positions are
useless across languages (WEMs are stored in media-ID order; position i is another line in 75 % of the
multi-variation entries).
- A line has one name in every language: the most specific speech event that plays it (10,156 of 10,815 voice
lines), numbered `NAME#2` in the event's own order when it plays two versions; the other 659 keep the name of
their English (INT) recording's position. The position in each language stays an alias (`NAME#i`).
useless across languages (WEMs are stored in media-ID order; 81.2-81.6 % of the WEMs in multi-variation entries
are at another position than in INT).
- A line has one name in every language: the most specific speech event that plays it (10,174 of the 10,811
WAD voice lines), numbered `NAME#2` in the event's own order when it plays two versions; the other 637 keep
the name of their English (INT) recording's position. The position in each language stays an alias (`NAME#i`).
- A recording stored twice in a WAD (5 per language) is written and reverted in both places.
- The catalog records the ORIGINAL bytes: `tools/build_catalog.py` stops before writing anything if a sound
differs from the current catalog (a modified game), unless `--accept-changes` (a game update).
@@ -174,14 +176,18 @@ copy per voice language) is filtered the same way, so the sound list never mixes
## 8. Verification
- `pytest`: unit tests, a synthetic game (WADs, packs, packages with banks, localized banks, dialogue and subtitle
objects, localization files), a two-language game built like the real one (per-language BKPK tables, a media
ID shared by both languages, a recording stored twice), offscreen GUI tests, and read-only real-game tests
when the game is installed.
ID shared by both languages, a recording stored twice, one also stored whole in a bank), offscreen GUI
tests, and read-only real-game tests when the game is installed.
- `ackit verify` (WEMs rebuilt byte-for-byte, encode/decode), `ackit verify --catalog` (catalog vs game files,
and every relation re-derived from the game files with independent checks; it prints them as facts).
- Real-game write round trips without launching the game: `tools/e2e_features.py [--lang all]` (every copy of
an in-memory sound, localized line, prefetch heads, subtitles incl. RSubtitle, menu text, sound + subtitle in
an in-memory sound, localized line, prefetch heads and whole bank copies of a line, subtitles incl. RSubtitle, menu text, sound + subtitle in
one package, a mod moved to another voice language; `all` = each of the 11 languages) and
`tools/e2e_editor.py` (through the editor's code path).
- Documentation: `tools/check_docs.py [--scan] [--wems]` recomputes every figure the documents state (from the
catalog, the build's `index.json`, the menu files; with `--scan` from a fresh package scan and the catalog
check's facts; with `--wems` from rebuilding every WAD WEM) and fails on any difference, so figures are never
copied by hand.
- In the running game: `ackit verify --ingame` (music heard), `--banks` (patched packages loaded, probe data in
memory), `--texts` (menu texts and Startup subtitles found in memory). Every tool reverts in a `finally` block
and checks that every touched file is byte-identical afterwards.