- ra3.webgl: a Web peer of Vulkan/Direct3D (SDL3 canvas + GLES3/WebGL2), with 2D blit and the GPU terrain raymarch; GLSL ES shaders; null fallback off Emscripten. backend::webgl + default_backend() (webgl under Emscripten). - Emscripten toolchain + Dockerfile.wasm + scripts/build-wasm.sh; import std, global -fexceptions, and Asyncify so the blocking frame loop yields to the browser (display::sleep_frame calls emscripten_sleep). - apps/web/shell.html + apps/web/serve.py (Range-capable dev server). - Assets: browsers forbid synchronous on-demand reads on the main thread (and FS.createLazyFile / the WasmFS fetch backend are worker-only; SDL3's Emscripten backend is main-thread DOM only, so the engine cannot run in a worker). The wasm build therefore preloads a compact per-map set via OPENRA3_WEB_ASSETS. - New openra3 textures --map ID lists the loose terrain TGAs a map resolves to (terrain::resolve_texture_files, shared with load_textures_from_dir). - Fixes: webgl heightmap used GL_R16 = 0x8229 (that is R8) -> upload rejected, terrain flattened to water; now 0x822A. Logger uses a stdout console sink on the web (stderr maps to console.error); a GL error check logs bad uploads. - CI: wasm image + build jobs.
36 KiB
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:
- the layer architecture (how the modules sit on top of one another), and
- 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:
- 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 intoopenra3. - No raw owning pointers. Ownership is
std::unique_ptr; cross-references are non-owning views (thing *, handles, indices). - Portable simulation. No platform API in the foundation or simulation
layers. All platform concerns live behind
display/audio/video. - Determinism. Anything that can diverge between runs (RNG, iteration order, float accumulation, hash order) is explicit, seeded and testable.
- RE-traceable. Every structure or constant taken from the retail
ra3_1.12.game(image base0x400000) 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,boolaliases[x]coord2d/coord3dvectors, 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)[ ]KindOfflag 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]seedablerandomstream (game_logicrandom)[ ]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 (appendMessage0x0060c4a0)[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^0xFFdecode[ ]placeholder substitution, plural/gender rules(v0.5)
M01 ra3.fs — containers & install [D]
- F1 BIG archive
[D][x]BIG4header parse (fileSizeLE,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_sizewithout full decompress[ ]encode (for tooling round-trips)(v0.8)
- F3 Install locator
[D][x]--game-dir/$RA3_GAME_DIR/C:\Red Alert 3defaults[ ]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 (newestLang-*.bigwins)(v0.5)[ ]case-insensitive lookup + path normalisation(v0.5)
- F5 Extraction targets
[D][x]openra3 extractdumps maps/terrain toassets/[ ]full asset dump viara3toolsintegration 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[ ].manifestcompiled-blob schema!!(v0.5)
- F2 Compiled asset blobs
[ ]!![ ]global.bindeserialisation(v0.5)[ ]static.*.bindeserialisation(v0.5)[ ]version/dependency validation(v0.5)
- F3 Balance tables
[~][x]damage types,ArmorTemplatepercentages[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/ObjectTemplateinheritance graph(v0.5)[ ]module descriptor lists (per-object update/draw module sets)[ ]WeaponTemplate/ArmorTemplate/LocomotorTemplatestores
- 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]scanMapsMultiplayer.bigfor main map entries[ ]campaign + challenge map catalog(v0.7)
- F2 Compiled map (
CkMp)[D][x]double unwrap (BIG4RefPack →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_Startwaypoint scan →coord3d[ ]MPPositionListlayout for maps without waypoints!!(v0.5)
- F4 Metadata
[~][x]display names fromgamestrings.csf(MAP:<ID>)[ ]player count, size, supported game modes(v0.5)
- F5 Map rules
[ ][ ]map.inioverride application(v0.5)
- F6 Preview art
[~][x]<map>_art.tgaoverview 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]HeightMapDatav6 (grid, border,u16elevations, scale)[ ]multi-resolution / LOD height sampling(v0.6)
- F2 Blend tiles
[D][x]BlendTileDatav27: tile grid, blends/three-way/cliff tables[x]BlendDescriptionparse;secondaryTiledecode[x]retailTerrain.fxblend ramp (blend_factor, axis flags)
- F3 Terrain textures
[D][x]art\terrain\*.tgafromTerrain.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]CliffTexturestable parsed[ ]cliff mesh +CliffTextureMappingUV 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→objectwith pluggableupdate_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_gametwo-phase start[ ]per-tick module scheduling with stable ordering(v0.4)
- F5 Commands
[~][x]message_streambus[ ]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 (fromThingTemplate)(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]ArmorTemplatepercentage 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_clientfacade 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_terrainis 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.fxoparity 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_eventmapping 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 viad3dcompiler_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 ofterrain.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 failsinit
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),.bgraswizzle
- F3 Terrain presentation
[D][x]GPU heightfield raymarch (GLSL ES port ofterrain.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 failsinit
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_gamesplit 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.RA3Replayplayback!!(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.bigarchives(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]parsegamestrings.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]newestLang-English*.bigwins[ ]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-datasubcommands(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-ignoredreference/
- 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:
- Language — runtime code is C++ only. Build tooling may use Python.
- Ownership — no raw owning pointers;
unique_ptrfor ownership, handles orthing *views for references. - Layering — a module imports only lower layers.
ra3.coreimports no engine module and no platform API. - Determinism — RNG, iteration, hashing and float use are explicit and seedable; the logic step must be bit-reproducible for a given input stream.
- RE-traceable — retail structure/constant changes cite an address in
REVERSE_ENGINEERING.md. - Offline — no online service; LAN lockstep (M25) is the only networking, and only command exchange.
- 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):
- No raw owning pointers. Ownership is
std::unique_ptr; the partition manager and object registry hold non-owningthing *views only. - Portable simulation. No platform APIs in
ra3.core/ simulation modules. All platform concerns live behinddisplay. - Determinism. Anything that can diverge between runs (random, iteration order) is explicit and seedable.
- RE-traceable. Where a structure or constant comes from the retail binary, the address is cited in the comment.
- 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.