Every major racing simulator speaks its own dialect.
iRacing exposes a memory-mapped file updated at 60 Hz with custom variable headers. Assetto Corsa Competizione writes to three separate Windows shared memory pages split across physics, graphics, and static metadata. Le Mans Ultimate and Automobilista 2 have their own memory layouts inherited from different simulation engines.
When building companion software like APEX or venue systems like CHRONO, supporting multiple titles can easily turn into a mess. If you take the obvious route, your UI code quickly fills with conditional checks for every game.
The cost of frontend conditionals
Most multi-sim tools start simply enough: an if (game === 'acc') here, an else if (game === 'iracing') there. Within a few months, the codebase becomes fragile.
The differences between simulators are small, subtle, and frustratingly inconsistent:
- Units and scales: One title reports tyre temperatures in Kelvin; another uses Celsius. One tracks pressure in bar, another in PSI, and a third in kilopascals.
- Gear indexing: In one simulator, gear
0is Neutral and1is First gear. In another,0is Reverse,1is Neutral, and2is First. - Session flags: How yellow flags, safety cars, and cut-track warnings are surfaced varies from one physics engine to the next.
Letting these discrepancies bleed into UI components means every new view you build risks breaking in at least one game.
Normalizing at the OS boundary
We solved this by writing a native Rust library that sits right at the operating system boundary. It binds directly to the running simulator's shared memory pages and translates raw byte structures into a single clean stream before anything else sees it.
Downstream applications never ask which sim is currently active. Whether it is our in-sim overlay in APEX or venue timing screens in CHRONO, screens receive standard units (Celsius, bar, km/h) and consistent gearbox states. Because this translation runs in compiled native code with stack allocations, it processes incoming ticks without causing garbage collection pauses or frame drops on the rig PC.
Replay testing without turning a wheel
A great side effect of normalizing telemetry early was how it changed our testing workflow. Developing sim racing companion software normally requires sitting in a rig, launching the simulator, and driving laps just to trigger a specific timing edge case.
With a single canonical data structure, we built recording and playback directly into the telemetry layer. We can record a stint from iRacing or ACC, save the raw binary log, and replay it on a laptop during development at normal or accelerated speed.
Our frontends, CHRONO broadcast displays, and APEX in-sim HUD overlays can run against realistic race sessions without anyone needing to sit in a bucket seat. That same pipeline feeds our cloud sync pipeline.
Keeping the stack clean
Translating simulator quirks at the boundary keeps the rest of the software simple. When frontend components only need to understand one data contract, you can build new features, overlays, and broadcast screens without worrying about which sim the driver chooses to launch next.
If you are working on sim racing hardware or platforms that need reliable data across multiple titles, talk to us about what we can build together.




