Files
BT411/reference/decomp/GAP_CENSUS.md
T
Joe DiPrimaandClaude Fable 5 f44be87ab2 #60 PART 2: the RE-EXPORT -- dark code 90KB -> 41KB, coverage 87.3% -> 93.5%
Installed JDK 21 + Ghidra 12.1.2 (no admin, %LOCALAPPDATA%\bt411-tools beside
DXSDK/cmake; runner uses 8.3 SHORT paths because Ghidra's .bat expands
%JAVA_HOME% unquoted and the profile has a space).

New tooling: reference/ghidra_scripts/ExportGaps.java -- ExportAll's exact
output contract PLUS a gap-fill pass (force disassembly + createFunction at
E8 call targets outside functions, data->code pointers at a plausible
prologue, and the census's discovered starts; iterated to a fixpoint,
logged to gapfill_report.tsv).  tools/ghidra_reexport.sh (headless runner,
'reprocess' mode) and tools/gapdiff.py (score two censused exports);
gapcensus.py now censuses any export dir.

Results: 6267 -> 6472 functions (+205 created in 2 rounds: 195 census
starts, 6 call targets, 4 data pointers; 56.1KB newly covered), ZERO
decompile failures.  Dark real code 90.4 -> 40.8 KB (54.8% recovered);
game-side dark 53.1 -> 21.1 KB; regions 428 -> 321.  EVERY historically
dark function now has pseudocode -- including @0x4c05c4 VehicleDead, the
absence that opened this issue.

VALIDATION: the new pseudocode confirms this week's hand reconstruction of
the crouch field-for-field (mapPosture/duckState/squatCapable/myomerEff/
novice gate/SetLegAnimation/ForceUpdate/stability alarm) -- and exposed one
branch the raw pass missed: AIRBORNE AUTO-RISE (mode 3|4 && legState 1 ->
forced squ), now implemented in mech4.cpp and re-benched un-regressed.

PROMOTION: the re-export is canonical reference/decomp/; the previous export
is preserved at reference/decomp/archive_2025export/ so old
`part_0NN.c:LINE` citations still resolve (addresses are stable across both;
line/shard membership is NOT -- cite @ADDR).

New lead recorded: @0x4c0904 is the MASTER BTPlayer Performance (team
resolution, EndMission console post, score heartbeat) -- our @0x4c083c
PlayerSimulation attribution needs a re-check.  KB: source-completeness,
gotcha #20 (the rule is cheap now -- look it up), CLAUDE.md router/layout.
Log: phases/phase-04-gap-census.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 11:11:26 -05:00

5.1 KiB

GAP CENSUS -- the export dark-region inventory (#60)

Generated by tools/gapcensus.py (deterministic; re-run after any re-export). Machine-readable twin: gap_census.tsv.

Headline

Metric Value
Code section (.text) 0x401000-0x4e0000 (892 KB)
Indexed functions (functions_index.tsv) 6472, covering 833 KB (93.5%)
RAW DARK (no indexed function at all) 321 regions >= 16B, 49 KB (5.5%) -- 40 KB REAL CODE after padding
Exported pseudocode functions (part_*.c) 6472
Indexed but NOT exported (Ghidra knew it; no pseudocode) 0 functions, 0 KB
Function starts discovered inside dark regions 135 (call-graph + data-pointer evidence)

Reading the tables: visited = the address is already cited somewhere in game/ context/ docs/ (a prior dig reached it); everything else is UNCHARTED. tu = nearest file-tagged export neighbors (before|after when they disagree).

Dark code by suspected TU family

Family Regions Real code bytes
munga/ (engine core -- source in repo) 117 14544
BOUNDARY/mixed 53 10346
bt/ (GAME -- reconstruction target) 60 5848
munga_l4/ (engine L4 -- source in repo) 34 5563
bt_l4/ (GAME video/glue -- reconstruction target) 57 5492

Top 40 dark regions by REAL CODE bytes (padding excluded)

# Range Code bytes Fn starts Call-ins Visited Suspected TU
1 0x4596ab-0x459eb8 1795 0 0 1: 4599ae munga_l4/l4vidrnd.cpp
2 0x480a2a-0x48116d 1521 0 0 - munga_l4/l4splr.cpp
3 0x40c82a-0x40cdb4 1322 0 0 - munga/scalar.cpp
4 0x40b68c-0x40bbe8 1293 0 0 - munga/scalar.cpp
5 0x481f77-0x48255c 1267 0 0 - munga_l4/l4splr.cpp
6 0x486467-0x486a0e 1252 0 0 - munga_l4/l4splr.cpp
7 0x47ae1b-0x47b2ec 1060 0 0 - munga_l4/l4ctrl.cpp
8 0x405b1e-0x405f44 972 0 0 - munga/filestrm.hpp
9 0x427fd0-0x4283b8 931 0 0 - munga/network.cpp
10 0x4d41ae-0x4d45b0 765 0 0 - bt_l4/btl4app.cpp
11 0x4af691-0x4af9cf 707 0 0 - bt/heat.cpp
12 0x4829ab-0x482c9f 687 0 0 - munga_l4/l4splr.cpp
13 0x487a38-0x487ca0 615 0 0 - munga_l4/l4splr.cpp
14 0x483b9b-0x483df0 520 0 0 - munga_l4/l4splr.cpp
15 0x4d95b6-0x4d9800 487 0 0 - bt_l4/btl4app.cpp
16 0x423202-0x423414 460 0 0 - munga/network.cpp
17 0x45472a-0x454924 451 0 0 - munga_l4/l4vidrnd.cpp
18 0x4b8837-0x4b8a48 448 2 0 1: 4b8837 bt/powersub.cpp
19 0x474671-0x474855 421 0 0 - munga_l4/l4gauge.cpp
20 0x4d2813-0x4d29fc 414 1 0 - bt_l4/btl4vid.cpp
21 0x4816b2-0x48186d 404 0 0 - munga_l4/l4splr.cpp
22 0x42f80b-0x42f9bc 394 0 0 - munga/player.cpp
23 0x443cf5-0x443e94 380 0 0 - munga/watcher.hpp
24 0x4b2c11-0x4b2d8c 324 0 0 11: 4b2c2d 4b2c75 4b2d00 4b2d23... bt/powersub.cpp
25 0x4d993f-0x4d9c38 321 12 0 - bt_l4/btl4app.cpp
26 0x4deec5-0x4df048 321 0 0 - bt_l4/btl4app.cpp
27 0x4c651c-0x4c668d 318 0 0 - bt_l4/btl4gaug.cpp
28 0x409c41-0x409d9c 312 0 0 - munga/scalar.cpp
29 0x484ed6-0x485020 307 0 0 - munga_l4/l4splr.cpp
30 0x43223f-0x4323a8 306 0 0 - munga/explode.cpp
31 0x40f6a7-0x40f7d8 283 0 0 - munga/boxsolid.cpp
32 0x4b1a84-0x4b1bb1 251 0 0 - bt/powersub.cpp
33 0x481565-0x481675 247 0 0 - munga_l4/l4splr.cpp
34 0x45888e-0x4589a0 241 0 0 - munga_l4/l4vidrnd.cpp
35 0x4d2016-0x4d2150 241 0 0 - bt_l4/btl4vid.cpp
36 0x466ac2-0x466bc4 235 0 0 - munga_l4/l4audwtr.cpp
37 0x4310c3-0x4311dc 234 2 0 - munga/explode.cpp
38 0x466702-0x466804 234 0 0 - munga_l4/l4audwtr.cpp
39 0x484076-0x48416d 229 0 0 - munga_l4/l4splr.cpp
40 0x480899-0x4809ba 222 0 0 - munga_l4/l4splr.cpp

Indexed-but-unexported functions (first 60 by address)

These have index rows (address + size) but no pseudocode in all/part_*.c -- decompile them individually (raw disasm or a targeted re-export) when a dig arrives.

Addr Size Index name Cited in repo