ADR-0002: fxe — a committed, generated, clean-room source port of the game executable¶
Status: Accepted (2026-07-04) Serves: epic #280 (fxe), epic #281 (fx_render); charters the executable-level validation program alongside the format-validation layer.
Context¶
The two reconstruction programs are complete: the game executable (all 20 subsystems named and
documented, #209) and its overlay binaries
(#247). The
db/ symbol
database — struct maps with
offsets, function signatures, dispatch tables, a globals registry — plus the prose subsystem docs now
describe the executable's behaviour completely enough to build against.
The format side of the toolkit has a validation principle: a byte-identical codec is the proof a format is understood. The executable side had no equivalent. fxe is that equivalent — a runnable, clean-room, modern C++ source port: give it the content from the user's original disks and it plays the game, on modern rendering and audio. A port that boots real content and behaves correctly is proof-of-understanding at the executable level.
Two questions shaped the decision:
- Legal posture. An open-source re-implementation of a commercial game engine is only safe as a clean-room work — written from documentation of behaviour and non-copyrightable facts (interfaces, struct layouts, algorithms described in prose), never a transcription of the original's decompiled expression. Separately, the game's content is EA's; the port must ship none of it.
- Where the code lives. Keeping generated output out of the repo was considered as caution, but that reduces visibility, not liability — and it forfeits a browsable, buildable, CI-tested port.
Options considered¶
- Generated-only, not committed — the repo holds only the generator; fxe is ephemeral build output. Lowest visibility, but no usable artifact and no CI coverage of the port itself.
- Committed, generator is the source of truth (chosen) — a committed generator emits fxe's C++; the emitted source is committed and kept in sync by CI (the same pattern already used for the generated matrices). Usable port + documented legal posture.
- Committed, hand-written — a conventional hand-written clean-room port, no generator. Simplest to
start and unambiguously clean-room, but loses the generate-from-truth link to
db/+ docs and drifts by hand.
Decision¶
fxe is a committed, generated, clean-room modern C++ source port of the game executable, with the generator as the source of truth.
- Generated from
db/+ docs by an in-repo generator; the emitted C++ is committed and a CI currency check regenerates and diffs it (as the reconstruction/format matrices are checked). - Clean-room discipline: the generator consumes our own facts and prose only. Behaviour is expressed independently; decompiler output is never transcribed. Same boundary as the rest of the RE effort (CLAUDE.md).
- Source-port legal model: fxe ships no assets and is inert without the user's original disks (the ScummVM / OpenMW model). The NOTICE records the clean-room provenance and the require-original-content posture.
- Rendering via
fx_render(ADR forthcoming if it grows): the OpenGL + faithful-software backends are a shared MIT module, extracted from fxs, that fxe and fxs both use — one renderer, not three (the fighters-legacy engine may adopt it too). - Validation lens, independent of fa-bridge: fxe proves the reconstruction docs by running; it is not a fa-bridge dependency. fxe (MIT source port) and fa-bridge (GPL bridge into the fighters-legacy engine) are independent consumers of the same reconstruction and share no code.
- Not a 1.0 gate: fxe is a stretch program on its own milestone, interleaved with the Phase 4 validation train.
Naming: fxe fits the fx family (fx_lib / fx / fxs / fxe) — the fx-engine: the runnable
engine, generated from db/ + docs, that replays FA content the way FA.EXE did. It renders
through fx_render (software + OpenGL today, Vulkan later).
Consequences¶
- New milestone (fxe — Clean-room source port) and epics #280 (fxe) / #281 (fx_render); #279 scopes the fx_lib asset interpreters the renderer consumes.
- CI gains an fxe currency check (regenerate → diff); the build never commits assets.
- MIT→GPL reuse is one-way and clean: fa-bridge / fighters-legacy may consume
fx_libandfx_render; nothing flows back. - The repo now hosts a generated implementation of the executable (fxe), not only documentation — a deliberate extension of "the docs are the product": fxe is the docs made executable.