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

Performance Targets & Comparisons

Performance Targets

MetricWeak Machine (2 core, 4GB)Mid Machine (8 core, 16GB)Strong Machine (16 core, 32GB)Mobile (phone/tablet)Browser (WASM)
Smooth battle size500 units2000 units3000+ units200 units300 units
Tick time budget66ms (Slower, ~15 tps)66ms (Slower, ~15 tps)50ms (Normal, ~20 tps)66ms (Slower, ~15 tps)66ms (Slower, ~15 tps)
Actual tick time (target)< 40ms< 10ms< 5ms< 50ms< 40ms
Render framerate60fps144fps240fps30fps60fps
RAM usage (1000 units)< 150MB< 200MB< 200MB< 100MB< 100MB
Startup to menu< 3 seconds< 1 second< 1 second< 5 seconds< 8 seconds (incl. download)
Per-tick heap allocation0 bytes0 bytes0 bytes0 bytes0 bytes

Tick budget rationale (D060): The sim tick rate varies with game speed preset (Slowest 80ms / Slower 67ms / Normal 50ms / Faster 35ms / Fastest 20ms per tick). The Slower default runs ~15 tps (67ms). Tick time budgets target the default Slower speed for weak/mid/mobile/browser, and Normal speed (~20 tps, 50ms) for strong machines. Actual tick time must be well under the budget to leave headroom for faster speed presets.

Performance vs. C# RTS Engines (Projected)

These are projected comparisons based on architectural analysis, not benchmarks. C# numbers are estimates for a typical C#/.NET single-threaded game loop with GC.

WhatTypical C# RTS (e.g., OpenRA)Our EngineWhy
500 unit tickEstimated 30-60ms (single thread + GC spikes)~8ms (algorithmic + cache)Flowfields, spatial hash, ECS layout
Memory per unitEstimated ~2-4KB (C# objects + GC metadata)~200-400 bytes (ECS packed)No GC metadata, no vtable, no boxing
GC pause5-50ms unpredictable spikes (C# characteristic)0ms (doesn’t exist)Rust ownership + zero-alloc hot paths
Pathfinding 50 units50 × A* = ~2ms1 flowfield + 50 lookups = ~0.1msAlgorithm change, not hardware change
Memory fragmentationIncreases over game durationStable (pre-allocated pools)Scratch buffers, no per-tick allocation
2-core scaling1x (single-threaded, verified for OpenRA)~1.5x (work-stealing helps where applicable)rayon adaptive
8-core scaling1x (single-threaded, verified for OpenRA)~3-5x (diminishing returns on game logic)rayon work-stealing

Input Responsiveness vs. OpenRA

Beyond raw sim performance, input responsiveness is where players feel the difference. OpenRA’s TCP lockstep model (verified: single-threaded game loop, static OrderLatency, all clients wait for slowest) freezes all players to wait for the slowest connection. Our relay model never stalls — late orders are dropped, not waited for.

OpenRA numbers below are estimates based on architectural analysis of their source code, not benchmarks.

FactorOpenRA (estimated)Iron CurtainWhy Faster
Waiting for slowest clientYes — everyone freezesNo — relay drops late ordersRelay owns the clock
Order batching intervalEvery N frames (configurable)Every tickHigher tick rate makes N=1 viable
Tick processing timeEstimated 30-60ms~8msAlgorithmic efficiency
Achievable tick rate~15 tps30+ tps4x shorter lockstep window
GC pauses during tick5-50ms (C# characteristic)0msRust, zero-allocation
Visual feedback on clickWaits for confirmationImmediate (cosmetic)Render-side prediction, no sim dependency
Single-player order delay~66ms (1 projected frame)~50ms (next tick at Normal speed)LocalNetwork = zero scheduling delay
Worst-case MP click-to-moveEstimated 200-400ms80-120ms (relay deadline)Fixed deadline, no hostage-taking

Combined effect: A single-player click-to-move that takes ~200ms in OpenRA (order latency + tick time + potential GC jank) should take ~50ms in Iron Curtain at Normal speed — imperceptible to human reaction time. Multiplayer improves from “at the mercy of the worst connection” to a fixed, predictable deadline.

See 03-NETCODE.md § “Why It Feels Faster Than OpenRA” for the full architectural analysis, including visual prediction and single-player zero-delay.