| domain | meta | ||||
|---|---|---|---|---|---|
| tags |
|
||||
| sources |
|
||||
| related |
|
||||
| updated | 2026-08-17 |
This file defines how the KB goes from "where things live" to "how things run": the granularity layers, the procedure for cutting the codebase into isolated domains, and the representation formats for flows and function digests. Read this before adding depth (flows / digests) to the KB.
The KB is built in four layers, shallow→deep. A reader descends only as far as the task needs.
- L0 — Glossary (
GLOSSARY.md): vocabulary/concepts. Answers "what does this term mean". - L1 — Domain map (
engine/*,modlayer/*): module responsibilities and where code lives. Answers "which file/dir owns X". - L2 — Flows & lifecycles (
flows/*): ordered cross-cutting sequences (boot, frame, save, callback dispatch, config load…). Answers "what happens, in what order, and where each step lives". - L3 — Function digests (inside flow/domain files): per-key-function condensed "what it does". Answers "what does this function actually do, what does it touch, what calls it".
L3 is selective: only spine / hot-path / repo-specific / non-obvious functions get a digest. Documenting every function in a 2686-file module is neither feasible nor useful; document the ones a future task will need to understand or modify.
A domain is well-isolated if you can state its inputs, outputs, owned state, and lifecycle using only its seams — without needing another domain's internals. Procedure:
- Seed from entry points & ownership. Find the process/subsystem entry (engine:
WinMain→ device; Lua:CScriptEngineload→on_game_start) and the state each subsystem owns. Ownership of state is the strongest domain boundary. - Cut along lifecycle phases. Most subsystems split into init / per-frame update / shutdown, and several have orthogonal axes: online vs offline (ALife), load vs save, main thread vs worker (MT build). Each phase is often its own flow.
- Treat extension seams as contracts. The Lua callback bus, DLTX/DXML hooks, and config params are the engine↔mod-layer interface. Document the seam from both sides (who fires / who handles).
- Apply the base+override rule (Lua). The analyzable Lua universe is two corpora: the
read-only base game (
unpacked/scripts/, ~455 files incl._g.script,xr_logic.script,db.script,bind_*) and this repo's overrides + additions (gamedata/scripts/, ~66 files, mostly same-named overrides). Document the canonical mechanism once (citingunpacked/), then the modded delta (citinggamedata/). Never editunpacked/— it is reference only. - Isolation test. If describing domain A keeps dragging in domain B's internals, the cut is wrong — find the real seam (an interface, an exported function, a callback, a config key) and put the boundary there.
- Engine (
src/): fully self-contained C++; flows traceable end-to-end by reading the code. - Mod layer (
gamedata/): depends on the base corpus inunpacked/. A mod-layer flow usually must read base scripts (for the mechanism) + repo overrides (for the behavior). Cite both.
Each flow file documents one sequence. Sections:
- Trigger / entry — what starts it (engine event, frame tick, user action, save).
- Sequence — numbered steps. Each step: the responsible
file:function(or module) + a one-line "what it does". Show branches/loops inline. - State touched — what is read/written/owned across the flow.
- Threading — main thread / worker / both (note MT-build differences).
- Extension points — callbacks fired, config keys read, hooks exposed to mods.
- Failure & edge cases — known crashes, ordering hazards, fatals.
- Deeper — pointers; Maintenance — how to re-verify.
One compact entry per function (inside the relevant flow/domain file):
file:function(args) → ret— Does: one/two lines. Reads/Writes: state/globals. Calls: key callees. Called by / fires: callers or callbacks. Gotcha: invariant or hazard (optional).
Keep it behavioral ("what it does"), not a code transcription. No pasted code (see CONVENTIONS.md).
Documenting every function in a large module is infeasible. For each domain, digest only the
lifecycle spine — the functions on the critical path: constructor / net_Spawn (or equivalent
init), the per-frame update entry/entries, each state-transition function, and teardown
(net_Destroy). A leaf/helper gets a digest only if non-obvious or repo-specific. This bounds
"read the whole module" down to the ~6–12 functions that define how the domain behaves. Everything
else stays an L1 pointer until a task needs it.
Every domain/flow file ends its body with an explicit seam list — the contract that makes the domain analyzable in isolation and is what future tasks actually need:
- Callbacks fired (exact engine/Lua callback names).
- Config keys read (LTX/
pSettings/spawn_ini). - Scheduler interaction (RT vs deferred; how it registers).
- ALife / server seam (CSE_* link, online/offline).
- Lua exposure (wrapper class, binder, exported surface).
- Other domains touched.
flows/object-lifecycle.md is the worked template for both rules.
When a read-only sub-agent gathers the raw trace (to save context on a large module), its claims are
a draft, not verified. Spot-verify the spine entries against code yourself before marking a file
verified; mark anything you did not personally re-read (agent-traced — not personally re-read),
distinct from (INFERRED) (which means no one read the code). See flows/object-lifecycle.md.
The detailed coverage plan — full flow inventory (F1–F20), phasing, per-flow execution recipe, and resume-after-compaction protocol — lives in
ROADMAP.md. This list is the short status mirror; keep both in sync.
High value = repo-specific, crash-prone, or frequently touched. Status as of updated — statuses
re-checked against the tree on 2026-08-17 (all ten are now documented; ROADMAP.md remains the detailed
plan, and INDEX.md's "Branch sync" section records what was reconciled after a code sync).
- Lua boot + callback lifecycle — ✅ done →
flows/lua-callback-lifecycle.md(flagship/template). - Config load: LTX parse + DLTX merge — ✅ done →
flows/dltx-config-load.md. - DXML XML interception — ✅ done →
flows/dxml-xml-interception.md. - Engine boot → device init → main/frame loop — ✅ done →
flows/engine-boot-frame.md. - Render frame (R4/DX11): cull → g-buffer → lighting → post → present — ✅ done →
flows/render-frame.md(+ theflows/renderer-*.mdfamily). - Save / load lifecycle — ✅ done →
flows/save-load.md. - ALife online↔offline transition — ✅ done →
flows/alife-online-offline.md. - Weapon fire → hit → callback chain — ✅ done →
flows/weapon-fire-callbacks.md. - Options framework lifecycle — ✅ done →
flows/options-runtime.md. - Object lifecycle (spawn/update/destroy) + scheduler split — ✅ done →
flows/object-lifecycle.md(the xrGame backbone; per-domain flows attach to its spine).
When you complete a flow, flip its status here and add the file to INDEX.md.
- Keep the backlog honest: mark done only when the flow file reaches L2 with L3 digests for its spine functions and is verified against the code this session.
- If a new analysis axis appears (e.g. Vulkan path, networking model change), add it to "cut along lifecycle phases".