Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Red Alert Experience Recreation Strategy

Making IC feel like Red Alert requires more than loading the right files. The graphics, sounds, menu flow, unit selection, cursor behavior, and click feedback must recreate the experience that players remember — verified against the actual source code. We have access to four authoritative reference codebases. Each serves a different purpose.

Reference Source Strategy

SourceLicenseWhat We ExtractWhat We Don’t
EA Original Red Alert (CnC_Red_Alert)GPL v3Canonical gameplay values (costs, HP, speeds, damage tables). Integer math patterns. Animation frame counts and timing constants. SHP draw mode implementations (shadow, ghost, fade, predator). Palette cycling logic. Audio mixing priorities. Event/order queue architecture. Cursor context logic.Don’t copy rendering code verbatim — it’s VGA/DirectDraw-specific. Don’t adopt the architecture — #ifdef branching, global state, platform-specific rendering.
EA Remastered Collection (CnC_Remastered_Collection)GPL v3 (C++ DLLs)UX gold standard — the definitive modernization of the RA experience. F1 render-mode toggle (D048 reference). Sidebar redesign. HD asset pipeline (how classic sprites map to HD equivalents). Modern QoL additions. Sound mixing improvements. How they handled the classic↔modern visual duality.GPL covers C++ engine DLLs only — the HD art assets, remastered music, and Petroglyph’s C# layer are proprietary. Never reference proprietary Petroglyph source. Never distribute remastered assets.
OpenRA (OpenRA)GPL v3Working implementation reference for everything the community expects: sprite rendering order, palette handling, animation overlays, chrome UI system, selection UX, cursor contexts, EVA notifications, sound system integration, minimap rendering, shroud edge smoothing. OpenRA represents 15+ years of community refinement — what players consider “correct” behavior. Issue tracker as pain point radar.Don’t copy OpenRA’s balance decisions verbatim (D019 — we offer them as a preset). Don’t port OpenRA bugs. Don’t replicate C# architecture — translate concepts to Rust/ECS.
Bevy (bevyengine/bevy)MITHow to BUILD it: sprite batching and atlas systems, bevy_audio spatial audio, bevy_ui layout, asset pipeline (async loading, hot reload), wgpu render graph, ECS scheduling patterns, camera transforms, input handling.Bevy is infrastructure, not reference for gameplay feel. It tells us how to render a sprite, not which sprite at what timing with what palette.

The principle: Original RA tells us what the values ARE. Remastered tells us what a modern version SHOULD feel like. OpenRA tells us what the community EXPECTS. Bevy tells us how to BUILD it.

Visual Fidelity Checklist

These are the specific visual elements that make Red Alert look like Red Alert. Each must be verified against original source code constants, not guessed from screenshots.

Sprite Rendering Pipeline

ElementOriginal RA Source ReferenceIC Implementation
Palette-indexed renderingPAL format: 256 × RGB in 6-bit VGA range (0–63). Convert to 8-bit: value << 2. See 05-FORMATS.md § PALic-cnc-content loads .pal; ic-render applies via palette texture lookup (GPU shader)
SHP draw modesSHAPE.H: SHAPE_NORMAL, SHAPE_SHADOW, SHAPE_GHOST, SHAPE_PREDATOR, SHAPE_FADING. See 05-FORMATS.md § SHPEach draw mode is a shader variant in ic-render. Shadow = darkened ground sprite. Ghost = semi-transparent. Predator = distortion. Fading = remap table
Player color remappingPalette indices 80–95 (16 entries) are the player color remap range. The original modifies these palette entries per playerGPU shader: sample palette, if index ∈ [80, 95] substitute from player color ramp. Same approach as OpenRA’s PlayerColorShift
Palette cyclingWater animation: rotate palette indices periodically. Radar dish: palette-animated. From ANIM.CPP timing loopsic-render system ticks palette rotation at the original frame rate. Cycling ranges are YAML-configurable per theater
Animation frame timingFrame delays defined per sequence in original .ini rules (and OpenRA sequences/*.yaml). Not arbitrary — specific tick counts per framesequences/*.yaml in mods/ra/ defines frame counts, delays, and facings. Timing constants verified against EA source #defines
Facing quantization32 facings for vehicles/ships, 8 for infantry. SHP frame index = facing / (256 / num_facings) * frames_per_facingQuantizeFacings component carries the facing count. Sprite frame index computed in render system. Matches OpenRA’s QuantizeFacingsFromSequence
Building construction animation“Make” animation plays forward on build, reverse on sell. Specific frame orderWithMakeAnimation equivalent in ic-render. Frame order and timing from EA source BUILD.CPP
Terrain theater palettesTemperate, Snow, Interior — each with different palette and terrain tileset. Theater selected by mapPer-map theater tag → loads matching .pal and terrain .tmp sprites. Same theater names as OpenRA
Shroud / fog-of-war edgesOriginal RA: hard shroud edges. OpenRA: smooth blended edges. Remastered: smoothedIC supports both styles via ShroudRenderer visual config — selectable per theme/render mode
Building bibsFoundation sprites drawn under buildings (paved area)Bib sprites from .shp, drawn at z-order below building body. Footprint from building definition
Projectile spritesBullets, rockets, tesla bolts — each a separate SHP animationProjectile entities carry SpriteAnimation components. Render system draws at interpolated positions between sim ticks
Explosion animationsMulti-frame explosion sequences at impact pointsExplosionEffect spawned by combat system. ic-render plays the animation sequence then despawns

Z-Order (Draw Order)

The draw order determines what renders on top of what. Getting this wrong makes the game look subtly broken — units clipping through buildings, shadows on top of vehicles, overlays behind walls. The canonical order (verified from original source and OpenRA):

Layer 0: Terrain tiles (ground)
Layer 1: Smudges (craters, scorch marks, oil stains)
Layer 2: Building bibs (paved foundations)
Layer 3: Building shadows + unit shadows
Layer 4: Buildings (sorted by Y position — southern buildings render on top)
Layer 5: Infantry (sub-cell positioned)
Layer 6: Vehicles / Ships (sorted by Y position)
Layer 7: Aircraft shadows (on ground)
Layer 8: Low-flying aircraft (sorted by Y position)
Layer 9: High-flying aircraft
Layer 10: Projectiles
Layer 11: Explosions / visual effects
Layer 12: Shroud / fog-of-war overlay
Layer 13: UI overlays (health bars, selection boxes, waypoint lines)

Within each layer, entities sort by Y-coordinate (south = higher draw order = renders on top). This is the standard isometric sort that prevents visual overlapping artifacts. Bevy’s sprite z-ordering maps to this layer system via Transform.translation.z.

Audio Fidelity Checklist

Red Alert’s audio is iconic — the EVA voice, unit responses, Hell March, the tesla coil zap. Audio fidelity requires matching the original game’s mixing behavior, not just playing the right files.

Sound Categories and Mixing

CategoryPriorityBehaviorOriginal RA Reference
EVA voice linesHighestQueue-based, one at a time, interrupts lower priority. “Building complete.” “Unit lost.” “Base under attack.”AUDIO.CPP: Speak() function, priority queue with cooldowns per notification type
Unit voice responsesHighPlays on selection and on command. Multiple selected units: random pick from group, don’t overlap. “Acknowledged.” “Yes sir.” “Affirmative.”AUDIO.CPP: Voice mixing. Response set defined per unit type in rules
Weapon fire soundsNormalPositional (spatial audio). Volume by distance from camera. Multiple simultaneous weapons don’t clip — mixer clampsAUDIO.CPP: Fire sounds tied to weapon in rules. Spatial attenuation
Impact / explosion soundsNormalPositional. Brief, one-shot.Warhead-defined sounds in rules
Ambient / environmentalLowLooping. Per-map or conditional (rain during storm weather, D022)Background audio layer
MusicBackgroundSequential jukebox. Tracks play in order; player can pick from options menu. Missions can set a starting theme via scenario INITHEME.CPP: Theme_Queue(), theme attributes (tempo, scenario ownership). No runtime combat awareness — track list is fixed at scenario start

Original RA music system: The original game’s music was a straightforward sequential playlist. THEME.CPP manages a track list with per-theme attributes — each theme has a scenario owner (some tracks only play in certain missions) and a duration. In skirmish, the full soundtrack is available. In campaign, the scenario INI can specify a starting theme, but once playing, tracks advance sequentially and the player can pick from the jukebox in the options menu. There is no combat-detection system, no crossfades, and no dynamic intensity shifting. The Remastered Collection and OpenRA both preserve this simple jukebox model.

IC enhancement — dynamic situational music: While the original RA’s engine didn’t support dynamic music, IC’s engine and SDK treat dynamic situational music as a first-class capability. Frank Klepacki designed the RA soundtrack with gameplay tempo in mind — high-energy industrial during combat, ambient tension during build-up (see 13-PHILOSOPHY.md § Principle #11) — but the original engine didn’t act on this intent. IC closes that gap at the engine level.

ic-audio provides three music playback modes, selectable per game module, per mission, or per mod:

# audio/music_config.yaml
music_mode: dynamic               # "jukebox" | "sequential" | "dynamic"

# Jukebox mode (classic RA behavior):
jukebox:
  tracks: [BIGF226M, GRNDWIRE, HELLMARCH, MUDRA, JBURN_RG, TRENCHES, CC_THANG, WORKX_RG]
  order: sequential               # or "shuffle"
  loop: true

# Dynamic mode (IC engine feature — mood-tagged tracks with state-driven selection):
dynamic_playlist:
  ambient:
    tracks: [BIGF226M, MUDRA, JBURN_RG]
  build:
    tracks: [GRNDWIRE, WORKX_RG]
  combat:
    tracks: [HELLMARCH, TRENCHES, CC_THANG]
  tension:
    tracks: [RADIO2, FACE_THE_ENEMY]
  victory:
    tracks: [RREPORT]
  defeat:
    tracks: [SMSH_RG]
  crossfade_ms: 2000              # default crossfade between mood transitions
  combat_linger_s: 5              # stay in combat music 5s after last engagement

In dynamic mode, the engine monitors game state — active combat, base threat level, unit losses, objective progress — and crossfades between mood categories automatically. Designers tag tracks by mood; the engine handles transitions. No scripting required for basic dynamic music.

Three layers of control for mission/mod creators:

LayerToolCapability
YAML configurationmusic_config.yamlDefine playlists, mood tags, crossfade timing, mode selection — Tier 1 modding, no code
Scenario editor (SDK)Music Trigger + Music Playlist modules (D038)Visual drag-and-drop: swap tracks on trigger activation, set dynamic playlists per mission phase, control crossfade timing
Lua scriptingMedia.PlayMusic(), Media.SetMusicPlaylist(), Media.SetMusicMode()Full programmatic control — force a specific track at a narrative beat, override mood category, hard-cut for dramatic moments

The scenario editor’s Music Playlist module (see decisions/09f/D038-scenario-editor.md “Dynamic Music”) exposes the full dynamic system visually — a designer drags tracks into mood buckets and previews transitions without writing code. The Music Trigger module handles scripted one-shot moments (“play Hell March when the tanks breach the wall”). Both emit standard Lua that modders can extend.

The music_mode setting defaults to dynamic under the iron_curtain experience profile and jukebox under the vanilla profile for RA1’s built-in soundtrack. Game modules and total conversions define their own default mode and mood-tagged playlists. This is Tier 1 YAML configuration — no recompilation, no Lua required for basic use.

Unit Voice System

Unit voice responses follow a specific pattern from the original game:

EventVoice PoolOriginal Behavior
Selection (first click)Select voicesPlays one random voice from pool. Subsequent clicks on same unit cycle through pool (don’t repeat immediately)
Move commandMove voices“Acknowledged”, “Moving out”, etc. One voice per command, not per selected unit
Attack commandAttack voicesWeapon-specific when possible. “Engaging”, “Firing”, etc.
Harvest commandHarvest voicesHarvester-specific responses
Unable to complyDeny voices“Can’t do that”, “Negative” — when order is invalid
Under attackPanic voices (infantry)Only infantry. Played at low frequency to avoid spam

Implementation: Unit voice definitions live in mods/ra/rules/units/*.yaml alongside other unit data:

# In rules/units/vehicles.yaml
medium_tank:
  voices:
    select: [VEHIC1, REPORT1, YESSIR1]
    move: [ACKNO, AFFIRM1, MOVOUT1]
    attack: [AFFIRM1, YESSIR1]
    deny: [NEGAT1, CANTDO1]
  voice_interval: 200     # minimum ticks between voice responses (prevents spam)

UX Fidelity Checklist

These are the interaction patterns that make RA play like RA. Each is a combination of input handling, visual feedback, and audio feedback.

Core Interaction Loop

InteractionInputVisual FeedbackAudio FeedbackSource Reference
Select unitLeft-click on unitSelection box appears, health bar showsUnit voice response from Select poolAll three sources agree on this pattern
Box selectLeft-click dragIsometric diamond selection rectangleNone (silent)OpenRA: diamond-shaped for isometric. Original: rectangular but projected
Move commandRight-click on groundCursor changes to move cursor, then destination marker flashes brieflyUnit voice from Move poolOriginal RA: right-click move. OpenRA: same
Attack commandRight-click on enemyCursor changes to attack cursor (crosshair)Unit voice from Attack poolCursor context from CursorProvider
Force-fireCtrl + right-clickForce-fire cursor (target reticle) on any locationAttack voiceOriginal RA: Ctrl modifier for force-fire
Force-moveAlt + right-clickMove cursor over units/buildings (crushes if able)Move voiceOpenRA addition (not in original RA — QoL toggle)
DeployClick deploy button or hotkeyUnit plays deploy animation, transforms (e.g., MCV → Construction Yard)Deploy sound effectDEPLOY() in original source
Sell buildingDollar-sign cursor + clickBuilding plays “make” animation in reverse, then disappears. Infantry may emergeSell sound, “Building sold” EVAOriginal: reverse make animation + refund
Repair buildingWrench cursor + clickRepair icon appears on building, health ticks upRepair sound loopOriginal: consumes credits while repairing
Place buildingClick build-queue item when readyGhost outline follows cursor, green = valid, red = invalid. Click to place“Building” EVA on placement start, “Construction complete” on finishRemastered: smoothest placement UX
Control group assignCtrl + 0-9Brief flash on selected unitsBeep confirmationStandard RTS convention
Control group recall0-9Previously assigned units selectedNoneDouble-tap: camera centers on group

The sidebar is the player’s primary interface and the most recognizable visual element of Red Alert’s UI. Three reference implementations exist:

ElementOriginal RA (1996)Remastered (2020)OpenRA
PositionRight side, fixedRight side, resizableRight side (configurable)
Build tabsTwo columns (structures/units), scroll buttonsTabbed categories, larger iconsTabbed, scrollable
Build progressClock-wipe animation over iconProgress bar + clock-wipeProgress bar
Power barVertical bar, green/yellow/redSame, refined stylingSame concept
Credit displayTop of sidebar, counts up/downSame, with income rateSame concept
Radar minimapTop of sidebar, player-colored dotsSame, smoother renderingSame, click-to-scroll

IC’s sidebar is YAML-driven (D032 themes), supporting all three styles as switchable presets. The Classic theme recreates the 1996 layout. The Remastered theme matches the modernized layout. The default IC theme takes the best elements of both.

Credit counter animation: The original RA doesn’t jump to the new credit value — it counts up or down smoothly ($5000 → $4200 ticks down digit by digit). This is a small detail that contributes significantly to the game feel. IC replicates this with an interpolated counter in ic-ui.

Build queue clock-wipe: The clock-wipe animation (circular reveal showing build progress on the unit icon) is one of RA’s most distinctive UI elements. ic-render implements this as a shader that masks the icon with a circular wipe driven by build progress percentage.

Verification Method

How we know the recreation is accurate — not “it looks about right” but “we verified against source”:

WhatMethodTooling
Animation timingCompare frame delay constants from EA source (#define values in C headers) against IC sequences/*.yamlic mod check validates sequence timing against known-good values
Palette correctnessLoad .pal, apply 6-bit→8-bit conversion, compare rendered output against original game screenshot pixel-by-pixelAutomated screenshot comparison in CI (load map, render, diff against reference PNG)
Draw orderRender a test map with overlapping buildings, units, aircraft, shroud. Compare layer order against original/OpenRAVisual regression test: render known scene, compare against golden screenshot
Sound mixingPlay multiple sound events simultaneously, verify EVA > unit voice > combat priority. Verify cooldown timingAutomated audio event sequence tests, manual A/B listening
Cursor behaviorFor each CursorContext (move, attack, enter, capture, etc.): hover over target, verify correct cursor appearsAutomated cursor context tests against known scenarios
Sidebar layoutTheme rendered at standard resolutions, compared against reference screenshotsScreenshot tests per theme
UX sequencesRecord a play session in original RA/OpenRA, replay the same commands in IC, compare visual/audio resultsSide-by-side video comparison (manual, community verification milestone)
Behavioral regressionForeign replay import (D056): play OpenRA replays in IC, track divergence pointsreplay-corpus/ test harness: automated divergence detection with percentage-match scoring

Community verification: Phase 3 exit criteria include “feels like Red Alert to someone who’s played it before.” This is subjective but critical — IC will release builds to the community for feel testing well before feature-completeness. The community IS the verification instrument for subjective fidelity.

What Each Phase Delivers

PhaseVisualAudioUX
Phase 0— (format parsing only)— (.aud decoder in ic-cnc-content)
Phase 1Terrain rendering, sprite animation, shroud, palette-aware shading, cameraCamera controls only
Phase 2Unit movement animation, combat VFX, projectiles, explosions, death animations— (headless sim focus)
Phase 3Sidebar, build queue chrome, minimap, health bars, selection boxes, cursor system, building placement ghostEVA voice lines, unit responses, weapon sounds, ambient, music (jukebox + dynamic mode)Full interaction loop: select, move, attack, build, sell, repair, deploy, control groups
Phase 6aTheme switching, community visual modsCommunity audio modsFull QoL toggle system