VerifiedBuild 2026.06.26.1097863.1, CU2

HaloSimulation_tag_release.dll

Native Blam simulation module loaded by the UE5 BlamEngine plugin. This page records the factory ABI and interface shape recovered from the CU2 build.

Artifact fingerprint

Size
14,670,608 bytes
SHA-256
8EE1A37F6F0BC89241F47946546EDCA798962F81E2D06B386196BC75DE991705
Image base
0x180000000

Update 2026-10-21: the project now targets CU4, build 2026.08.11.1121610.2 (config/hce-build.lock.json). Its HaloSimulation_tag_release.dll is 14,668,560 bytes with SHA-256 C8C144404ADF61A9DE821C996682A7E66ABADD7E530397D3BBDE31C123203BF7. The fingerprint above, the RVAs, and the host hash on this page are CU2's and were not re-recorded for CU4.

Shell factory

bool CreateBlamEngineShell(void* context, void** outShell)
  • Export RVA: 0x6980.
  • Allocates 0x5A0 bytes aligned to 0x20 bytes.
  • Installs interface tables at object offsets 0x0 and 0x140.
  • Initializes three lock-free lists and a 32-entry reusable event pool.
  • Replaces the process-global shell, frees the previous allocation, writes outShell, and returns 1.

Primary interface

The table at RVA 0x7B1560 has nine entries. Names below describe observed behavior; they are not recovered source symbols.

SlotRVAObserved behavior
00x7230Releases the global shell allocation and clears shell state.
10x7280Performs one-time initialization and normalizes a caller-supplied path.
20x7360Large startup path: initializes tag systems and can create a worker thread.
30x89F0Clears queues, frees worker state, waits for the worker, and closes its handle.
40x6940Returns the embedded interface at this + 0x140.
50x8B00Builds an auxiliary result/container; semantic role is not yet identified.
60x9A00Allocates and returns an auxiliary callback object.
70x9A70Releases four callback/object references.
80x6130Control Flow Guard placeholder in the recovered table.

Embedded output interface

Slot 4 returns this + 0x140, whose table is at RVA 0x7B1610. It also has nine entries. One method drains and dispatches shell events, four methods enqueue typed payloads through the lock-free pool, and three small thunks release payload objects.

UE5 loader path

The matching host is CU2 build 2026.06.26.1097863.1. Its SHA-256 is 0670FAA751E2553940B90DF6BE43D3B0FF59EA87F22155CF3C3FE9D439367F1D.

  1. A launcher method constructs the wide module basename HaloSimulation.
  2. The engine module loader stores its handle at launcher offset 0x1A0.
  3. The export resolver looks up CreateBlamEngineShell.
  4. The factory writes the shell pointer at launcher offset 0x1C8.
  5. UE5 immediately invokes primary interface slot 1.

The host does not contain a contiguous tag_release filename. That suffix is selected below this recovered launcher layer.

Current limits

Slot names remain behavioral labels, not source symbols. Runtime invocation has not yet established which startup structures select CTF or another game variant. The next useful step is to trace host call sites for primary slots 2 and 3, then correlate their inputs with the reflected BlamGameEngineBaseVariant and BlamGameEngineCampaignVariant objects.

Update 2026-10-21: answered on CU4. The engine a map load starts is one constant in the simulation's load-map handler (RVA 0xf650): mov r8d, 3 at 0xf6db, where 3 is campaign and 2 is Megalo. MJOLNIRLevelLoader's native half patches it so converted multiplayer maps start the Megalo engine, and the game type comes from the Megalo variant file it installs (native/map_registry, shipped in mods-v0.7.0, PR #106; the Slayer and CTF variant files themselves ship since mods-v0.9.0). mjolnir live engine reads the running engine and patches the same constant.

Reproduce

analyzeHeadless <project-dir> HaloSimulation \
  -import HaloSimulation_tag_release.dll \
  -scriptPath tools/ghidra \
  -postScript AnalyzeBlamShell.java <output-dir>

The reusable probe is checked in at tools/ghidra/AnalyzeBlamShell.java.