Version 3.4.0: Edit tab (edit list, large subtitle, replacements with effects and presets), Sounds tab only browses, ackit fx (pedalboard + own reverb) and replace --fx, first Linux build, catalog without a mod package

This commit is contained in:
2026-10-28 13:54:12 +01:00
parent a706dae419
commit 6de470174e
36 changed files with 2872 additions and 278 deletions

View File

@@ -1,15 +1,16 @@
# Report — full-game audio, subtitles and menu text (mission 3)
# Report — full-game audio, subtitles and menu text (mission 3), Edit tab and effects (mission 4)
Brief: `docs/history/mission3_audio_text_prompt.md`. Earlier missions: the WAD/WEM toolkit (mission 1) and the
editor Unheard City (mission 2).
Briefs: `docs/history/mission3_audio_text_prompt.md`, `docs/history/mission4_dubbing_plan.md` (plan, the effects
found in the game, the user's decisions). Earlier missions: the WAD/WEM toolkit (mission 1) and the editor Unheard
City (mission 2).
## What works (verified)
- **Every sound of the game is cataloged and editable**: the speech WADs (5 languages x 10,816), the SFX WAD (651)
and, new, the **15,355 in-memory sounds** stored inside soundbanks (archive `BANK`: footsteps, foley, combat,
weapons, UI, efforts; 8,092 shared by all languages, ~1,450 localized speech lines per voice language, 6
shared by several) in 65 loose `.bnk` files and 975 `.upk` packages. ackit reads and patches the
shared by several) in 65 loose `.bnk` files and 974 `.upk` packages. ackit reads and patches the
LZO-compressed UE3 packages itself (`ackit/upk.py`, `lzo.py`; no external tools). A replacement goes into every
copy (93,826 copies). 445 WAD voice recordings (89 lines) also have bank copies (396 prefetch heads, 49
copy (93,702 copies). 445 WAD voice recordings (89 lines) also have bank copies (396 prefetch heads, 49
whole copies; 2,185 copies), which are rewritten with them.
Names: 13,501 BANK sounds are named after the Wwise event that plays them (`Play_...`, `Speech_...`), the
other 1,854 after their bank.
@@ -34,24 +35,37 @@ editor Unheard City (mission 2).
- **Menu text**: the localization files (`BmGame\Localization\<LANG>\*.int`, ~7,000 strings per language),
edited value by value; everything else in the files stays byte-identical.
- **Editor**: one *Language* setting (default: the game's language) for voices, subtitles and menu text
(languages without voices use the INT ones, like the game); tabs *Sounds* / *Subtitles* / *Menu text*. The sound
editor shows Listen / Replace / Subtitle side by side (resizable columns, no scrolling at usual window sizes);
the subtitle list links back to the sound. Search, filters (character,
category, file, modified), room counter, apply/revert/revert all, find & replace on the filtered rows, mod
export/import with texts, changed-outside banner for sounds and texts.
(languages without voices use the INT ones, like the game); tabs *Sounds* / *Edit* / *Subtitles* / *Menu text*.
*Sounds* only browses (filters, list, a player with Play original / Play installed / Stop, Edit / Add to edit
list). *Edit* is where every kind of sound is replaced: an edit list (Previous / Next) whose sounds keep their
replacement audio, trim/level values and effects in the user data folder until applied; the subtitle shown
large with the original (and English) line; original / installed / replacement waveforms; record or load;
the effects. No scrolling at 1400 x 900 or 1280 x 800. The subtitle list links back to the sound. Search,
filters (character, category, file, modified), room counter, apply/revert/revert all, find & replace on the
filtered rows, mod export/import with texts, changed-outside banner for sounds and texts.
- **Effects** (mission 4, `ackit/fx.py`, pedalboard + numpy): the effects found in the game's sounds (metadata
survey of every bank + signal analysis of every INT speech recording + the user listening to sample groups):
pitch / formant / pitch drift, octave layers, ring modulator and comb, glitch repeats, band-pass EQ,
distortion and phone codec, noise, echo, reverb (a generated room response) with reverse swells, and the
channel layout of 2-5 channel sounds (WAVE mask order; the PA lines' dry centre and delayed surrounds).
Presets per effect and whole presets (Radio, Phone, PA announcement, Mr. Freeze, ...); set by hand in the
Edit tab, or `ackit replace --fx` on the command line. Effects the game adds while it plays (the McDSP
FutzBox radio sound of many thug and street lines, room reverbs) are not in the files and must not be added
again.
- **Safety**: every changed file (WAD, bank, package, localization file) is rebuilt from a verified original copy
in the store + the edits applied now; reverting the last edit restores it byte-for-byte; files changed by
another tool or Steam are detected (whole-file SHA-1) and not overwritten without confirmation (also when
installing a mod in the editor). The original copy is taken only from a file that matches the catalog
(another tool's or another originals store's change is a conflict; checked on all 1,447 files with sounds or
(another tool's or another originals store's change is a conflict; checked on all 1,446 files with sounds or
subtitles: no false alarm), and the editor does not switch stores while changes are applied. Writes are
serialized, so a sound and its subtitle applied at the same time both reach the package. **Revert all**
(editor and `ackit revert --all`) reverts sounds and texts; `ackit restore-backup` is the last resort for a
damaged store.
- **Tests**: 148 automated tests (unit, synthetic game with packages/banks/dialogues/localization, a
- **Tests**: 177 automated tests (unit, synthetic game with packages/banks/dialogues/localization, a
two-language game for the lines (incl. a recording also stored whole in a bank), the shipped catalog's cross-references, real-game read-only (every
name of every language's catalog resolves to its own sound), offscreen GUI incl. list order, selection and
loading overlays) pass. `ackit verify` PASS (incl.
name of every language's catalog resolves to its own sound), offscreen GUI incl. list order, selection,
loading overlays and the Edit tab (edit list, saved replacements, effects panel, no scrolling), every effect
measured back on synthetic signals) pass. `ackit verify` PASS (incl.
300/300 in-memory WEMs rebuilt byte-identically).
- **Real game** (2026-10-10), all reverting and checking byte-identity themselves:
`tools/e2e_features.py --lang all` 89/89 PASS in all 11 languages (every copy of an in-memory sound, each
@@ -60,15 +74,19 @@ editor Unheard City (mission 2).
position); `ackit verify --ingame` PASS (music heard, ncc 1.0);
`--banks` PASS (77 in-memory sounds of the front-end packages replaced in 54 files: the game loads them, 71
probes found in its memory, no crash); `--texts` PASS (12/12 menu texts and 23/23 subtitles of Startup.upk
found in the game's memory, no crash); `tools/e2e_editor.py` PASS. Game files original at the end
(`ackit status`). The catalog builder refuses to run on a modified game, so the catalog always describes the
found in the game's memory, no crash); `tools/e2e_editor.py` PASS. 2026-10-27 (Linux, the game's Flatpak
install): `tools/e2e_features.py --lang INT` 10/10 PASS, incl. a 5-channel line replaced with effects (EQ,
echo, PA layout), decoded back from the game file (dry centre, surround echo 0.160 s later) and reverted
byte-identically. Game files original at the end (`ackit status`). The catalog builder refuses to run on a modified game, so the catalog always describes the
original files.
- **Package**: `dist/UnheardCity-3.3.0-windows-amd64.zip` (86 MB, catalogs included; built 2026-10-13). With `PATH` reduced to
the Windows folders the packaged exe passes its smoke test (in the game's language - Italian on the test PC:
21,015 sounds loaded, encode + inject, 9,377 subtitles and 7,020 menu texts loaded, an in-memory sound decoded from a package) and the GUI starts and
quits cleanly. The installer is unchanged since mission 2 (install/upgrade/uninstall verified then); the
uninstaller now also counts text edits before offering to delete the user data (2026-10-13; that count was
tested, the full uninstall cycle was not run again).
tested, the full uninstall cycle was not run again). Version 3.4.0: the Linux package
(`dist/UnheardCity-3.4.0-linux-x86_64.tar.gz`, built 2026-10-27, the first Linux build) passes the same smoke
test (incl. the effects) with `PATH=/usr/bin:/bin`, and the GUI starts.
## Unresolved / limitations
- **Checked by a person in game** (2026-10-10), not automatically (nothing of this plays or shows on the title
@@ -94,14 +112,16 @@ editor Unheard City (mission 2).
`<Bank>_<n>`.
- 25 SFX originals (music seek tables and sample counts, looping ambience) are not reproduced byte-for-byte by
the WEM rules (`docs/formats/wem.md`); writing is not affected (replaced music plays in game).
- Two copies of media `1C898731` differ; its checksum is left empty. Channel order for 4-6 channel sounds is
unverified. M4A/AAC/WMA input needs an ffmpeg on the system.
- Two copies of media `1C898731` differ; its checksum is left empty. Channel order of 3-6 channel sounds:
the WEMs carry WAVE channel masks and ackit keeps that order (mission 4). M4A/AAC/WMA input needs an ffmpeg
on the system.
- **Effects are approximations** set by ear; the presets are starting points. The Edit tab does not mark the
lines the game itself adds an effect to (known from the bank survey, not in the catalog).
- Another game build is scanned at first start (WADs: seconds; banks, lines and subtitles: a few minutes,
cached); it gets the same line identities, but no original checksums.
## Next steps
1. Optional: lift the subtitle length limit by relocating dialogue objects (checked in game by a person).
2. Build and smoke-test the Linux package once on a Linux machine.
3. Listen to the 19 lines whose speaker label differs from the game's dialogue speaker field
2. Listen to the 19 lines whose speaker label differs from the game's dialogue speaker field
(`docs/categories.md`) and fix the curated lists if needed; extend them (`data/catalog/source/<lang>/*.txt`)
and rebuild the catalog.