From 59261868e1af009b9065e6d7ef95b43027aa84ce Mon Sep 17 00:00:00 2001 From: EnderTheCoder Date: Sat, 26 Sep 2026 22:28:19 +0800 Subject: [PATCH] docs: rewrite ARCHITECTURE as a Module/Function/Feature master plan Decompose the full Red Alert 3 feature set three levels deep (29 modules, 169 functions, ~500 features) with per-feature status and milestone tags. Fold the release roadmap into ARCHITECTURE section 5 and remove docs/ROADMAP.md. --- README.md | 2 +- docs/ARCHITECTURE.md | 841 +++++++++++++++++++++++++++++++++++++------ docs/ROADMAP.md | 60 --- 3 files changed, 741 insertions(+), 162 deletions(-) delete mode 100644 docs/ROADMAP.md diff --git a/README.md b/README.md index 97cbc4f..4ffc146 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ built-in test map so the project still builds and runs in CI. | `apps/openra3/main.cpp` | `menu` / `maps` / `skirmish` / `render` CLI | | `tests/ra3_tests.cpp` | smoke tests (run via `ctest`) | | `tools/` | reference fetch + Ghidra-driven reconstruction helpers | -| `docs/` | architecture, reverse-engineering notes, roadmap | +| `docs/` | architecture & master plan, reverse-engineering notes | | `Dockerfile` | Linux build image (`dev` toolchain + `deploy` runtime) | | `Dockerfile.win` | isolated Windows cross-build image (llvm-mingw + SDL3 MinGW) | | `cmake/toolchains/` | `llvm-mingw-x86_64.cmake` cross toolchain | diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index ba17169..77a785b 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,131 +1,770 @@ -# Architecture +# Architecture & Master Plan -OpenRA3 is organised as a stack of C++26 modules. Each layer may import the ones -below it, never the ones above. Every module uses `import std;` for the standard -library; the engine is built with Clang + libc++ on Linux and cross-compiled -with llvm-mingw for Windows. +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. ``` - ┌───────────────────────────────────────┐ - applications │ openra3 (apps/openra3) │ - └───────────────────┬───────────────────┘ - │ import ra3 - ┌───────────────────▼───────────────────┐ - umbrella │ ra3 (re-exports everything) │ - └───────────────────┬───────────────────┘ - ┌──────────────┬───────────────┼───────────────┬──────────────┐ - ▼ ▼ ▼ ▼ ▼ - ra3.display ra3.render ra3.skirmish ra3.client ra3.game - backend pick framebuffer match rules display+loops RA3 sides - │ │ │ │ │ - ┌──┴───┐ │ └───────┬───────┘ │ - ▼ ▼ ▼ ▼ │ -ra3.ui ra3.vulkan ra3.terrain ra3.logic │ -SDL Vulkan heightmap/blends simulation │ - ┌──────────────────────┘ - ▼ - ra3.map / ra3.fs - catalog / BIG4 + RefPack + 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 + | (SDL3) (Vulkan) + --------------------------------------------------------------------------- + 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) ``` -## Presentation layer +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.display`, `ra3.game`, `ra3.client`) 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. -`ra3.client::display` is the single seam between the engine and the windowing -stack. A backend implements only the low-level primitives (`init`, `present`, -`poll_event`, `window_size`, `key_down`, `shutdown`) and, optionally, -`present_terrain`; the interactive loops (menu, image viewer, camera viewer, -GPU terrain) and the native-to-`ui_event` mapping live once in the base class, -so the SDL and Vulkan paths cannot drift. SDL3 remains the platform layer (it -owns the window, input and the low-cost blit backend); Vulkan is the accelerated -backend. `ra3.display` selects the first backend that starts, and the app never -references a backend by name. +### Status legend -The Vulkan backend currently hand-rolls its pipelines. As materials, skybox and -HUD arrive, a thin RHI + render-graph belongs between `ra3.client` and the -Vulkan/SDL backends; `present_terrain` is the placeholder for that step. +| 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 | -## Module responsibilities +--- -### `ra3.core` -The vocabulary every other module shares, mirroring SAGE's `GameEngine/Common`: -`real`/`int32`/`uint32`, `coord3d`/`coord2d`/`rgb_color`, `ascii_string` + -`make_name_key`, the deterministic `random` stream, and the `message_stream` -command bus (node layout derived from retail `MessageStream::appendMessage`, -`0x0060c4a0`). +## 3. Master plan — Module → Function → Feature -### `ra3.logic` -The deterministic simulation, mirroring SAGE's `GameLogic`: `thing` → `object` -with pluggable `update_module`s, `player`/`player_list`, the `partition_manager` -spatial grid, and the 30 Hz `game_logic` driver (`prepare_new_game` / -`start_new_game` / `update`). +### M00 `ra3.core` — foundation vocabulary `[D]` -### `ra3.client` -The presentation boundary: the abstract `display` (low-level primitives plus the -shared interactive loops and `ui_event` mapping), a `headless_display` for -CPU-only runs, and `game_client`, the facade that owns the simulation and drives -the frame loop. +Mirrors SAGE `GameEngine/Common`. Everything else speaks this. -### `ra3.display` -Backend selection: tries Vulkan, then SDL, then reports failure so the caller can -fall back to an offscreen image. The only module that names a concrete backend. +- **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)` -### `ra3.terrain` -The real map terrain: parses `CkMp`'s `HeightMapData` and `BlendTileData` -(tiles, `Blends`/`ThreeWayBlends` and their `BlendDescription`s), loads the -`Terrain.big` tile textures, and rasterises the map (software `render`/`render3d` -and the GPU `gpu_terrain` for `present_terrain`). +### M01 `ra3.fs` — containers & install `[D]` -### `ra3.game` -Red Alert 3 data that SAGE keeps in `PlayerTemplate`: the three sides -(`faction` flags `Empire=2`, `Allied=4`, `Soviet=8`, `Random=7`, recovered from -the retail skirmish setup) and skirmish defaults. +- **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)` -### `ra3.fs` -Reading the user's installation. Implements the `BIG4` archive container and -EA's RefPack codec, plus `find_game_dir` (`--game-dir` / `$RA3_GAME_DIR` / -`C:\Red Alert 3`). Only the archive index is held in memory; payloads are read -on demand. +### M02 `ra3.data` — data schema & balance `[P]` -### `ra3.map` -Map discovery and loading: scans `MapsMultiplayer.big` for main map entries, -unwraps the two compression layers (`BIG4` RefPack → `EAR\0` wrapper → RefPack → -`CkMp`), recovers `Player_N_Start` waypoint coordinates, and decodes the -localized display names from the install's `gamestrings.csf`. Degenerate -extractions are rejected so the caller can fall back. +- **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) -### `ra3.skirmish` -The minimal match: two players, unit classes (harvester/infantry/tank/base), -passive + harvester income, a simple build AI, movement and combat on a fixed -30 Hz step, and a base-destruction win condition. Fully deterministic. +### M03 `ra3.assets` — runtime asset manager `[ ]` -### `ra3.render` -A dependency-free software renderer: an ARGB8888 `image` framebuffer with -blit/line/circle/text primitives (an embedded 8x8 bitmap font), a TGA decoder for -the game's map art, a 24-bit BMP encoder for headless output, and `compose` which -overlays a world grid and markers (start positions, live units) onto the map art. +- **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)` -### `ra3.ui` -The SDL3 backend: `sdl_display` implements the `ra3.client::display` primitives -using an `SDL_Renderer` streaming texture. Cheap and dependency-light, it is the -fallback when Vulkan is unavailable. A null backend returns `false` so the build -still runs without SDL3. +### M04 `ra3.map` — map catalog & loader `[D]` -### `ra3.vulkan` -The accelerated backend: `vulkan_display` implements the same primitives and -adds `present_terrain`, a GPU heightfield raymarcher (mipmapped tile atlas with a -replicated gutter and the retail SAGE blend ramp). A null backend reports failure -when no Vulkan loader is present. +- **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)` -## Design rules +### 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]` try Vulkan → SDL → 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 + +### 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 holds non-owning `thing *` views only. -2. **Portable simulation.** No platform APIs in `ra3.core` / `ra3.logic`. All - platform concerns live behind `display`. + 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. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md deleted file mode 100644 index 523d50d..0000000 --- a/docs/ROADMAP.md +++ /dev/null @@ -1,60 +0,0 @@ -# Roadmap - -OpenRA3 is a very large undertaking. This roadmap is deliberately honest about -scope: reconstructing a 2008 RTS engine from a decompiler plus a related open -engine is a multi-year, multi-person effort. The milestones below are ordered so -that each one produces something that builds and runs. - -## Done - -- [x] **v0.0.1 — skeleton + minimal skirmish.** C++26 modules, GCC 16, - CMake/Ninja, Docker `dev`/`deploy`, GitLab CI. Reads `BIG4`/RefPack data - from a local install, recovers map start waypoints, and runs a - deterministic headless two-player skirmish to a decision. -- [x] **v0.1.0 — map renderer + window.** Software ARGB framebuffer, TGA - decoder for the map art, BMP output, map/grid/unit compositing, and an - SDL3 window viewer (pan/zoom). -- [x] **v0.2.0 — dual toolchain.** Switched to Clang + libc++ with - `import std;` in every module; added an isolated Windows cross-build - (llvm-mingw + SDL3 MinGW) producing `openra3.exe` + `SDL3.dll`, alongside - the Linux build. Both images are separate to keep the toolchains apart. -- [x] **v0.3.2 — real terrain.** `ra3.terrain` parses the map's `HeightMapData` - and `BlendTileData` and rasterises the actual terrain from the install's - `Terrain.big` tile textures (top-down, elevation-shaded), replacing the - `_art.tga` overview as what `render` draws. -- [x] **v0.3.0 — real balance + skirmish + Vulkan.** `ra3.data` pins the retail - numbers (damage types, `ArmorTemplate` percentages, weapons, units, - structures, ore economy) audited from EA's open RA3 XML; `ra3.skirmish` is - rebuilt on them (armour resolution, weapon target masks, pay-as-you-go - build queue, power, tech prerequisites, refinery ore cycle, team-wipe - victory); and `ra3.vulkan` replaces the presentation stack with Vulkan - (SDL3 surface, embedded SPIR-V), with a null fallback where no loader - exists. - -## Next - -- [ ] **v0.3.1 — tactical map view.** The Vulkan/SDL viewer reproduces the - retail tactical view (`TheTacticalView`, `ra3_1.12.game` `0x00cdb7b4`): - opens centred on the player's start, wheel zoom, edge scroll and clamped - pan. A hand-rolled HUD was tried and removed — the real in-game interface - is `.apt` art that must be recovered first, so it is not on the near - roadmap. -- [ ] **v0.4.0 — real update modules.** Locomotor movement, projectiles and - warheads, build placement, shroud, and pathfinding, driven by the - `GameObject` module set recovered from the binary. -- [ ] **v0.5.0 — data-driven content.** Deserialise the compiled assets - (`global.bin`/`static.*.bin` + `.manifest`) so `ra3.data` reads the - install instead of pinned constants; real maps, models and strings. -- [ ] **v0.6.0 — full renderer.** Perspective terrain (the heightmap is decoded - but drawn top-down today), W3D models and the full in-game client on - Vulkan, plus input. - -## Cross-cutting tracks - -- **RE depth** — keep recovering retail layouts (see - [`REVERSE_ENGINEERING.md`](REVERSE_ENGINEERING.md)); every structure gets an - address citation and a test. -- **Determinism & replay** — the logic random stream and frame ordering must be - reproducible; replay format and a golden-replay test suite. -- **Offline only** — no online mode. Multiplayer, if pursued, is LAN lockstep on - the message stream, never an online service.