Files
OpenRA3/docs/ARCHITECTURE.md
T
EnderTheCoder 26e1934a5d feat(render): SAGE water/ocean shaders, per-user logs, camera & culling
Terrain pass now ports the SAGE water model (Ocean.fx / OpenSAGE Water.frag): a de-gridded procedural wave normal combined with the retail ra3_deepocean flow and ra3_deepocean_nrm bump maps (appended as the last two terrain-atlas layers, no new backend binding), Schlick fresnel, sky reflection + depth-graded refraction, SAGE diffuse/specular lighting, depth-based transparency, and an underwater tint (UnderwaterDeferred.fx). Mirrored across terrain.frag / dx_terrain.hlsl / webgl_terrain_frag.glsl / webgpu_terrain.wgsl.

Also: logs move to the per-user state dir (%LOCALAPPDATA%\\OpenRA3\\logs, else XDG) and archive as openra3.<stamp>.log; the FPS label shows the active backend; middle-drag camera reset; objects and roads below the water plane are culled.
2026-09-30 22:18:08 +08:00

40 KiB
Raw Blame History

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.webgpu / ra3.wasmgl
                                  |          (SDL3)  (Vulkan)   (D3D11/12) (wasm workers)
   ---------------------------------------------------------------------------
                                  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.models, ra3.render, ra3.ui.*, ra3.vulkan.*, ra3.dx.*, ra3.webgpu.*, ra3.wasmgl.*, 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 [~]
    • [x] compiled W3DMesh decode (vertex buffer + D3D9 declaration + triangle list) from the BAB static/worldbuilder stream
    • [x] embedded DDS textures (DXT1/3/5 + uncompressed RGB) → ARGB
    • [x] W3DHierarchy decode + static bind-pose skinning (bone-space vertices)
    • [ ] W3D container/hierarchy animation, LOD sets, collision meshes !! (v0.6)
  • 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:<ID>)
    • [ ] player count, size, supported game modes (v0.5)
  • F5 Map rules [ ]
    • [ ] map.ini override application (v0.5)
  • F6 Preview art [~]
    • [x] <map>_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_modules
    • [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<Money*>) 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 (v0.6)
    • [x] water surface in the raymarch: SAGE Water.frag port (ocean/river) [~]
  • F4 Model render [~]
    • [x] static map-object triangle soup, world-space, depth-tested over the terrain (Vulkan + software)
    • [x] bind-pose skinning (bone-space vertices) + ground-decal depth bias
    • [ ] animated W3D draw, 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 [ ]
    • [x] underwater tint/fog in the terrain pass (retail UnderwaterDeferred.fx) [~]
    • [ ] bloom, color grading, AA, resolution scaling (v0.7)

M16b shader porting status (retail Data\Shaders.big → *.fxo)

The retail set is 88 compiled effects (Core12\shaders\compiled, duplicated in Misc/Shaders; Core5/Core8 ship only terrain; plus a 60-byte null stub). OpenRA3 implements the static-map subset only:

  • Ported (approximate stand-ins, shared by all backends): Terrain.fx (terrain.*), the opaque diffuse subset of BuildingsGeneric.fx / BasicW3D.fx / ObjectsGeneric.fx (object.*), and the SAGE water model Ocean.fx (+ OceanDisplacement/OceanNoVertexTexture/RiverWater/ RiverReflection/UnderwaterDeferred, folded into the terrain.* water branch — see docs/REVERSE_ENGINEERING.md). The retail water flow and bump maps (art/terrain/ra3_deepocean.tga, ra3_deepocean_nrm.tga) ride as the last two terrain-atlas layers, so no backend adds a binding.
  • Not ported: all faction/variant model shaders (buildings*, objects*, basicw3d*, defaultw3d*, normalmapped, tree/treesway), instances/ animation (infantry*), particles and beams (cpuparticle, gpuparticle*, swarmparticle, laser*, lightning, fx*, tracer, trail, connectionline, linerenderers, stream, rain, simple*), shadows and ground decals (shadow, decal, outlines, occlusion, terraintracks), post-processing (postfx_*), and the 2D/misc shaders (render2d, video, bootupscreen, debug, errormissing, rotateenvironmentmap, distortingobject). The shared retail includes shadowmap.fxh, ssao.fxh, macrotexture.fxh, gamma.fxh are likewise absent (skinning.fxh is done at bind pose only).

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 [~]
    • [x] static-model pipeline (vertex/index buffers, texture array, depth test)
    • [ ] 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

M18d ra3.wasmgl — SDL-free wasm worker backend [P]

  • F1 Device & canvas [D]
    • [x] Emscripten-only; engine runs on a plain Web Worker, WebGL2 on an OffscreenCanvas transferred by the page (no SDL, no PROXY_TO_PTHREAD)
    • [x] specialHTMLTargets['#canvas'] lets emscripten_webgl_create_context find the worker's OffscreenCanvas
  • F2 2D image path [D]
    • [x] GLSL ES BGRA texture + fullscreen triangle (.bgra swizzle)
  • F3 Terrain presentation [D]
    • [x] GPU heightfield raymarch (GLSL ES), including the GL_R16 (0x822A) heightmap and GL_RGBA16 cell textures
  • F4 On-demand assets [D]
    • [x] assets.manifest.json (from scripts/make_web_manifest.py) is embedded; the worker registers every file with FS.createLazyFile, so only opened files are fetched (a map pulls just its map + tiles)
  • F5 Input [D]
    • [x] page owns DOM listeners and posts events to the worker's exported openra3_* functions (no DOM callbacks in the worker)
  • F6 Null fallback [D]
    • [x] non-Emscripten builds link a stub that fails init

M18e ra3.webgpu — WebGPU wasm backend [P]

  • F1 Device & surface [D]
    • [x] Emscripten emdawnwebgpu port (Dawn C++ wrapper); the worker pre-creates the device (Module.preinitializedWebGPUDevice) and a surface is configured on the transferred OffscreenCanvas
  • F2 WGSL shaders [D]
    • [x] web WebGPU is WGSL-only, so the scene/terrain shaders are WGSL ports (the Vulkan SPIR-V blobs cannot be reused); the uniform layout and terrain data plumbing are shared with Vulkan/WebGL
  • F3 Terrain [D]
    • [x] GPU heightfield raymarch in WGSL (R16Uint heightmap, RGBA16Uint cell record, RGBA8 atlas)
  • F4 Selection & fallback [D]
    • [x] preferred wasm backend; falls back to ra3.wasmgl when no adapter is available
  • 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:<ID>)
    • [ ] 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.
  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; the !! tags above mark the functions that still need a recovery pass before they can be built.