Skip to content

Atlas home · Diagrams · Audit · Runtime · Persistence & services

Civ13 architecture audit and UML atlas

Audit date: 2026-10-20. Source: Civ13/Civ13 master at 5bf351248de6050876fe5b53f91209a970cc5668. This is an immutable source snapshot, not a report of the deployed server or unmerged pull requests.

Executive result

Civ13 is a BYOND/DM game with a large subtype/content tree, global registries and singleton controllers, a legacy process scheduler, independent yielded/deferred activities, map-specific round policy, and custom durable persistence. Its architecture cannot be understood as one linear main loop. Native BYOND events, virtual proc overrides, hook enumeration, queued callbacks, browser Topic messages, file spools and world reloads all add entry points.

The atlas covers the entire tracked DM file inventory and the literal include closure of civ13.dme. It provides focused UML views of the important lifecycle and subsystem interactions, plus searchable source-linked declarations, inheritance candidates, call sites, control sites and unresolved/dynamic sites. It does not claim that all possible executable runtime paths have been enumerated. Loops, recursion, dynamic dispatch, mutable types/data, timing and external input make that set unbounded; a lexical scan cannot prove path feasibility or reachability.

Findings that matter

  1. Scheduler ownership needs an executable source of truth. Legacy /process scheduling coexists with included MC/timer infrastructure and independent movement/spawn loops. Comments suggesting subsystem ownership do not establish active routing. Keep lifecycle diagrams tied to actual startup and registration, not only file names. See runtime audit.
  2. Restart contracts differ. Owned transactional restart recovery and scheduled maintenance save/reboot do not have the same completion/intent contract. This is a design consistency review target, not a demonstrated data-loss defect. See persistence audit.
  3. Persistence crosses nearly every domain. A custom variable serializer, explicit runtime-field exclusions, durable graph schemas and identity restoration must evolve together. A new transient pointer/clock or cross-level relationship can invalidate save assumptions. Treat schema/ownership review as a feature gate, not an optional follow-up.
  4. Entry-point and authority boundaries are distributed. Click, native client/world callbacks, NanoUI, direct Topic handlers, admin verbs, Discord spools and Help worker exchanges have different gates. The presence of one UI or client gate does not prove that every alternate entry route is protected. No security vulnerability is asserted by this architecture audit.
  5. Derived state has distinct reconstruction phases. Lighting corners/overlays, processing registries, runtime reservations and restored-round daylight are not interchangeable with ordinary saved gameplay state. Startup and restoration should have separately testable invariants.
  6. Names and comments can overstate behavior. The preferencesSQLite directory uses delimiter-file storage on the audited path. Research comments describe optional prototype shortcuts while executable research completion requires the prototype gate. Distinguish documentation debt from proven functional bugs.
  7. Included, activated and deployed are different claims. Experimental gameplay bridge and immutable_capture sources are outside the main include closure. Human sub-tile movement is included but defaults disabled. Bot-service deployment is separately blocked by repository guidance. This audit changes none of those states.

Coverage and evidence strength

Scope Result
Tracked DM files inventoried 1,462
Tracked DM source lines 415,124
DM files in textual include closure 1,257
Source lines in that closure 383,278
Included proc declaration candidates 14,081
Included type declaration/reopening candidates 13,131
Tracked support files inventoried (selected source/map/UI/workflow extensions) 660
Python AST function/class declarations 2,036
Python parse errors 0

These are inventory counts, not compiler-certified symbol totals or a percentage of runtime behavior tested. Included types can be reopened; proc declarations can be conditionally compiled or macro-generated. Explicit parent_type overrides are recorded separately from path-default ancestry. All tracked DM files are scanned, including excluded tests and experimental sources; use in_include_union to filter production candidates.

The include closure is a conditional union: literal includes are followed without evaluating preprocessor conditions. No claim is made that every union member executes, or even that every union member is compiled in every configuration. The default map include is maps/nomads/nomads.dmm; other map content and runtime configuration can change reachability. Source path and SHA-256 are recorded per file.

Evidence levels

Read the atlas

Start with the rendered overview and core type diagram in diagrams/. Then follow runtime/report.md for scheduler, startup, movement/combat, crafting/research and AI; persistence-services/report.md for save/load/restart and external services. Source diagrams are editable PlantUML (.puml) and Mermaid (.mmd). Graphviz (.dot) is used only for explicitly labeled lexical call-candidate views.

Diagram index lists the rendered outputs and source files. SVG is zoomable; PNG is convenient for previews. The PDF atlas collects the rendered diagrams with captions.

Additional source-traced boundaries

Machine-readable inventory

  1. Adopt the inventory as a baseline, then obtain a compiler-backed, configuration-specific DM symbol/type graph. Add explicit engine entry-point roots, parent_type resolution, macro expansion and virtual dispatch sets; do not relabel lexical edges as precise calls.
  2. Make an entry-point matrix for native callbacks, verbs, Topic handlers, timers, hooks and file spools, with authority/lifetime requirements and tests per route.
  3. Document one scheduler ownership model and verify each active worker’s startup, cancellation, budget and teardown paths. Remove misleading subsystem comments only after behavior is confirmed.
  4. Review restart/save contracts together, then add cross-path tests of completed-generation selection and failure holds before consolidating code.
  5. Require explicit persistence decisions for new fields and schema changes, including restored references, transient clocks, resource ownership and derived registries.
  6. For each high-risk sequence, add bounded integration/mutation tests plus real-client checks where rendering, movement timing or dispatch depends on a connected client. Existing fixture success is not blanket server acceptance.

No broad refactor is recommended solely on this static audit. First improve contracts and evidence at the boundaries above, then use narrowly scoped changes with regression coverage.

Reproduce

Use a clean checkout of the exact pin. Run tools/build_inventory.py with the checkout and inventory output directory, then tools/summarize_inventory.py and tools/check_inventory.py. The scripts use Python standard library and do not execute repository code.

Example: python tools/build_inventory.py SOURCE_ROOT OUTPUT_ROOT/inventory

To explore a proc name: python tools/query_graph.py inventory create_lighting output.dot 45, then dot -Tsvg output.dot -o output.svg. The graph explicitly labels candidate edges and reports truncation. The default node cap is 80; changing it does not improve semantic precision.

Diagram render versions and verification results are recorded in VALIDATION.md. Read source reports for the evidence behind each manually drawn interaction. All repository source remains unmodified.

Atlas home · Diagrams · Audit · Runtime · Persistence & services