Repository navigation
Parity
The goal is that everything the original game ships makes its way into SiegeFX and behaves the way it did. This page is the measurement. One command, siegefx parity ledger <install>, reads the original's data and the compiled engine and counts, for each kind of authored content, how much of it some engine path can act on. tools/receipts.sh runs it before every push and fails when a section handles fewer items than the committed baseline (goldens/parity-ledger.baseline.txt).
2026-10-06, the GOG data, SiegeFX 0.4.0+bc91b30:
| Section | Authored | Handled | Gap | By use | An item counts as handled when… |
|---|---|---|---|---|---|
| commands | 43 | 40 | 3 | 99.9% | the command catalog the engine's dispatcher and NIS indexer consult lists it |
| trigger-verbs | 24 | 23 | 1 | 99.8% | the engine names the verb (triggers dispatch by name) |
| quests | 31 | 30 | 1 | 96.9% | the engine's quest catalog defines it (journal text and objective) |
| skrit-components | 152 | 95 | 57 | 84.9% | the engine names the script (a native replacement or the VM) |
| ai-jobs | 118 | 3 | 115* | 2.5% | the engine names the job script |
| template-sections | 170 | 114 | 56 | 98.4% | the engine names the section |
| template-fields | 934 | 397 | 537 | 81.9% | the engine names the field |
| mood-fields | 26 | 21 | 5 | 88.6% | the engine names the field |
| ui-interfaces | 125 | 13 | 112* | 11.0% | the engine names the interface |
| effect-keys | 136 | 136 | 0 | 100.0% | the effect engine reports the key consumed (live probe) |
| sounds | 676 | 674 | 2* | 99.7% | a field the engine reads names the sound, or the engine names it itself |
| animation-skrit-api | 31 | 17 | 14 | 73.2% | the engine names the extern (bridge member or literal) |
Authored counts the distinct items the data has; by use weighs each by how often the data uses it, so a field set on five thousand templates counts for more than one set once.
Handled is a ceiling, not a promise. It means some engine path can act on the item by name. Whether it then behaves as the original does is checked against the original itself, running beside SiegeFX under Proton (tools/ds1/).
* The native AI reimplements behaviours without naming the original job scripts, and most screens are native panels drawn with the original art that never name their interface file, so a job or screen they cover still counts as a gap until it is mapped. Sounds that no data names are left out (unused by the original, or played by its own code).
- Commands — the engine dispatches scripted commands through one catalog, and the ledger reads that same catalog, so the audit cannot disagree with the dispatcher.
- Named rows (trigger verbs, skrit components, AI jobs, template sections and fields, mood fields, UI interfaces, the animation-script API) — the ledger reads every literal and member name compiled into the engine; an item is handled when the engine's code names it.
- Quests — the engine's quest catalog.
- Sounds — through the engine's own sound-database loaders: a sound is handled when a field the engine reads names it, or the engine names it.
- Effect keys — a live probe: every authored effect script runs through the engine's effect VM, which reports the keys it consumed.
Every check was built with a planted fault it must catch.
-
Commands (3):
cmd_ai_c_drop,cmd_ai_c_equip,cmd_ai_c_stop— one use each, in the opening region. -
Trigger verbs (1):
start_camera_fx— 21 uses, all in elite-difficulty container templates. -
Quests (1):
quest_fort_kroth2, granted by a legionnaire's conversation. - Sounds (2): two button-press sounds named only in interface fields the engine does not read.
-
Mood fields (5): the music repeat and intro delays; the authored day length (
timeofday.realminutesperworldhour— the world clock runs the authored 1.6 minutes per hour as a constant); two frustum fields used only by a stress-test map. -
Template fields: the most-used unread ones are
category_name,pcontent.modifier_min/max(the random magic modifiers on generated loot),aspect.priority,aspect.lodfi_upper/lower,mind.personal_space_range,common.membership,inventory.min_pileandtrapped.fire_event.
Every gap, with an example of where the data uses it: siegefx parity ledger "<install>" --out=DIR writes one list per section.
-
Effect traces: every spell's cast effect run through the effect VM with a fixed seed. The 248 traces generated on Windows come out byte for byte on Linux; the gate compares all of them (
goldens/sfx-timelines) before every push. - Movement: the chase-sim audit (1,122 pathfinder-verified walks) gives the same 49 failures on Linux as its last recorded Windows run.
siegefx parity ledger "<your Dungeon Siege folder>" --out=parity
tools/receipts.sh # the whole gate; --update-baseline records a deliberate change