# Architecture & Master Plan OpenRA3 is a from-scratch, portable re-implementation of **Command & Conquer: Red Alert 3** (SAGE 2.0) in **pure C++26** — C++ modules, `import std;`, no scripting language, no managed runtime, no other programming language anywhere in the tree. It is built with Clang + libc++ on Linux and cross-compiled to Windows with llvm-mingw. This document is two things at once: 1. the **layer architecture** (how the modules sit on top of one another), and 2. the **master plan** — the complete Red Alert 3 feature set decomposed three levels deep into **Module → Function → Feature**, each tagged with its implementation status and target milestone. The decomposition is the contract: every feature RA3 has is either implemented, being implemented, or explicitly planned here. Nothing is silently dropped. > **Scope.** Offline only. Single-player campaign, skirmish, Commander's > Challenge and LAN lockstep — never an online service, matchmaking, EA account > or GameSpy/Steam integration. The simulation is deterministic and > self-contained. No game assets or binaries are shipped; the engine reads the > user's own install at runtime. --- ## 1. Principles Same five rules as the rest of the tree, restated because the plan is written against them: 1. **Pure C++.** One language. No Lua, no JS, no C#, no Python at runtime. Python is allowed *only* in offline build tooling (`tools/`, cmake helper scripts), never linked into `openra3`. 2. **No raw owning pointers.** Ownership is `std::unique_ptr`; cross-references are non-owning views (`thing *`, handles, indices). 3. **Portable simulation.** No platform API in the foundation or simulation layers. All platform concerns live behind `display` / `audio` / `video`. 4. **Determinism.** Anything that can diverge between runs (RNG, iteration order, float accumulation, hash order) is explicit, seeded and testable. 5. **RE-traceable.** Every structure or constant taken from the retail `ra3_1.12.game` (image base `0x400000`) or from the GPLv3 SAGE 1.0 reference cites its origin. No asserted fact without a source. --- ## 2. Layer architecture Each layer may import the ones below it, never the ones above. The `ra3` umbrella module re-exports the SDK; applications import `ra3` only. ``` L6 tooling / apps openra3 (CLI) tools/ (offline, Python allowed) | import ra3 --------------------------------------------------------------------------- v L5 meta ra3.i18n ra3.mod ra3.net (deferred) | L4 match services ra3.match ra3.replay ra3.save | L3 presentation ra3.client ── ra3.render ── ra3.audio ── ra3.video | \ | | \ v | ra3.display (backend pick) | / | \ \ v ra3.ui ra3.vulkan ra3.dx ra3.webgl | (SDL3) (Vulkan) (D3D11/12) (WebGL2) --------------------------------------------------------------------------- v L2 simulation ra3.logic ra3.modules ra3.combat ra3.movement ra3.economy ra3.ai ra3.script ra3.powers ra3.shroud | L1 data & assets ra3.data ── ra3.assets ── ra3.map ── ra3.terrain | | v v ra3.fs (BIG4 / RefPack / install) | L0 foundation ra3.core (types, math, containers, RNG, message bus) ``` The current concrete modules (`ra3.core`, `ra3.logic`, `ra3.data`, `ra3.skirmish`, `ra3.fs`, `ra3.map`, `ra3.terrain`, `ra3.render`, `ra3.ui.*`, `ra3.vulkan.*`, `ra3.dx.*`, `ra3.webgl.*`, `ra3.display`, `ra3.game`, `ra3.client`, and the vendored `ender.log`) are the **seeds** of the target modules below. `ra3.skirmish` and `ra3.game` will be absorbed into `ra3.ai` / `ra3.match`; new modules are added as their subsystems are recovered. ### Status legend | Tag | Meaning | | --- | --- | | `[x]` | implemented and tested on `main` | | `[~]` | partially implemented / works for the happy path | | `[ ]` | planned, not started | | `(vX.Y)` | target milestone (see the roll-up in §5) | | `!!` | needs reverse engineering before it can be built | | Function tag | Meaning | | --- | --- | | `D` | **done** — the function's features are largely present | | `P` | **partial** — some features present | --- ## 3. Master plan — Module → Function → Feature ### M00 `ra3.core` — foundation vocabulary `[D]` Mirrors SAGE `GameEngine/Common`. Everything else speaks this. - **F1 Types & math** `[D]` - `[x]` `real` (float), `int32`/`uint32`/`uint16`/`uint8`, `bool` aliases - `[x]` `coord2d` / `coord3d` vectors, dot/cross/length/normalize - `[x]` `rgb_color` / `argb_color`, packing and lerp - `[x]` geometry: `segment`, `triangle`, `plane`, ray/segment intersection - `[ ]` fixed-point helpers for replay-stable accumulation `(v0.4)` - `[ ]` matrix / quaternion (needed by W3D models) `(v0.6)` - `[ ]` `KindOf` flag bitset (SAGE object taxonomy) `(v0.4)` - **F2 Containers** `[D]` - `[x]` `ascii_string` + `make_name_key` (case-folded hash for data lookup) - `[x]` intrusive doubly linked list (message stream node layout) - `[x]` deterministic iteration-order map (insertion-ordered) - `[ ]` object pool / arena for per-frame allocations `(v0.4)` - `[ ]` interned string table `(v0.5)` - **F3 Deterministic RNG** `[D]` - `[x]` seedable `random` stream (`game_logic` random) - `[ ]` independent per-player / per-subsystem streams `(v0.4)` - `[ ]` shuffle / weighted-pick primitives `(v0.4)` - **F4 Message stream** `[D]` - `[x]` command bus with retail node layout (`appendMessage` `0x0060c4a0`) - `[x]` ordered per-frame command drain - `[ ]` command argument blocks (build/target/waypoint payloads) `(v0.4)` - `[ ]` network/replay source tagging `(v0.4)` - **F5 Diagnostics** `[~]` - `[x]` logging sink + assert macro - `[ ]` scoped profiling timers, per-subsystem counters `(v0.4)` - `[ ]` structured crash/report capture `(v0.8)` - **F6 Serialization primitives** `[~]` - `[x]` little-endian byte reader/writer - `[ ]` chunked binary reader/writer with versioning `(v0.5)` - `[ ]` stable content hashing (replay/desync checks) `(v0.4)` - **F7 Localization primitives** `[~]` (see M26) - `[x]` UTF-16 unit access, CSF low-byte `^0xFF` decode - `[ ]` placeholder substitution, plural/gender rules `(v0.5)` ### M01 `ra3.fs` — containers & install `[D]` - **F1 BIG archive** `[D]` - `[x]` `BIG4` header parse (`fileSize` LE, `fileCount`/offsets BE) + name index - `[x]` payload read on demand (index-only resident memory) - `[ ]` `BIGF` (RefPack whole-archive) variant `!!` `(v0.5)` - `[ ]` write support (pack/repack, used by tooling) `(v0.8)` - **F2 RefPack codec** `[D]` - `[x]` decode: 2/3/4-byte commands, long-literal, stop opcode - `[x]` `refpack_output_size` without full decompress - `[ ]` encode (for tooling round-trips) `(v0.8)` - **F3 Install locator** `[D]` - `[x]` `--game-dir` / `$RA3_GAME_DIR` / `C:\Red Alert 3` defaults - `[ ]` registry / Steam / EA-app discovery `(v0.5)` - `[ ]` Uprising as an optional content source `(v0.5)` - **F4 Virtual file system** `[~]` - `[x]` layered archive mounts (loose files → `*.big`) - `[ ]` patch/language precedence rules (newest `Lang-*.big` wins) `(v0.5)` - `[ ]` case-insensitive lookup + path normalisation `(v0.5)` - **F5 Extraction targets** `[D]` - `[x]` `openra3 extract` dumps maps/terrain to `assets/` - `[ ]` full asset dump via `ra3tools` integration as a build target `(v0.5)` ### M02 `ra3.data` — data schema & balance `[P]` - **F1 Data schema** `[ ]` `!!` - `[ ]` SAGE INI parser (`#include`, `#define`, inheritance) `(v0.5)` - `[ ]` XML rule schema - `[ ]` `.manifest` compiled-blob schema `!!` `(v0.5)` - **F2 Compiled asset blobs** `[ ]` `!!` - `[ ]` `global.bin` deserialisation `(v0.5)` - `[ ]` `static.*.bin` deserialisation `(v0.5)` - `[ ]` version/dependency validation `(v0.5)` - **F3 Balance tables** `[~]` - `[x]` damage types, `ArmorTemplate` percentages - `[x]` weapon target masks, weapon definitions - `[x]` unit/structure build costs, times, prerequisites - `[x]` ore economy constants - `[ ]` read these from the install instead of pinned constants `(v0.5)` - **F4 Object definitions** `[ ]` - `[ ]` `ThingTemplate`/`ObjectTemplate` inheritance graph `(v0.5)` - `[ ]` module descriptor lists (per-object update/draw module sets) - `[ ]` `WeaponTemplate`/`ArmorTemplate`/`LocomotorTemplate` stores - **F5 Faction & player templates** `[~]` - `[x]` Allied / Soviet / Empire side flags (`2/4/8`), match templates - `[ ]` commander/sub-commander definitions `(v0.7)` - `[ ]` build/upgrade unlock trees per faction `(v0.5)` - **F6 Rules & settings** `[ ]` - `[ ]` skirmish options (cash, crates, superweapons, speed, limits) - `[ ]` bonus crate effect table - `[ ]` AI personality tables - `[ ]` map-specific rule overrides (`map.ini`) - **F7 Validation** `[ ]` - `[ ]` schema diagnostics with source location - `[ ]` cross-reference integrity (missing templates/refs) ### M03 `ra3.assets` — runtime asset manager `[ ]` - **F1 Textures** `[~]` - `[x]` TGA decode (`ra3.render`); 256×256 terrain cells - `[ ]` DDS / DXT compressed textures `(v0.5)` - `[ ]` atlas + mip generation, gutter padding (GPU) `[~]` - `[ ]` async upload / streaming `(v0.6)` - **F2 Models** `[ ]` `!!` - `[ ]` W3D container parse (chunks, hierarchy, meshes) `(v0.6)` - `[ ]` materials, shaders, texture references - `[ ]` LOD sets, collision meshes - **F3 Animation** `[ ]` `!!` - `[ ]` W3D animation chunks, bone poses `(v0.6)` - `[ ]` blend trees / transition animations - **F4 Audio** `[ ]` `!!` - `[ ]` audio container + codec decode `(v0.7)` - `[ ]` cue/event tables (unit responses, weapon foley) - **F5 Fonts & glyphs** `[ ]` - `[ ]` bitmap/vector font load; CJK coverage `(v0.5)` - **F6 Asset registry** `[ ]` - `[ ]` cache with ref counting, eviction `(v0.6)` - `[ ]` name-key lookup into the data schema - **F7 UI art (`.apt`)** `[ ]` `!!` - `[ ]` RA3 interface art decode (HUD/command bar) `(v0.7)` ### M04 `ra3.map` — map catalog & loader `[D]` - **F1 Catalog** `[D]` - `[x]` scan `MapsMultiplayer.big` for main map entries - `[ ]` campaign + challenge map catalog `(v0.7)` - **F2 Compiled map (`CkMp`)** `[D]` - `[x]` double unwrap (`BIG4` RefPack → `EAR\0` → RefPack → `CkMp`) - `[x]` name table + chunk list (`{index,version,size,data}`) - `[ ]` full typed chunk dispatch for all chunk kinds `(v0.5)` - **F3 Start positions** `[~]` - `[x]` `Player_N_Start` waypoint scan → `coord3d` - `[ ]` `MPPositionList` layout for maps without waypoints `!!` `(v0.5)` - **F4 Metadata** `[~]` - `[x]` display names from `gamestrings.csf` (`MAP:`) - `[ ]` player count, size, supported game modes `(v0.5)` - **F5 Map rules** `[ ]` - `[ ]` `map.ini` override application `(v0.5)` - **F6 Preview art** `[~]` - `[x]` `_art.tga` overview decode (`--thumbnail`) - **F7 Validation & fallback** `[D]` - `[x]` reject degenerate extractions, fall back to built-in test map - `[ ]` integrity/version checks with actionable errors `(v0.5)` ### M05 `ra3.terrain` — terrain `[P]` - **F1 Heightmap** `[D]` - `[x]` `HeightMapData` v6 (grid, border, `u16` elevations, scale) - `[ ]` multi-resolution / LOD height sampling `(v0.6)` - **F2 Blend tiles** `[D]` - `[x]` `BlendTileData` v27: tile grid, blends/three-way/cliff tables - `[x]` `BlendDescription` parse; `secondaryTile` decode - `[x]` retail `Terrain.fx` blend ramp (`blend_factor`, axis flags) - **F3 Terrain textures** `[D]` - `[x]` `art\terrain\*.tga` from `Terrain.big` / `Core11.big` - `[x]` cell atlas with replicated gutter (GPU bleeding fix) - `[ ]` continuous 32 px / Morton layout (kill residual grid lines) `(v0.4)` - **F4 Water** `[ ]` `!!` - `[ ]` water height/type, sea level `(v0.6)` - `[ ]` animated waves + shoreline blending `(v0.6)` - `[ ]` shroud-aware water rendering `(v0.6)` - **F5 Cliffs & roads** `[ ]` `!!` - `[x]` `CliffTextures` table parsed - `[ ]` cliff mesh + `CliffTextureMapping` UV remap `(v0.6)` - `[ ]` roads and bridges (passability + render) `(v0.6)` - **F6 Terrain lighting** `[ ]` - `[ ]` per-vertex normals, cell lighting, global light `(v0.6)` - **F7 Terrain queries** `[~]` - `[x]` height lookup (render) - `[ ]` passability grid (ground/naval/amphibious/air) `(v0.4)` - `[ ]` buildability grid (flatness, slope, water) `(v0.4)` ### M06 `ra3.logic` — simulation core `[P]` - **F1 Objects & things** `[~]` - `[x]` `thing` → `object` with pluggable `update_module`s - `[x]` global object registry with stable ids - `[ ]` handle/reference system (survives deletion) `(v0.4)` - `[ ]` object destruction lifecycle + death dispatch `(v0.4)` - **F2 Players & teams** `[~]` - `[x]` `player` / `player_list` - `[x]` money (`std::vector`) and power fields - `[x]` team assignment and relations - `[ ]` diplomacy matrix, ally vision sharing `(v0.5)` - **F3 Partition manager** `[~]` - `[x]` spatial grid, neighborhood queries - `[ ]` cell-resolution + large-object multi-cell registration `(v0.4)` - **F4 Game loop** `[~]` - `[x]` 30 Hz deterministic step with frame counter - `[x]` `prepare_new_game` / `start_new_game` two-phase start - `[ ]` per-tick module scheduling with stable ordering `(v0.4)` - **F5 Commands** `[~]` - `[x]` `message_stream` bus - `[ ]` typed commands (build, attack, move, ability, sell, repair) `(v0.4)` - `[ ]` command validation + feedback (insufficient funds, etc.) `(v0.4)` - **F6 Determinism** `[~]` - `[x]` seeded logic random - `[ ]` replay-hash of state per tick `(v0.4)` - `[ ]` float determinism policy / fixed-point where required `(v0.4)` - **F7 Victory / defeat** `[~]` - `[x]` team-wipe / base-destruction win condition - `[ ]` surrender, disconnection, timed, objective victories `(v0.5)` - `[ ]` score / stats accumulation `(v0.8)` ### M07 `ra3.modules` — object update & draw modules `[P]` - **F1 Module system** `[~]` - `[x]` update modules attached to objects with a simple order - `[ ]` module descriptor data-binding (from `ThingTemplate`) `(v0.5)` - `[ ]` interface queries (get WeaponModule / ContainModule on demand) `(v0.4)` - **F2 Locomotor** `[ ]` - `[ ]` movement state machine (idle/moving/attacking) `(v0.4)` - **F3 Weapon module** `[~]` - `[x]` simple weapons on units, auto-target + fire - `[ ]` multi-weapon slots, turret aiming/rotation `(v0.4)` - `[ ]` reload/clip, deploy/undeploy states `(v0.6)` - **F4 Contain** `[ ]` - `[ ]` transport passenger slots, load/unload `(v0.4)` - `[ ]` garrison of civilian structures `(v0.6)` - `[ ]` paradrop / airdrop `(v0.6)` - **F5 Production** `[~]` - `[x]` pay-as-you-go build queue on a factory - `[ ]` per-factory queues, rally points, queue reordering `(v0.4)` - `[ ]` building placement → production handoff `(v0.4)` - **F6 Power** `[~]` - `[x]` power production/consumption fields - `[ ]` brownout/blackout effects on radar + build speed `(v0.4)` - **F7 Upgrades** `[ ]` - `[ ]` upgrade research, unlock dependent modules/weapons `(v0.5)` - **F8 Experience / veterancy** `[ ]` - `[ ]` XP from kills, ranks (veteran/elite/heroic), bonuses `(v0.6)` - `[ ]` chevron rendering `(v0.6)` - **F9 Special abilities** `[~]` - `[ ]` secondary ability slots with cooldown, target/area types `(v0.6)` - `[ ]` toggle/instant/targeted ability kinds `(v0.6)` - **F10 Stealth / disguise / detection** `[ ]` - `[ ]` stealth states, detection radius, decloak on fire `(v0.6)` - `[ ]` disguise (spy-like) and detection interaction `(v0.6)` - **F11 Structure modules** `[~]` - `[x]` base structures, destruction - `[ ]` construction/assembly animation, sell, repair `(v0.4)` - `[ ]` walls/gates if present, defensive structures `(v0.6)` - **F12 Resource modules** `[~]` - `[x]` harvester ↔ refinery ore cycle - `[ ]` ore field spread/depletion, multiple miners, dock queue `(v0.4)` - **F13 Shroud modules** `[ ]` - `[ ]` per-object shroud reveal / clearance `(v0.4)` - **F14 Draw modules** `[ ]` - `[ ]` model draw, animation, particles, construction ghost, temp effects `(v0.6)` ### M08 `ra3.combat` — weapons, warheads, damage `[P]` - **F1 Weapons** `[~]` - `[x]` damage, range, rate of fire, target masks - `[ ]` clip/burst, scatter, arc, continuous beam `(v0.4)` - `[ ]` primary vs secondary weapon selection `(v0.4)` - **F2 Warheads** `[~]` - `[x]` damage type + armor multiplier resolution - `[ ]` radius/falloff, affects mask, death type on kill `(v0.4)` - **F3 Armor** `[~]` - `[x]` `ArmorTemplate` percentage table - `[ ]` armor upgrades and per-state armor `(v0.6)` - **F4 Damage application** `[~]` - `[x]` damage resolution against armor - `[ ]` conditional modifiers (from above, in air, moving) `(v0.4)` - `[ ]` friendly-fire policy, self-damage `(v0.4)` - **F5 Projectiles** `[ ]` - `[ ]` ballistic / laser / missile / beam / homing / arcing `(v0.4)` - `[ ]` projectile draw + impact VFX hook `(v0.6)` - **F6 Targeting** `[~]` - `[x]` simple nearest/in-range acquisition - `[ ]` priority scans (attack-move, guard, force-attack) `(v0.4)` - `[ ]` re-targeting, leash, target ground `(v0.4)` - **F7 Special effects** `[ ]` - `[ ]` EMP/stun, flame/radiation DoT, mind-control, shrink/grow `(v0.7)` - **F8 Death & corpses** `[ ]` - `[ ]` death types, wrecks, gibs, salvage, rebuild `(v0.6)` ### M09 `ra3.movement` — locomotion & pathfinding `[ ]` - **F1 Locomotors** `[ ]` - `[ ]` ground / air / naval / amphibious / hover / teleport `!!` `(v0.4)` - `[ ]` turn rates, acceleration, braking, banking `(v0.6)` - **F2 Pathfinding** `[ ]` - `[ ]` grid A* over the passability grid `(v0.4)` - `[ ]` hierarchical / jump-point refinement `(v0.6)` - `[ ]` dynamic obstacle integration (buildings, units) `(v0.6)` - **F3 Steering & flocking** `[ ]` - `[ ]` separation, avoidance, group cohesion `(v0.6)` - `[ ]` formation slots (line/wedge/box) `(v0.6)` - **F4 Orders & waypoints** `[~]` - `[x]` straight-line move toward a target (skirmish) - `[ ]` waypoint queues, queued orders with shift `(v0.4)` - `[ ]` guard / patrol / attack-move / stop / scatter `(v0.4)` - **F5 Collision & crush** `[ ]` - `[ ]` unit-unit collision, pushing, crush damage `(v0.6)` - **F6 Naval & amphibious** `[ ]` - `[ ]` water-only movement, amphibious land↔water transition `!!` `(v0.6)` - **F7 Transport & airdrop** `[ ]` - `[ ]` boarding/unloading, airdrop descent `(v0.6)` ### M10 `ra3.economy` — resources, power, construction `[P]` - **F1 Ore / resource** `[~]` - `[x]` ore fields and harvester↔refinery cycle - `[ ]` ore spread/regrowth, depletion, ore density `(v0.4)` - **F2 Power** `[~]` - `[x]` power balance fields - `[ ]` brownout/blackout consequences `(v0.4)` - **F3 Construction** `[~]` - `[x]` pay-as-you-go queue, tech prerequisites, build times - `[ ]` build-radius rules (structures must be in base vicinity) `(v0.4)` - `[ ]` low-power build-speed penalty `(v0.4)` - **F4 Placement** `[ ]` - `[ ]` placement grid, footprint validation, green/red ghost `(v0.4)` - `[ ]` adjacency bonuses / prerequisite-adjacent structures `(v0.6)` - **F5 Repair & sell** `[ ]` - `[ ]` structure repair over time, cost, sell refund `(v0.4)` - `[ ]` unit repair pads if present `(v0.6)` - **F6 Rally points** `[ ]` - `[ ]` factory rally, rally preview, waypoint rally `(v0.6)` - **F7 Income modifiers** `[ ]` - `[ ]` bonus crates (cash/units/repair/heal, `random_bonus_crates`) `(v0.5)` ### M11 `ra3.ai` — computer opponents `[P]` - **F1 Skirmish AI** `[~]` - `[x]` simple build AI (base, ore, a couple of unit types) - `[ ]` data-driven build orders per faction `(v0.5)` - `[ ]` economy management (expand, defend harvesters) `(v0.5)` - **F2 Attack management** `[~]` - `[x]` send units at the enemy base - `[ ]` attack force assembly, waves, retreat/regroup `(v0.5)` - `[ ]` targeting priorities (harvesters, key structures) `(v0.6)` - **F3 Team AI / diplomacy** `[ ]` - `[ ]` allied coordination, shared attacks, base defense `(v0.6)` - **F4 Difficulty & personalities** `[ ]` - `[ ]` easy/normal/hard modifiers, AI cheating options `(v0.5)` - `[ ]` commander personalities (aggressive/turtle/air/naval) `(v0.7)` - **F5 Scouting** `[ ]` - `[ ]` exploration, map awareness, threat response `(v0.6)` - **F6 Superweapon usage** `[ ]` - `[ ]` AI powers/power targeting `(v0.7)` - **F7 Script hooks** `[ ]` - `[ ]` AI cooperation with script triggers (campaign) `(v0.7)` ### M12 `ra3.script` — triggers & missions `[ ]` - **F1 Trigger system** `[ ]` `!!` - `[ ]` conditions (elapsed, object in region, destroyed, flag) `(v0.7)` - `[ ]` actions (spawn, order, reveal, camera, dialog, win/lose) `(v0.7)` - **F2 Script engine** `[ ]` `!!` - `[ ]` SAGE script language / mission script parse `(v0.7)` - `[ ]` timers, counters, flags, per-player state `(v0.7)` - **F3 Campaign missions** `[ ]` - `[ ]` mission objectives, sequential phases, briefing `(v0.8)` - `[ ]` three faction campaigns (Allied/Soviet/Empire) `(v0.8)` - **F4 Reinforcements & spawns** `[ ]` - `[ ]` scripted spawns, cinematic units, capture `(v0.8)` - **F5 Tutorials** `[ ]` - `[ ]` tutorial message gates, camera lock/unlock actions `(v0.8)` - **F6 Co-op** `[ ]` - `[ ]` co-op commander missions `(v0.9)` ### M13 `ra3.powers` — superweapons & support powers `[ ]` - **F1 Superweapons** `[ ]` `!!` - `[ ]` Allied Chronosphere `(v0.7)` - `[ ]` Soviet Vacuum Imploder `(v0.7)` - `[ ]` Empire Psionic Decimator `(v0.7)` - `[ ]` charge timer, targeting, ready state, HUD `(v0.7)` - **F2 Support powers** `[ ]` - `[ ]` per-faction powers (spy satellite, air support, etc.) `(v0.7)` - `[ ]` cooldowns, targeting types, cost `(v0.7)` - **F3 Commander's Challenge powers** `[ ]` - `[ ]` challenge-mode power loadouts `(v0.8)` ### M14 `ra3.shroud` — fog of war & radar `[ ]` - **F1 Shroud** `[ ]` - `[ ]` per-player unexplored grid `(v0.4)` - **F2 Fog of war** `[ ]` - `[ ]` explored-but-unseen dimming `(v0.4)` - **F3 Reveal sources** `[ ]` - `[ ]` units/structures reveal radius, abilities, spy satellite `(v0.6)` - **F4 Radar / minimap** `[ ]` - `[ ]` radar texture, unit blips, radar-offline on low power `(v0.6)` - **F5 Shroud ↔ logic** `[ ]` - `[ ]` targetability gating, option for AI to ignore shroud `(v0.4)` ### M15 `ra3.client` — game client & shell `[P]` - **F1 Game client** `[~]` - `[x]` `game_client` facade owning the sim, driving the frame loop - `[ ]` sim/present decoupling, interpolation, catch-up `(v0.6)` - **F2 Tactical view / camera** `[~]` - `[x]` controls: wheel zoom, edge scroll, clamped pan, open on player start - `[x]` camera tuning table (`cameraMinHeight` …) + lock actions - `[ ]` retail perspective camera, pitch/yaw, FOV (needs 3D terrain) `(v0.6)` - **F3 Selection** `[ ]` - `[ ]` click select, drag-box, double-click type select `(v0.6)` - `[ ]` control groups (Ctrl+N), type filters, select-all-of-type `(v0.6)` - **F4 Orders** `[ ]` - `[ ]` contextual right-click orders, force-attack, force-move `(v0.6)` - `[ ]` order queue with shift, formation move `(v0.6)` - **F5 Command bar** `[ ]` `!!` - `[ ]` build/production palettes, ability buttons, portraits `(v0.7)` - `[ ]` tooltips, cost/time, cooldown sweep, disabled states `(v0.7)` - **F6 HUD** `[ ]` - `[x]` minimal match-state overlay (units, start markers) - `[ ]` resource/power readouts, objectives, notifications `(v0.7)` - `[ ]` EVA voice announcements hook `(v0.7)` - **F7 Shell menus** `[~]` - `[x]` map list by localized name + full render/skirmish options; console fallback - `[ ]` main menu, skirmish setup, faction/team/color pickers `(v0.7)` - `[ ]` options (video/audio/keybinds), pause, load/save, credits `(v0.8)` - **F8 Feedback & cursors** `[ ]` - `[ ]` action cursor, placement ghost, move/attack markers `(v0.6)` ### M16 `ra3.render` — renderer & RHI `[P]` - **F1 RHI** `[ ]` - `[ ]` device/queue/swapchain abstraction over Vulkan `(v0.6)` - `[ ]` buffers, textures, samplers, descriptor sets, pipelines `(v0.6)` - `[ ]` `present_terrain` is the seam where this lands today `[~]` - **F2 Render graph** `[ ]` - `[ ]` pass scheduling, barriers, transient/aliased resources `(v0.6)` - **F3 Terrain render** `[~]` - `[x]` top-down software + GPU heightfield with blend ramp + gutter atlas - `[ ]` perspective terrain mesh, LOD, cliff, water `(v0.6)` - **F4 Model render** `[ ]` `!!` - `[ ]` W3D draw, skinning, materials, team colors `(v0.6)` - `[ ]` shadows, decals, ground marks `(v0.6)` - **F5 VFX** `[ ]` - `[ ]` particle systems, beams, muzzle flashes, explosions `(v0.6)` - `[ ]` shader effect graph (retail `.fxo` parity where feasible) `!!` `(v0.7)` - **F6 Sky & atmosphere** `[ ]` - `[ ]` skybox, fog, weather, time-of-day `(v0.7)` - **F7 HUD render** `[ ]` - `[ ]` 2D art layer, fonts, minimap/radar texture `(v0.7)` - **F8 Software renderer** `[D]` - `[x]` ARGB framebuffer, blit/line/circle/text, TGA decode, BMP encode - `[x]` map compositing, grid, markers; headless output - **F9 Post-processing** `[ ]` - `[ ]` bloom, color grading, AA, resolution scaling `(v0.7)` ### M17 `ra3.ui` — platform layer & backends `[D]` - **F1 Display abstraction** `[D]` - `[x]` shared primitives + interactive loops + `ui_event` mapping in the base - `[x]` backends implement primitives only (SDL/Vulkan cannot drift) - **F2 SDL3 backend** `[D]` - `[x]` window, streaming-texture blit, input polling - `[ ]` gamepad support `(v0.8)` - **F3 Backend selection (`ra3.display`)** `[D]` - `[x]` preferred backend + ordered fallback (Vulkan / D3D11 / D3D12 / SDL) - `[x]` in-game Renderer option; report failure for offscreen fallback - **F4 Input mapping** `[~]` - `[x]` keyboard/mouse state, modifier masks - `[ ]` rebindable keybinds, mouse capture, scroll wheel events `(v0.6)` - **F5 Window modes** `[ ]` - `[ ]` windowed/fullscreen/borderless, resize, multi-monitor `(v0.6)` - **F6 Null/headless backend** `[D]` - `[x]` returns false so the tree builds and runs without SDL3/Vulkan ### M18 `ra3.vulkan` — Vulkan backend `[P]` - **F1 Device & swapchain** `[~]` - `[x]` embedded SPIR-V, SDL3 surface, present path - `[ ]` formal RHI integration (see M16 F1) `(v0.6)` - **F2 Terrain presentation** `[D]` - `[x]` GPU heightfield raymarch, mipmapped atlas, gutter, retail blend ramp - **F3 Materials & pipelines** `[ ]` - `[ ]` model/particle/HUD pipelines `(v0.6)` - **F4 Null fallback** `[D]` - `[x]` report failure when no Vulkan loader is present ### M18b `ra3.dx` — Direct3D 11 / 12 backend `[P]` - **F1 Device & swapchain** `[D]` - `[x]` SDL3 window → HWND, DXGI flip-model swapchain, resize - `[x]` runtime HLSL via `d3dcompiler_47` (no build-time shader compiler) - **F2 2D image path** `[D]` - `[x]` BGRA scene texture + fullscreen-triangle blit (D3D11/D3D12) - **F3 Terrain presentation** `[D]` - `[x]` GPU heightfield raymarch (HLSL port of `terrain.frag`), D3D11 and D3D12 - **F4 Root signatures / PSOs (D3D12)** `[~]` - `[x]` root constants, descriptor tables, static samplers, barriers - `[ ]` shared RHI with Vulkan (see M16 F1) `(v0.6)` - **F5 Null fallback** `[D]` - `[x]` non-Windows builds link a stub that fails `init` ### M18c `ra3.webgl` — WebGL backend `[P]` - **F1 Device & canvas** `[D]` - `[x]` Emscripten-only; SDL3 canvas + GLES 3.0 (WebGL2) via `-sUSE_SDL=3` - **F2 2D image path** `[D]` - `[x]` BGRA texture + fullscreen triangle (GLSL ES 300), `.bgra` swizzle - **F3 Terrain presentation** `[D]` - `[x]` GPU heightfield raymarch (GLSL ES port of `terrain.frag`) - **F4 Wasm packaging** `[~]` - `[x]` `openra3.html/.js/.wasm`, assets preloaded into the FS at `/assets` - `[ ]` async/fetch streaming assets instead of a single preload blob `(v0.6)` - **F5 Null fallback** `[D]` - `[x]` non-Emscripten builds link a stub that fails `init` ### M19 `ra3.audio` — audio `[ ]` - **F1 SFX** `[ ]` - `[ ]` 3D positional sound from cues/events `(v0.7)` - **F2 Music** `[ ]` - `[ ]` streaming music, playlists, combat stingers `(v0.7)` - **F3 Voice & EVA** `[ ]` - `[ ]` unit response lines, announcer (EVA) events `(v0.7)` - **F4 Mixer** `[ ]` - `[ ]` buses (master/sfx/music/voice), volume, ducking, reverb `(v0.7)` - **F5 Codecs** `[ ]` `!!` - `[ ]` decode RA3 audio formats `(v0.7)` ### M20 `ra3.video` — movies & cutscenes `[ ]` - **F1 Movie playback** `[ ]` `!!` - `[ ]` intro/briefing/ending video decode + playback `(v0.8)` - `[ ]` skip, subtitles, aspect handling `(v0.8)` - **F2 In-engine cutscenes** `[ ]` - `[ ]` scripted camera + unit animation sequences `(v0.8)` ### M21 `ra3.match` — game setup & match rules `[P]` - **F1 Game setup** `[~]` - `[x]` map + two players + seed defaults - `[ ]` faction/color/team/start-slot selection, AI personalities `(v0.7)` - **F2 Rules & options** `[ ]` - `[ ]` starting cash, crates on/off, superweapons on/off, speed, limits `(v0.7)` - **F3 Match flow** `[~]` - `[x]` `prepare_new_game` / `start_new_game` split mirroring retail - `[ ]` loading progress, in-game start countdown `(v0.7)` - **F4 Factions** `[~]` - `[x]` Allied / Soviet / Empire player templates - `[ ]` full faction tech trees and rosters `(v0.5)` - **F5 Victory & scoring** `[~]` - `[x]` team-wipe victory - `[ ]` full victory conditions, post-match score screen `(v0.8)` ### M22 `ra3.replay` — recording & playback `[ ]` - **F1 Recorder** `[ ]` - `[ ]` capture command stream + seed + map id per match `(v0.4)` - **F2 Replay format** `[ ]` - `[ ]` self-describing header, command log, checksums `(v0.4)` - `[ ]` compatibility with retail `.RA3Replay` playback `!!` `(v0.9)` - **F3 Playback** `[ ]` - `[ ]` deterministic re-simulation, speed control, seek `(v0.4)` - **F4 Golden replays** `[ ]` - `[ ]` curated replay corpus as a regression test `(v0.4)` - **F5 Observer / spectator** `[ ]` - `[ ]` watch live or recorded matches, fog option `(v0.9)` ### M23 `ra3.save` — save/load & profiles `[ ]` - **F1 Save / load** `[ ]` - `[ ]` full simulation state serialization (objects, modules, queues) `(v0.8)` - `[ ]` versioned saves with migration `(v0.8)` - **F2 Profiles** `[ ]` - `[ ]` player profile, stats, progress/unlocks `(v0.8)` - **F3 Options persistence** `[ ]` - `[ ]` settings, keybinds, last-used skirmish config `(v0.7)` - **F4 Checkpoints** `[ ]` - `[ ]` campaign checkpoint save/restore `(v0.9)` ### M24 `ra3.mod` — data packages `[ ]` - **F1 Data packages** `[ ]` - `[ ]` load order, override precedence, loose-file mounting `(v0.8)` - **F2 Content discovery** `[ ]` - `[ ]` scan user mod dirs and additional `.big` archives `(v0.8)` - **F3 Mod validation** `[ ]` - `[ ]` schema + reference checks, actionable errors `(v0.8)` ### M25 `ra3.net` — LAN lockstep `[ ]` *(deferred, offline-only)* - **F1 Lockstep** `[ ]` - `[ ]` deterministic lockstep over LAN, command-exchange only `(v1.0)` - **F2 Lobby & sync** `[ ]` - `[ ]` lobby, slot/team assignment, start sync `(v1.0)` - **F3 Desync detection** `[ ]` - `[ ]` state-hash comparison, desync report `(v1.0)` > No online service, matchmaking, EA account or third-party network > integration — ever. LAN only. ### M26 `ra3.i18n` — localization `[P]` - **F1 CSF strings** `[~]` - `[x]` parse `gamestrings.csf` (UTF-16 units, low byte `^0xFF`) - `[x]` map display-name lookup (`MAP:`) - `[ ]` full string-table load for all UI text `(v0.5)` - **F2 Language selection** `[~]` - `[x]` newest `Lang-English*.big` wins - `[ ]` all supported languages, fallback chain `(v0.5)` - **F3 Fonts & shaping** `[ ]` - `[ ]` glyph coverage, CJK/RTL shaping where applicable `(v0.6)` - **F4 Substitution** `[ ]` - `[ ]` placeholders, numbers, plurals `(v0.5)` ### M27 `apps` — applications `[D]` - **F1 CLI** `[D]` - `[x]` `menu` / `menu-preview` / `maps` / `skirmish` / `render` / `extract` - `[ ]` `replay`, `benchmark`, `validate-data` subcommands `(v0.5)` - **F2 Extraction pipeline** `[~]` - `[x]` `extract` → `assets/` (maps, terrain) - `[ ]` full asset dump (models/textures/audio/movies) as a build target `(v0.5)` - **F3 Diagnostics** `[ ]` - `[ ]` headless render/benchmark modes for CI `(v0.4)` ### M28 `tools` — offline tooling `[~]` *(Python is permitted here; it is never linked into `openra3`.)* - **F1 Reference fetch** `[D]` - `[x]` sparse-clone SAGE 1.0 reference into git-ignored `reference/` - **F2 Ghidra workflow** `[D]` - `[x]` MCP-driven recovery loop + recovered symbol map (see RE doc) - `[ ]` automated structure/table extractors `(v0.5)` - **F3 Format inspectors** `[ ]` - `[ ]` BIG/RefPack/CkMp/W3D/APT dumpers `(v0.5)` - **F4 CI & packaging** `[D]` - `[x]` GitLab CI builds both targets → test → package --- ## 4. Cross-cutting invariants These hold across **every** module above and are enforced in review: 1. **Language** — runtime code is C++ only. Build tooling may use Python. 2. **Ownership** — no raw owning pointers; `unique_ptr` for ownership, handles or `thing *` views for references. 3. **Layering** — a module imports only lower layers. `ra3.core` imports no engine module and no platform API. 4. **Determinism** — RNG, iteration, hashing and float use are explicit and seedable; the logic step must be bit-reproducible for a given input stream. 5. **RE-traceable** — retail structure/constant changes cite an address in [`REVERSE_ENGINEERING.md`](REVERSE_ENGINEERING.md). 6. **Offline** — no online service; LAN lockstep (M25) is the only networking, and only command exchange. 7. **No bundled assets** — game data is read from the user's install; nothing from it is committed. The tree builds and runs in CI on a built-in test map. --- ## 5. Milestone mapping The plan rolls up to these releases: | Milestone | Modules advanced | Delivers | | --- | --- | --- | | `v0.3.x` (done) | M00, M01, M04, M05(F1–F3), M06, M07(partial), M08(partial), M10(partial), M16(F3,F8), M17, M18 | minimal deterministic skirmish, real terrain, Vulkan present, menu | | `v0.4.0` | M05(F4–F7), M06, M07, M08, M09(F1,F2,F4), M14, M22(F1–F4) | real update modules: locomotor, projectiles/warheads, placement, shroud, pathfinding, replay | | `v0.5.0` | M02, M03, M04(F3,F4), M08, M10(F3,F4), M11(F1,F2), M26 | data-driven content: deserialise `.bin`/`.manifest`, real rosters, maps, strings | | `v0.6.0` | M03(F1–F3), M07(F4,F6,F8,F14), M09(F2–F7), M16(F1,F2,F4,F5), M18(F3), M15(F1–F4,F8) | full renderer: perspective terrain, W3D models, in-game client + input | | `v0.7.0` | M13, M15(F5–F7), M19, M11(F4–F6), M20, M21 | HUD/command bar, audio, superweapons, Commander's Challenge | | `v0.8.0` | M12, M20(F1), M23, M24, M21(F5) | campaigns, cutscenes, save/load, mods | | `v0.9.0` | M22(F2,F5), M12(F6), M25 | retail replay playback, co-op, LAN lockstep | | `v1.0.0` | all | feature-complete offline RA3 | --- ## 6. Design rules The five rules the codebase is held to (restated from §1, with the concrete consequences that trip people up): 1. **No raw owning pointers.** Ownership is `std::unique_ptr`; the partition manager and object registry hold non-owning `thing *` views only. 2. **Portable simulation.** No platform APIs in `ra3.core` / simulation modules. All platform concerns live behind `display`. 3. **Determinism.** Anything that can diverge between runs (random, iteration order) is explicit and seedable. 4. **RE-traceable.** Where a structure or constant comes from the retail binary, the address is cited in the comment. 5. **No bundled assets, no online.** Game data is read from the user's install and never committed; there is no networking or online service. --- ## 7. Where to start - New to the codebase: read this plan top-to-bottom (§3 is the feature set, §5 the near-term order of work). - Picking up a feature: find its **Function** above, take the lowest-numbered unmet `[ ]` **Feature**, and cite its supporting retail address. - Reverse engineering a subsystem: follow the loop in [`REVERSE_ENGINEERING.md`](REVERSE_ENGINEERING.md); the `!!` tags above mark the functions that still need a recovery pass before they can be built.