← 1.20 ReplayEntropic Dev

REPLAY 1.20 · RESEARCH NOTES

The asset brain

A linked map of loading, rendering, and collision evidence.

34 notes · Latest source update
SOURCE NOTE · Updated 2026-09-28 13:27:08 UTC
On this page

GfxWorld and Brush Models

Asset brain · Engine Integration · Lighting, Light Grids, and Shadows · Transient Zones

Status

GfxWorld loader family and brush-model array have targeted source/Replay correspondences. Whole GfxWorld serialization and renderer ABI remain unresolved.

Game-Test source evidence

The PDB-backed Load_GfxBrushModelArray candidate begins at RVA 0x60A510, reported size 20. A fixed multiply by 96 precedes the stream load and tail handling. The brush array is reached through independent paired parent routes from Load_GfxWorld and Load_AddonMapEnts.

Replay 1.20 evidence

Replay Load_GfxBrushModelArray candidate is RVA 0xDD1750, size 20. The report finds matching body behavior and two independent parent routes. The observed 96-byte stride is specific to the analyzed Replay/source code path; it is not sufficient by itself to assert a serialized struct ABI.

Other GfxWorld evidence includes Load_GfxWorldLightmapReindexData at Replay RVA 0xD96CC0, paired through Load_GfxWorldDraw, and q-prefixed transient-zone helpers documented in Lighting, Light Grids, and Shadows and Transient Zones.

GfxWorld light-AABB child loader

Replay ID 18172 at RVA 0xD92480 is now named Load_GfxLightAABB. Its former imported label, bdReportUserEventsRequest::bdReportUserEventsRequest, is superseded: it conflicted with the GfxWorld child call route and the loader body. The unique Game-Test PDB/Atlas anchor is Load_GfxLightAABB ID 7214 at RVA 0x4ACF10, source extent 192 bytes; Replay's .pdata and SQLite extent is 185 bytes. Replay size and prototype remain unchanged: __int64 __fastcall sub_140D92480(__int64 a1).

The source and Replay loader bodies share the operation order for a 24-byte root, conditionally aligned node-array load with a 28-byte per-node stream operation, and a second optional ushort array. In the observed bodies, pointer/count accesses occur at offsets such as +8 and +0x10; these are observations within their respective builds only. They do not establish equivalent field offsets, a shared structure, or serialized ABI.

The parent route is independently paired: each Load_GfxWorld calls its Load_GfxLightAABB child after Load_GfxShadowGeometry and immediately before Load_GfxWorldDpvsStatic; Replay then proceeds to the dynamic DPVS loader. Source extent/prototype, Replay extent/prototype, and runtime interpretation remain distinct. The array child routines remain Replay-local observations; this mapping does not name them.

Evidence: coordinator cross-reference and applied result.

GfxVoxelTree array loader — q-name with preserved export-size discrepancy

Replay ID 18181 at RVA 0xD92C20 is now q_Load_GfxVoxelTreeArray; its existing prototype remains __int64 __fastcall sub_140D92C20(__int64 a1, __int64 a2). The source array wrapper is exact PDB ID 7302 Load_GfxVoxelTreeArray (RVA 0x4B1010, 79 bytes, signature void __cdecl Load_GfxVoxelTreeArray(DBStreamStart, unsigned __int64)), but source Load_GfxWorld expresses the counted array inline and calls scalar Load_GfxVoxelTree ID 7301. Replay extracts the array-and-element parser into ID 18181. The paired parent places it between matching Load_GfxDynamicLightset and Load_GfxMayhemSelfVis children. This supports a source-family role, while the q-prefix marks the build-specific function-granularity difference.

IDA ownership reconciled the former boundary hold: ID 18181 owns one 599-byte chained PDATA/function range ([0xD92C20,0xD92E77)), although the SQLite size remains 70. Preserve that size and prototype. Source arrays use 120-byte elements while the Replay path uses 112; neither stride or source structure offsets transfer to the other build. The earlier hold is superseded only on boundary ownership; array-role identity and size discrepancy remain separately qualified.

The old imported Load_GfxVoxelTree label belonged to Replay ID 10689 (size 368, prototype __int64 __fastcall sub_1405425E0(_QWORD *a1)), not the array parser. The reviewed batch corrected ID 10689 to the address-derived placeholder sub_1405425E0 as a misleading-name cleanup, without assigning it a source identity; its saved i64 label was reported as still stale and is not claimed updated here. See the resolved-boundary/q-name assessment, applied render-asset batch, and superseded boundary hold.

XSurface loader relation

Load_XModelSurfs has a repeated q_Load_XSurface Replay child (ID 20339; exact source PDB family Load_XSurface). This is an XModel surface route, not a direct GfxWorld root child established by these reports. The Replay name remains q-prefixed because direct-caller census evidence conflicts; see XModels and Surfaces for the parent loop, boundaries, and limits.

GfxWorld asset Mark leaf

Replay ID 24825 is Mark_GfxWorldAsset at RVA 0xF62580, with its 16-byte size and prototype __int64 __fastcall sub_140F62580(__int64 a1, unsigned int a2) preserved. Its exact Game-Test helper is Atlas/PDB ID 36751 at RVA 0xC10D70, 16 bytes, signature Mark_GfxWorldAsset(struct GfxWorld *, int). The paired pointer method is source PDB ID 8245 Mark_GfxWorldPtr, RVA 0x522300, 127-byte extent, and Replay ID 18268 Mark_GfxWorldPtr, RVA 0xD9DAB0, 127-byte extent, with preserved Replay prototype __int64 sub_140D9DAB0(). Both parents call the asset helper, then a nested GfxWorld-root method, then the asset helper again; the mark-phase values passed to the helper are 0 then 1. The target helper calls are at 0xD9DACF, 0xD9DAFA, and 0xD9DB16. This exact helper/root/helper sequence supports the pointer-wrapper name independently of the outer dispatcher case.

The nested root is now named Mark_GfxWorld: source PDB ID 8223 at RVA 0x521510, extent 688 bytes, maps under this parent route to Replay ID 18266 at RVA 0xD9D5A0. Replay SQLite size remains 688 and prototype remains __int64 sub_140D9D5A0(); its complete PDATA extent is 691 bytes ([0xD9D5A0,0xD9D853)), three bytes longer than the stored size. The parent/root and ordered 12-call child routes support the name, but several nested child identities are still unresolved: source Mark_GfxWorldSurfaces/StaticModels/Draw correspond to Replay size-only children (122/193/515 bytes); source Mark_MdaoVolumeArray and Mark_StreamTree correspond to Replay size-only children (120/401 bytes); two source Mark_StreamTreeGrid calls correspond to Replay size-285 children. Do not infer those child names or layouts from order alone.

The former Replay child label Mark_AttLaser on ID 18265 was corrected to Mark_GfxPrecomputedSkyIllumination (RVA 0xD9D500, size/complete PDATA 150, prototype _BOOL8 sub_140D9D500()). Exact source PDB ID 8189 is at RVA 0x520FA0, 150 bytes. The full normalized 37-instruction body matches; four Replay calls to Mark_GfxImagePtr distinguish it from source Mark_AttLaser, which calls Mark_LaserDefPtr. The correction resolves the previous nested-child conflict but does not name the remaining size-only child rows.

The helper loads source dispatch immediate 0x1B and Replay 0x1F before tail-jumping to their respective DB_MarkXAsset workers. These are build-local values and do not establish a cross-build type-index mapping, ABI, structure layout, or runtime behavior. See the source/Replay reassessment and applied-name manifest.

The pointer method's source/Replay reassessment and applied manifest are here and here. Root and child adjudication with applied manifest: report and manifest.

Integration and safe use

GfxWorld is a renderer-facing map root. Loader order, pointer fixups, child image/material references, brush model arrays, and transient subworld data should be traced separately. Confirm each Replay target boundary and each stream count/stride before implementing a serializer.

Open questions

  • Reconstruct the full GfxWorld root child order and stream phases.
  • Determine whether the 96-byte brush stride is backed by Replay field accesses and on-disk serialization.
  • Join source UDT members to Replay accesses without treating header offsets as target ABI.

Evidence

  • Brush-model array cross-reference
  • GfxWorld lightmap reindex data
  • Source/Replay GfxWorld member lead index and holds

DPVS static and dynamic data

The Game-Test Load_GfxWorldDpvsDynamic body at RVA 0x4B2330 and Replay body at 0xD93BB0 have normalized body equality in the crosswalk. Load_GfxWorldDpvsStatic has a separate matched loader route. The coordinator recorded 21 paired source-member/Replay-access observations in SQLite. In the source PDB, GfxWorldDpvsDynamic is 560 bytes and GfxWorldDpvsStatic is 632 bytes; these are source type sizes only.

Selected paired load observations:

  • Dynamic: dynEntClientWordCount starts at +0x00 (unsigned int[2]); dynEntCellBits at +0x10 (unsigned int *[2]); and dynEntVisData at +0x20 (unsigned int *[33][2]). Replay accesses corresponding offsets. The Replay schema type for dynEntVisData is recorded as unsigned __int8 *[2][33], a type/shape discrepancy that remains unresolved despite equal offsets.
  • Static: counts occupy source offsets +0x00 through +0x14 for smodel, surface, primary-light, reflection-probe, volumetric, and decal visibility counts. Pointer arrays begin at +0x18 (smodelVisData, 33 pointers) and +0x120 (surfaceVisData, 33 pointers). Later pointer fields include primary-light +0x228, reflection-probe +0x230, volumetric +0x238, decal +0x240, sorted surface indices +0x248, sorted SModel indices +0x258, and sun-shadow fields from +0x260 through +0x270. Most paired types match the source PDB; sortedSmodelIndices is source unsigned int * versus Replay schema unsigned __int16 *.

These offsets are source PDB member starts paired with observed Replay accesses and schema records; equal offsets are evidence for review, not a declaration of Replay ABI or serialized layout. See the access crosswalk and SQLite observation manifest.

DPVS Postload child parsers

Postload_GfxWorld is paired source RVA 0x538ED0 to Replay ID 18328 q_Postload_GfxWorld at 0xDA2C80. It calls static then dynamic DPVS parsers in both builds. The static parser is Replay ID 18331 at 0xDA5020, now named q_Postload_GfxWorldDpvsStatic (stored size 5701); the dynamic parser is ID 18329 at 0xDA3B10, now named q_Postload_GfxWorldDpvsDynamic (stored size 5111). Coordinator readback confirms both names, unchanged sizes/prototypes, and quick_check=ok.

The source parent accesses the static/dynamic current objects at +0x3BE8/+0x3E60; Replay accesses them at +0x3F98/+0x4210. Those displacements differ by build and are not transferable field offsets. Replay static/dynamic child parsers use distinct current-object globals and first conditional stream advances (0x278 static, 0x230 dynamic), supporting the identity distinction. Source exact PDB extents are 5735 static and 5145 dynamic; Replay rows and .pdata extents are 5701 and 5111. Keep q prefixes because Replay Array/Stream wrapper routes and full IDA chunk ownership remain unresolved.

See the DPVS Postload report, proposal rows, and apply/readback manifest.

DPVS planes Postload child

The paired Postload_GfxWorld roots call the planes parser before the separate static/dynamic parsers. Replay ID 18330 at RVA 0xDA4F10 is applied as q_Postload_GfxWorldDpvsPlanes; stored size 264 and prototype were preserved, and SQLite quick_check passed. The source PDB parser is at RVA 0x53C030 with 310-byte extent. Both parent instructions install the current object from their GfxWorld root plus 0x90 immediately before calling the parser; equality is one paired access observation, not a portable member or layout claim.

Replay parser observations: conditional stream advance 0x28; pointer-like fields at child offsets +8, +0x18, +0x20; 16-bit count inputs at +4 and +0x10; the latter path reaches existing q_Postload_ushortArray ID 19083, while the final count at +0 drives a count << 9 advance. These are Replay disassembly facts, not asserted C type declarations. Source PDB extent is 310 bytes; Replay .pdata and SQLite size are 264 bytes. Keep q_ because Replay Array/Stream wrapper routes and IDA chunk ownership remain unresolved.

See the planes Postload report and apply/readback manifest.

GfxWorld draw-surface array helpers

Source Load_GfxWorldSurfaces at PDB RVA 0x8E2630 is paired with Replay ID 20399 at RVA 0xE305D0. In this parent, the source allocator route reaches exact PDB AllocLoad_GfxDrawSurf (RVA 0x49BFB0, 33 bytes) and then exact PDB Load_GfxDrawSurfArray (RVA 0x4A8280, 19 bytes). Replay calls ID 18147/RVA 0xD90400, now q_AllocLoad_GfxDrawSurf (stored size 26), followed by ID 18163/RVA 0xD90D10, now q_Load_GfxDrawSurfArray (stored size 19). Both target names, sizes, and prototypes were read back after the name-only applications.

q_AllocLoad_GfxDrawSurf aligns by 7 and returns the current stream cursor; Replay omits the source bounds-check call and its extent is 26 bytes versus source 33. q_Load_GfxDrawSurfArray has the same normalized 19-byte wrapper body as many generated loaders: it scales the count by 16, sets the stream length, and tail-jumps to Load_Stream. That body appears in 129 source functions and four Replay functions, so paired parent callsite plus adjacent allocator order is necessary evidence. Keep both labels q-prefixed and preserve target metadata. These are GfxWorld draw-surface stream helpers; do not conflate them with XModelSurfs mesh geometry or use the count scaling as a complete element-layout declaration.

Evidence: allocator report, allocator apply readback, array wrapper report, and array apply readback.

GfxWorld index-buffer stream wrapper and following resource operation

Replay ID 18924 at RVA 0xDD1770 is now Load_GfxIndexBuffer; its 18-byte SQLite size, prototype, and mangled name were preserved. It maps to the unique source PDB/Atlas ID 12210 Load_GfxIndexBuffer at RVA 0x60A870 (18 bytes). The wrapper's three-instruction body loads the current index-buffer field through a build-local global, sets the byte count, and tail-jumps to that build's Load_Stream. Source passes 8; Replay passes 0x20 (32), an actual stream-byte-count difference. This function-name correspondence does not assert that the source and Replay GfxIndexBuffer layouts or ABIs match.

Three paired parent routes call the wrapper: Load_StDiskTerrainSurface, Load_StMesh, and Load_GfxWorldDrawVerts. In each, a separate low-level index-buffer resource operation follows the stream wrapper: source calls exact PDB ID 87441 Load_IndexBuffer (RVA 0x220C5C0, 394 bytes), while Replay calls target ID 50660 at RVA 0x18D9F10 (91 bytes). The stream wrapper is not itself that resource loader. In GfxWorld, the q_Load_GfxWorldDrawVerts path connects this operation to draw-vertex parsing; the other two parents are terrain/static-mesh paths.

Source global varGfxIndexBuffer and Replay qword_145D41FF0 are build-local references; no equivalent global type or layout is inferred. Source Array/Stream callers are indexed, but corresponding Replay wrapper coverage is incomplete; do not claim one-to-one Array/Stream mapping. Adjacent generated wrappers and the source Load_IndexBuffer operation are explicit alternatives, resolved here by the distinct paired parent call routes and call ordering.

Evidence: initial cross-reference, stream-size/caller follow-up, coordinator apply manifest, and applied-row CSV.

GfxWorld static-model Postload child

Replay ID 20354 at RVA 0xE2BE20 is applied as q_Postload_GfxWorldStaticModels (SQLite/.pdata size 3673; prototype preserved). The source PDB parser is at RVA 0x8BDEA0, size 4897. Both paired Postload_GfxWorld roots call this child between the surfaces parser and GfxWorldDraw; source installs the current object from GfxWorld+0x170, while Replay uses GfxWorld+0x150 and current-object global qword_145D45028. Keep the two displacements separate; this paired access does not establish matching world layouts.

Replay observations include an entry advance of 0x4F8, a pointer-like field at [object+0x38], a count at [object+0] driving a count*4 advance, and calls to Postload_XModelPtr, vector/byte array loaders, wrapped-buffer helpers, and material-handle allocation. These are target instructions and child-call evidence, not transferred member definitions. Exact source root placement and Replay child/body boundary support the q name; Replay Array/Stream wrappers are still unresolved.

See the static-model Postload report and apply/readback manifest.

Shared byte-array loader under spatial and static-model paths

Replay ID 18989 at RVA 0xDD3A40 is now Load_uint8_tArray (15-byte SQLite row/prototype preserved), paired to exact source PDB/Atlas ID 12867 at RVA 0x636DA0 (15 bytes). Both are three-instruction tail helpers that forward the count and stream phase to their own Load_Stream implementation. Two independent parent pairs disambiguate it from the same-shaped Load_byteArray: source/Replay Load_SpatialPartition_Tree calls this helper with the count loaded from its own current-object +0x10 at parent offsets +0x70/+0x6D; source/Replay Load_GfxWorldStaticModels calls it with the same observed local count setup at +0x2CA/+0x28C. These offsets are instruction/callsite observations per build, not transferred field definitions.

In the paired Load_GfxWorldStaticModels parent, Load_byteArray is a separate later child call, with a different source/Replay callsite and its own stream global. The shared generated tail-call pattern is therefore not enough to identify the helper; its distinct SpatialPartition_Tree caller route plus paired parent callsites distinguish Load_uint8_tArray. Source Atlas xrefs include two additional wrapper parents not indexed as Replay direct callers, so caller absence there is unresolved rather than contradictory.

Source uses a global at RVA 0x08DB2440; Replay uses a different global at 0x05D415E8. Both are build-local stream/current-object state and must not be treated as the same address or ABI field. The observed +0x10 count source remains build-specific. The mapping names a byte-array stream helper only; it does not assign semantic meaning to the count field, infer element ownership, or establish an asset layout.

Evidence: source/Replay helper and parent-call report, applied SQLite manifest, and applied-row audit CSV.