Telemetry Outputs Overview
Information for Game Developers to Assist in Creating Telemetry Outputs in Games
Introduction
Modern video games, especially racing and simulation titles, often provide telemetry output – real-time data about the game’s state – to enhance the experience with external systems. Telemetry data (e.g., vehicle speed, orientation, acceleration, engine status) can drive motion simulators, power external dashboard displays, and control haptic transducers that add tactile feedback. By exporting this data from the game, developers enable a rich ecosystem of hardware and companion apps that elevate immersion and provide analytical insights. Achieving low-latency, high-frequency telemetry output is technically challenging, and two common inter-process communication methods have emerged as solutions: UDP network packets and shared memory-mapped files (MMF). This paper explores these telemetry output methods in depth, comparing their advantages and disadvantages, and examines how to structure telemetry data for optimal performance and compatibility. We also discuss the broad uses of telemetry in gaming and review case studies from existing games. The goal is to provide game developers with a clear understanding of telemetry integration techniques suitable for motion platforms, dashboards, and other peripherals.
Methodology
To compare telemetry output approaches, we analyze their communication mechanisms, performance characteristics, and integration complexity. Our methodology includes reviewing documentation and SDKs of popular simulation games, and formulating best practices for implementing telemetry in a game engine. We break down the process of adding telemetry output into clear steps, then evaluate how UDP and shared memory fulfill the requirements at each step. We consider data update rates, bandwidth, multi-client access, and synchronization needs. This approach is informed by both theoretical reasoning and real-world implementations found in games.
Steps to Implement Telemetry Output in a Game:
Define Telemetry Data and Frequency: Decide which game state variables (e.g., position, velocity, acceleration, gear, health) to output and at what rate. Many games use a fixed interval (e.g., 60 Hz) or tie updates to the physics tick.
Choose Output Method(s): Determine whether to use UDP network packets, shared memory, or both. This choice can be exposed in a configuration file or settings menu. For example, a config might allow
UDP_Output = True
orMemMap_Output = True
and specify target IP/port or shared memory name.Format the Telemetry Packet/Structure: Design a data format that includes all required telemetry fields in a compact form. Ensure consistent byte ordering and alignment for cross-compatibility. (Detailed techniques are discussed in a later section.)
Initialize Communication Channel: If using UDP, create a UDP socket and configure the destination IP and port (which may be user-defined, e.g.,
127.0.0.1:4123
for local output). If using shared memory, create or open a named memory-mapped file region accessible to other processes.Write/Send Data Each Frame: On each update tick, populate the telemetry structure with current values. For UDP, serialize the data into a byte buffer and send it via the socket. For shared memory, write the values into the memory region. Use timing (sleep or integration into the game loop) to achieve the desired output rate (e.g., 10 ms interval for 100 Hz output).
Ensure Thread Safety and Performance: If the game runs telemetry output on a separate thread, use synchronization or lock-free techniques to avoid race conditions when accessing game state. For shared memory, consider using sequence numbers or double buffering to prevent readers from catching partial updates (see Data Structuring section).
Testing and Verification: Use a telemetry client (or simple network listener) to verify that the data is received correctly and at the expected rate. Measure the performance impact on the game and adjust frequency or data content if needed to maintain smooth gameplay.
Following this methodology, we can evaluate how UDP and shared memory perform at each stage and how they meet the needs of various telemetry use cases. Next, we examine the two telemetry output methods in detail.
Useful Telemetry Values for Motion Simulators
Motion simulation software relies on a well-structured set of telemetry values to accurately reproduce in-game movements in the real world. Different types of simulation hardware—motion platforms, bass transducers, and force feedback systems—require specific types of data to create realistic motion cues. Below is a categorization of essential telemetry data needed for effective motion simulation:
Essential Values for Motion Simulators
These values are fundamental for any motion simulator to function properly, ensuring accurate real-time motion representation:
Packet ID: Ensures each data packet is uniquely identifiable and helps detect when data has changed.
Acceleration: Local accelerations in lateral, longitudinal, vertical directions.
Angular Velocity: Rotational speed around the pitch, roll, and yaw axes.
Orientation: Current orientation in pitch, roll, and yaw directions
Car/Racing-Specific Telemetry Values
These values are useful in racing games for tuning vehicle dynamics, replicating road effects, and enhancing immersion:
Speed: The vehicle’s forward velocity.
Suspension Position: Vertical movement of each suspension component (front left, front right, rear left, rear right).
Suspension Velocity: The rate of change of the suspension travel, useful for vibration feedback.
Road Surface Type: The type of material under each tire (e.g., asphalt, gravel, rumble strip), which can be used for dynamic haptic effects.
Gear Position: The current gear of the vehicle.
Engine RPM: The engine’s rotational speed, which can be used for simulating vibrations.
ABS Engagement: A flag or intensity value indicating the engagement of the anti-lock braking system.
Traction Control Engagement: Similar to ABS, used for simulating tire slip effects.
Flight-Specific Telemetry Values
These values are specific to flight simulators, allowing accurate representation of aircraft movement and behavior:
Altitude: The aircraft’s altitude or height above ground.
Air Speed: The speed of the aircraft.
Canopy Position: Represents whether the canopy is open or closed.
Landing Gear Position: The position of the landing gear, useful for motion cueing during takeoff and landing.
Air Brake Position: The percentage of deployment of air brakes.
Flap Position: Position of flaps to simulate lift adjustments.
Gun/Ammunition Status: Number of rounds left, useful for generating vibration effects when firing.
Including a motion-active or pause flag ensures that the motion platform correctly synchronizes with the game state, preventing unintended movement during menus or pauses. Additionally, well-structured telemetry ensures compatibility across different types of simulation hardware. The implementation of these values varies per game, but including them in a standardized format maximizes usability across different applications and devices.
Telemetry Output Methods
UDP Telemetry Output
UDP (User Datagram Protocol) is a lightweight network protocol commonly used for real-time data streaming. In a telemetry context, the game acts as a UDP sender, transmitting packets containing game state to one or more receiver applications. UDP is connectionless and does not require an established session between the game and the client. This makes it simple to implement – the game just “fires and forgets” a packet each update. UDP’s design trades reliability for speed: it does not guarantee delivery or ordering of packets
This means packets may be lost or arrive out of order, but in a continuous telemetry stream (e.g., 60 updates per second), occasional losses are usually tolerable. Real-time applications often prefer dropping packets over waiting for retries, so UDP is suitable for telemetry where the latest state is what matters most.
Advantages of UDP Telemetry:
Network Flexibility: UDP packets can be sent to any IP address, enabling telemetry to be received on the same machine or over a network. This is ideal for scenarios like using a separate PC, tablet, or microcontroller as a dashboard or for remote motion rigs. For example, Forza Motorsport’s “Data Out” feature allows sending telemetry to a remote IP or localhost, and flight simulators like X-Plane let multiple external devices receive data via UDP.
Ease of Implementation: Most programming languages and engines support UDP sockets with minimal code. There is no connection handshake; the game simply sends datagrams. This simplicity was noted by indie developers – UDP was “a lot easier” to get working quickly compared to memory mapping.
Low Overhead and Non-Blocking: Sending a UDP packet is generally non-blocking and incurs little CPU overhead. The game’s network stack handles the packet asynchronously. As long as the outgoing bandwidth is within limits, the impact on the game loop is negligible.
Broadcast/Multicast Capability: UDP supports broadcasting to a subnet or using multicast groups. This means a game can send one packet that multiple clients can listen to. Some games provide a broadcast mode for telemetry so that multiple applications can receive the data concurrently. For instance, the F1 series games have a “UDP Broadcast Mode” option – when enabled, the telemetry packet is broadcast so that more than one device can pick it up.
Platform Agnostic: UDP works across different operating systems and even consoles. On consoles, where running external processes is limited, UDP is often the only way to export telemetry off the device. (Project CARS 2, for example, used UDP on consoles as the sole telemetry mechanism, since shared memory is not viable off-device.)
Disadvantages of UDP Telemetry:
Unreliable Delivery: As noted, UDP does not guarantee delivery or order. If network conditions are poor or the CPU is under heavy load, packets might be dropped. Telemetry clients should be designed to handle missing frames gracefully (e.g., use the last known value or simply skip updates). Important one-time events could be missed unless an application-layer acknowledgment or redundancy is added (which is usually not done for performance reasons).
No Built-in Feedback: Since the game just sends data without a connection, it doesn’t know if a receiver is present or how many are listening. There is no automatic flow control. Developers may need to provide configuration for IP/port, as the game cannot inherently discover consumers. The F1 games, for example, require the user to input the target IP and port in the settings. If broadcast is used, any device on the network can receive the packets but also no feedback is given to the sender.
Data Size Constraints: While UDP can technically send packets up to ~65KB, in practice it’s best to keep telemetry packets relatively small (a few hundred bytes) to avoid fragmentation. Each UDP packet has some overhead (IP/UDP headers ~28 bytes) and large packets could be split by the network stack, increasing the chance of drop. Developers often design telemetry packets to fit within a single Ethernet frame for efficiency.
Security and Privacy: Exposing game telemetry over a network could pose security risks if not handled carefully. Broadcasted data could potentially be intercepted by unwanted listeners. However, for local network gaming setups this is usually a minor concern.
Complexity for Multiple Local Consumers: If two programs on the same PC want to get telemetry via UDP, it’s not straightforward because only one process can easily bind to a given UDP port in default mode. Using broadcast to
127.0.0.1
can allow multiple listeners with socket options, but it’s more complex than the inherent multi-access of shared memory. Some games circumvent this by allowing only one target IP and instead rely on that target to redistribute data if needed. In contrast, shared memory shines in this area (discussed below).
Despite these caveats, UDP is widely used for game telemetry. It works especially well for remote dashboards and apps – e.g., a smartphone app displaying speed and gear from a racing game – and for cross-computer motion simulators where the game PC sends data to a dedicated motion controller rig. Many high-profile games use UDP telemetry: the Codemasters F1 series outputs structured UDP packets for each frame of data (with adjustable send rates like 20Hz or 60Hz), and Forza Motorsport uses UDP at 60 fps for its motion “sled” data and dashboard info. These implementations show that UDP can deliver real-time performance needed for motion and displays, as long as packet loss rates are low on a local network.
Shared Memory-Mapped File (MMF) Telemetry Output
Shared memory-mapped files provide an alternative method for telemetry output by sharing a region of memory between the game and external applications. In this approach, the game creates a memory-mapped file (which may or may not have an actual file on disk) and writes telemetry data into it, while one or more external processes open the same memory mapping to read the data. The operating system ensures that all processes see the same memory content. Essentially, this is a form of high-speed Inter-Process Communication (IPC) that avoids the network stack altogether. Memory mapping is extremely fast – reading/writing to shared memory is as fast as normal RAM access since the OS maps the pages into each process’s address space.
A memory-mapped file used in this way is typically non-persisted, meaning it exists only in RAM (backed by the pagefile) and is not saved to disk. This is ideal for telemetry, which doesn’t need to be stored permanently, only conveyed in real-time. Applications can open a common named mapping to access the same data region. For example, a game might create a shared memory file named "GameTelemetry"
; any number of clients that know this name can open it and read from it.
Advantages of Shared Memory Telemetry:
Ultra-Low Latency and High Throughput: Shared memory is one of the fastest IPC methods. The game writes directly to a memory address and the client reads from memory – there is no OS context switch for data transfer or network protocol to process once the mapping is established. This allows very high update rates. For instance, iRacing uses a memory-mapped file to provide telemetry at up to 360 Hz for force feedback and 60 Hz for general telemetry, which multiple apps (like dashboards or analytics tools) can read simultaneously. The high update rate is possible because of the efficiency of shared memory – iRacing’s approach “provides telemetry data with a high update rate which can be read by multiple applications”.
Multiple Concurrent Readers: A major benefit of MMF is the ability to have multiple clients access the telemetry in parallel. Once the memory region is created by the game, many processes can map it (as long as they know the name and have permission). There is no additional cost per client – they are all reading the same memory bytes. This is superior to UDP in a single-machine scenario: with memory mapping, you could run a motion simulator driver, a dashboard app, and a data logger all at once, each simply reading the shared memory. Because the data is local and identical for all, this ensures consistency between tools.
Reliable Data Access: Unlike UDP, memory mapping does not drop data. The latest written values remain available in memory until updated next. Clients always read a coherent set of data (assuming proper synchronization is used during writes, discussed later). There is no concept of packet loss – if a client momentarily lags, it will just read an older snapshot of telemetry that is still in memory. This reliability is useful for software like tactile feedback systems that need every impulse, or for logging every frame of data.
No Network Overhead: Since data isn’t going through the network stack, using shared memory avoids any network-related delays or configuration. There’s no need to worry about IP addresses, firewalls, or broadcast domains. This can simplify setup for local-only setups. It also means telemetry doesn’t consume network bandwidth, which can be important if the game is online multiplayer (you wouldn’t want telemetry to steal bandwidth from the game’s networking).
Structured Data Access: The shared memory approach encourages a structured data layout (often a C/C++ struct). External apps can directly cast the memory to a struct and access fields, making for easy and CPU-efficient parsing. There’s no need to decode a byte stream or deal with endianness if all processes are on the same machine/architecture. Many developers provide a header file or library for the shared memory structure – e.g., Kunos (Assetto Corsa) documented a C struct for their telemetry shared memory, and third-party libraries in C# and Go have been built around those structures.
Disadvantages of Shared Memory Telemetry:
Limited to Local Machine: The foremost limitation is that shared memory works only for applications on the same system. External devices or networked computers cannot directly access the memory region. This means if you need telemetry on a separate PC or mobile device, shared memory alone is insufficient – you would need a relay application that reads the memory and then forwards it over the network. Some tools actually do this (e.g., a “telemetry bridge” that reads a game’s shared memory and emits UDP for remote clients), but it adds complexity. Games that need to support console or remote usage must implement another method (often UDP) for those cases.
Platform Specific Implementation: Setting up a memory-mapped file is OS-dependent. On Windows, one uses functions like
CreateFileMapping
andMapViewOfFile
, often via a Windows-only API. On Linux/Unix, one might use POSIXshm_open
/mmap
. Cross-platform engines can abstract this, but it’s more code to write and maintain compared to using a cross-platform socket library for UDP. Additionally, differences in how processes share memory on different OSes must be handled. (Many simulation games using shared memory are PC-only, which simplifies this issue. For example, Assetto Corsa and iRacing run on Windows and freely use Windows MMF APIs.)Synchronization and Concurrency: When using shared memory, the game and readers are accessing the same data asynchronously. Care must be taken to avoid race conditions where the reader might read half-updated data. Unlike UDP where each packet is self-contained, shared memory is like a continuously updating buffer. If the game writes to the buffer while a client is reading it, the client could see a mix of old and new values. To mitigate this, developers use techniques such as:
Double-buffering or ring buffers: iRacing, for example, uses a ring of 4 buffers and updates an index in the header to let readers know which buffer is the latest. The reader can then read an entire stable snapshot from one buffer while the game writes to a different buffer.
Sequence numbers: Another approach is to have a small header in the shared memory with a counter or timestamp. The game increments the counter each time it finishes updating the data. A reader can check that the counter is the same before and after reading the data to ensure consistency – if it changed, the reader knows an update occurred during read and should retry. (This pattern ensures the reader either gets a full old frame or a full new frame, not a half mix.) The iRacing SDK header contains an update tick count for this purpose.
These synchronization mechanisms require careful design. It’s extra complexity that UDP (with discrete packets) doesn’t have. However, many SDKs provide this logic so external developers just use the data safely.
Memory Overhead: The memory region for telemetry must be allocated in the game’s process. Telemetry data is usually not huge (hundreds of bytes to a few kilobytes), so this is trivial for modern PCs. But if a very large telemetry dataset is needed, it will consume part of the process address space. On 32-bit systems, large memory-mapped files can be an issue due to limited address space, though this is rarely a problem in practice for telemetry.
Versioning and Compatibility: If the game’s telemetry structure changes (e.g., new fields added in a patch), it might break compatibility with external apps reading the shared memory expecting the old layout. There’s no easy way to handle version mismatches except to include a version number in the memory or require the external app to match the game version. (In contrast, a network protocol could be versioned and possibly handled more dynamically.) Some games include a data version in the shared memory header – e.g., iRacing’s header has a version field (currently 2.0) so clients can check if they know how to interpret the data.
Overall, shared memory telemetry is excellent for local, high-performance integrations. A prime example is Assetto Corsa, which exposes a shared memory API for real-time data like speed, RPM, gear, car position, etc., used by many community apps. Another is iRacing, whose sophisticated shared memory system allows apps ranging from strategy dashboards to VR motion platforms to all concurrently tap into the simulation state. When only one application needs the data, shared memory and UDP are both viable; but when many do, shared memory’s one-write/multiple-read efficiency is a clear advantage. Consequently, some PC simulators even offer both methods – for instance, Automobilista 2 (PC) provides a shared memory interface (inherited from Project CARS) and a UDP output option, catering to different use cases.
Data Structuring Techniques for Telemetry
Designing the format of telemetry data is as important as choosing the transport. A well-structured telemetry data format ensures compatibility between the game and external tools, and optimal performance in transmission and parsing. Key considerations include binary layout, data types, byte ordering, update atomicity, and extensibility. In this section, we outline best practices and technical details for structuring telemetry data for both UDP and shared memory outputs.
Binary vs. Text Data
Game telemetry should almost always be sent in a binary format rather than human-readable text (like JSON or XML). Binary formats are far more compact and faster to produce/consume, which is critical at high update rates. Each value (integer, float, etc.) is encoded in fixed-size binary representation. For example, a 32-bit float will be 4 bytes; an integer (range-limited) might be 1 or 2 bytes. In contrast, sending the same value as text could take many bytes (plus requires parsing). Nearly all known implementations (Forza, F1, iRacing, etc.) use binary telemetry structures. Forza’s documentation defines fields like F32
(32-bit float) and U32
(32-bit unsigned int) in the packet. The F1 series also packs all data without any delimiter overhead. The efficiency gain is significant: binary packing minimizes packet size (important for UDP to avoid fragmentation) and ensures quick memory copy for shared memory.
Tip: Make sure to align and pack the data in a consistent way. Some languages or compilers might insert padding bytes for alignment (to align fields to 4 or 8-byte boundaries). It’s often wise to explicitly define the packing or use fixed-size types and ordering that minimize padding. Codemasters explicitly state that in F1 telemetry “all data is packed” with little-endian encoding, and they provide a C-struct layout to enforce that. Using #pragma pack(1)
in C/C++ or equivalent ensures the struct in memory matches the intended byte layout for sharing or sending.
Data Types and Precision
Decide on an appropriate data type for each telemetry field:
Floating-point (float/double): Most continuous values like speed, acceleration, orientation are best as floats (
float32
) for efficiency. A float32 gives sufficient precision for game units (e.g., speed to 0.1 km/h, position within a world). Double precision (float64
) is usually unnecessary and doubles the size, so use it only if there’s a clear need for extreme precision (rare in real-time telemetry).Integers: For discrete values like gear, lap count, player health, an integer is suitable. Often small ranges apply, so you can use small widths: e.g., gear can be a signed 8-bit (
int8
) if it ranges from -1 (reverse) to 10; flags or booleans can be bitfields or 8-bit. Using a smaller type saves space, but ensure the receiving side knows how to interpret it.Normalized or Fixed-Point Values: In some cases, games normalize a value to a 0–1 range or similar (e.g., normalized tire wear or throttle position) and send it as a float or as an integer percentage. This can reduce the need for high precision. For example, Forza’s “Sled” format sends some values like suspension travel as normalized floats between 0 and 1.
Strings and IDs: If telemetry needs to include strings (e.g., car model name, track name), it’s often better to avoid putting long strings in the high-frequency data. Instead, use an ID or index. Static or rarely-changing info can be separated (discussed below). If a string must be included, consider a fixed-size char array in shared memory (e.g., 64 bytes for track name) or a reference number that external apps can map to actual names.
Endianness: For shared memory on the same machine, endianness is not an issue since both processes use the host’s byte order (usually little-endian on modern PCs). But for UDP, the server and client could be different architectures. A safe practice is to choose an endianness and stick to it (network protocols traditionally use big-endian, “network byte order”). However, many game telemetry protocols simply use the native little-endian for convenience, expecting that most clients will be on PC as well. Codemasters explicitly note their UDP is little-endian, and Forza’s data is effectively little-endian given it’s just a memory dump of floats/ints. If you expect cross-platform clients (say a microcontroller that is big-endian), you might either document the format as little-endian or convert multi-byte values to network byte order before sending. Consistency is key – document the choice in your telemetry spec so developers of client apps know how to interpret the bytes.
Structuring Static vs Dynamic Data
Not all telemetry data changes every frame. It’s useful to distinguish dynamic telemetry (e.g., vehicle position, speed, forces) from static or semi-static data (e.g., track name, vehicle type, maximum RPM, player name). Static data can be large (think of a string for track name, or an array of curves for engine power) but doesn’t need to be sent or updated at high frequency.
Technique: Separate the data into multiple structures or packets by update frequency. For instance, Assetto Corsa’s shared memory API uses three sections: Static Info (car/track details, updated only on session change), Graphics (lap times, current lap, flags, updated occasionally), and Physics (high-rate data like speed, G-forces, updated every few ms). The game updates each at appropriate rates. External apps can read all sections but focus on the physics section per frame and check static section when a new session starts. This segmentation ensures that the high-rate memory region remains small and efficient, while large strings or arrays that rarely change don’t bloat each update.
In a UDP scenario, a similar approach is to define different packet types. Codemasters F1 games do this: they have separate UDP packet structures for motion data, car status, lap data, session info, etc., each identified by a packet ID in a common header. The game sends the motion packets every frame (for motion rigs), car status perhaps less frequently, and session info only when changed. Each packet type includes a header with a packet format version and identifier so that the client knows how to parse it. This multi-packet approach is efficient and extensible; clients can subscribe to or process only what they need. The downside is increased complexity – clients must assemble data from multiple packet streams. Simpler games might opt for one monolithic packet containing everything, which is easier to implement but can waste bandwidth on repeated static info. The choice depends on the data size and use cases: if the static data is small or you don’t mind the repetition, a single packet format is okay; otherwise consider a layered approach.
Atomic Updates and Buffering
As mentioned in the shared memory discussion, ensuring that clients read a coherent snapshot is crucial. Here are some structuring tips to support atomicity:
Include a Sequence Number or Timestamp: Make the first field of your telemetry struct a counter (
uint32
that increments each update) or a timestamp (ms or tick count). For UDP, this helps clients detect out-of-order or missed packets (if a sequence number is skipped, a packet was lost). For shared memory, this can be paired with a duplicate at the end of the struct. For example, putseq
at start and end; the writer does:seq++
at start, write all data, then copyseq
to the end. A reader checks if the start and end sequence match; if not, it read during an update and should retry. This pattern ensures atomic read or detect-and-retry. Even a single sequence at the start can help a reader know if data changed mid-read (by comparing before/after values of some stable field).Double Buffering: Allocate two identical telemetry structs in memory (or more, as iRacing does with four). Maintain a flag which is the “current” buffer. The game writes to the non-current buffer, then flips the flag when done. Readers always read from the buffer indicated as current. This way, writes never happen to the buffer readers are actively using. The overhead is doubling the memory usage for telemetry (still trivial size) and needing to handle the swap indicator. In shared memory, one could implement this by making the memory region twice as large: e.g., offset 0 is buffer A, offset N is buffer B. A header contains a boolean or index indicating which is latest.
Padding and Alignment for Atomic Writes: On some architectures, reading or writing certain sizes can be atomic if properly aligned (e.g., 64-bit values on 64-bit alignment). This is a low-level consideration and usually one cannot guarantee the whole struct write is atomic (it’s typically way larger than CPU word). So it’s safer to use the software sequence checks as above.
Compatibility and Versioning
When structuring telemetry, plan for future changes. The format might need new fields as the game evolves (new features, more sensors, etc.). To maintain compatibility with older client software, consider:
Including a Format Version: If using a header in your data (either as part of a UDP packet or at a known location in shared memory), include a version number. For UDP, Codemasters includes
packetFormat
(e.g., 2023) and a game version in each packet’s header. In shared memory, you can have adataVersion
field in the header (e.g., iRacing’s header shows “data version (currently 2.0)”). External apps can read this and adjust if they support multiple versions, or at least warn if mismatched.Don’t Reorder Existing Fields: If you add new fields, do so at the end of the structure (or in reserved padding space if you planned any). Reordering or removing fields will confuse clients expecting the old order. By appending, older clients might read fewer bytes (which is fine, they just won’t use the new data) if the system allows that, or they’ll at least not misinterpret data.
Documentation: Provide documentation of the telemetry structure to developers. Many games release an SDK or a document describing each field, unit, and data type. Clear documentation helps third-party software align with the game’s output precisely. As an example, Forza published an official document listing each field in their “Sled” and “Dash” packets with types and descriptions. Codemasters published their F1 UDP spec on forums and in a PDF which has tables for each packet type and field. These docs often include notes on units (e.g., speeds in m/s or km/h, angles in radians or degrees) which are critical for correct use of the data.
By carefully structuring telemetry data with these techniques, developers ensure that the data is efficiently transmitted, accurately interpreted, and scalable for future needs. A well-designed telemetry format, coupled with the appropriate transport (UDP or shared memory), lays the foundation for a variety of applications to leverage game data in real time.
Uses of Telemetry Data in Gaming Applications
Game telemetry data can be put to use in a wide array of applications that enhance gameplay, realism, and user engagement. Below we discuss the major use cases and how they leverage the telemetry outputs:
Motion Simulators (6-DoF Platforms & Racing Rigs): Telemetry is the lifeblood of motion platforms – these are setups where the seat or an entire cockpit moves in sync with the game to simulate acceleration, bumps, and turns. Key telemetry outputs here are the vehicle’s acceleration along axes (surge, sway, heave) and rotation (pitch, roll, yaw). Motion software (like DR Sim Manager, SimHub Motion, SRS, SimTools, or FlyPT Mover) takes these telemetry values and drives actuators to tilt or move the rig accordingly. For instance, a sudden deceleration (negative surge) from braking causes the platform to pitch forward, simulating the feeling of braking. Games outputting telemetry for motion will typically provide a specific packet or dataset tuned for motion cues – e.g., Forza’s “Sled” format is designed specifically for motion sleds. With accurate telemetry, a motion rig can replicate road texture (via high-frequency vibration cues from suspension telemetry) and large movements for cornering forces. This greatly enhances realism for racing and flight simulation, providing physical feedback that the game alone cannot give.
Dashboards and Gauges: Many gamers use external displays or even physical gauge clusters to show game information. Telemetry data can drive digital dashboards on tablets/phones or USB devices showing speedometers, tachometers, gear indicators, fuel level, tire temperatures, and more. In sim racing, applications like SimHub and DashPanel use telemetry from games to render custom dashboards. Some enthusiasts even connect real car dashboards or build DIY gauge clusters that move actual needles based on telemetry. For example, a telemetry feed provides engine RPM, and an Arduino or similar device drives a servo motor for a tachometer dial. Racing games also output status lights (shift lights, warning lights) via telemetry which these external dashboards can replicate with LEDs. Because dashboards are primarily visual, they can tolerate slightly lower update rates (20–60 Hz is usually fine), but they benefit from the breadth of data (everything on the HUD). Games like F1 series provide all HUD data in their telemetry stream, enabling players to turn off the in-game HUD and use a custom display instead.
Transducers and Haptic Feedback: Beyond large motion rigs, smaller haptic devices like bass shakers (example: the ButtKicker) or rumble motors can use telemetry to generate tactile feedback. These transducers are often mounted to a seat or wheel to provide vibrations corresponding to engine rumble, road bumps, or tire slip. Telemetry that is useful for this includes engine RPM (for engine vibration), suspension impact or wheel slip (for bumps and skids), and curbstone hits. Software such as SimHub’s ShakeIt or SimVibe takes telemetry and translates it into frequency signals sent to transducers. For instance, as the car’s RPM rises, the software outputs a harmonics that make the bass shaker vibrate like an engine. When the car runs over a rumble strip, a burst of vibration is generated corresponding to that wheel’s telemetry data. These systems greatly enhance immersion by engaging the sense of touch – the player feels the game’s events. Telemetry is critical here because the feedback must be synced with game events (audio alone is sometimes used for this, but telemetry is more direct and customizable).
Analytics and Telemetry Logging: Telemetry data is invaluable for performance analysis in both competitive gaming and single-player improvement. Racing sims and flight sims often allow exporting telemetry to files or real-time streams that can be recorded. Tools like MoTeC (for racing) or Tacview (for flight combat) can ingest telemetry logs to plot graphs of speed, throttle, G-forces, etc. This helps players analyze their performance (e.g., braking points, racing lines, consistency) and make improvements. In eSports or competitive scenarios, telemetry can be used by teams to monitor their players in real time (e.g., a race engineer watching a driver’s tire temperatures and fuel via a telemetry feed to strategize pit stops). Some games output telemetry in industry-standard formats (like MoTeC’s LD or IBT logs) for compatibility with professional analysis software. Even when not for professional use, hobbyists enjoy reviewing their lap telemetry to compare with friends or overlay two laps. The use case of logging typically isn’t as time-critical (since it’s often post-processing), but it benefits from telemetry outputs by the game, sometimes at higher resolution than what the on-screen HUD shows.
AI and Training Tools: With the rise of machine learning, some advanced users or researchers use game telemetry as a data source to train AI models or to create driver assist tools. For example, one could feed telemetry into a machine learning model to predict the best driving line or to build an AI that can drive the car. Or use telemetry in real time to give live feedback to the player (like a virtual coach that says if you’re carrying enough speed through a corner, by comparing telemetry to a reference). These applications typically consume telemetry via shared memory or UDP and then run algorithms on the data. The advantage is that telemetry provides a quantitative, programmatic view of the game state, which is necessary for any computational analysis or AI logic.
Streaming and Spectator Overlays: In broadcast or streaming of gameplay, telemetry allows creation of rich overlays showing information to viewers. For example, in a racing broadcast, telemetry from each car (speed, gear, gap to leader, etc.) can be shown on stream. Games like iRacing and F1 have been used in official eSports broadcasts where the production team pulls telemetry for live graphics. Even individual streamers use tools that read telemetry to display extra info on their stream (like an overlay of the car’s dashboard or a track map with positions). This enhances the viewer experience. Because spectator uses might involve multiple cars, the telemetry feed might include data for all players in a session (some games do output all cars’ data when in spectator mode or with special settings). This is more data and might use more bandwidth or memory, but since it’s one way to the broadcast software, it’s feasible with UDP in broadcast mode or a larger shared memory.
Augmented Reality (AR) or Extended Displays: Experimental uses of telemetry include AR glasses showing a virtual HUD synchronized to the game, or lighting systems that change based on game state. For example, a DIY project might use telemetry to control ambient LED lighting in the room that matches the game (flashes red when braking hard, etc.). Or AR headset apps that draw racing lines or braking markers in real-world view using telemetry as input. These creative applications show how telemetry data can break out of the screen and integrate the game with the player’s environment.
Force Feedback Enhancement: While steering wheels and joysticks often get force feedback directly from the game’s internal physics, there are cases where telemetry is used to generate feedback for custom hardware. For instance, a custom built flight simulator cockpit might use telemetry for controlling hydraulic cylinders or force-feedback instruments. Some motion software also injects additional effects to a wheel or pedal based on telemetry (like adding a road vibration effect even if the game’s native FFB is limited). This again leverages the raw data the game provides.
In summary, telemetry data is extremely versatile. It allows the game’s internal state to be experienced in new modalities (motion, touch, external visuals) and to be analyzed or enjoyed outside the game’s own UI. By supporting telemetry output, developers essentially open their game to a wide range of extensions that passionate users and third-party developers will create – from serious racing simulators with full-motion cockpits to creative home-brew projects. This greatly extends a game’s functionality and can make it the center of an ecosystem of peripherals and tools.
Case Studies: Telemetry in Existing Games
To ground the discussion, we examine how some existing games implement telemetry output, highlighting their chosen methods and usage scenarios:
Forza Motorsport (2017 and 2023): The Forza series introduced a feature called “Data Out” to support motion rigs and companion dashboards. Forza uses UDP telemetry exclusively. In Forza Motorsport 7 and the new Forza Motorsport (2023), players can enable Data Out in the settings and specify an IP address (including localhost) and port. The game then streams UDP packets at 60 Hz. Notably, Forza provides two packet formats: “Sled” and “Dash.” The Sled format is tailored for motion (containing the core physics and 6-DoF data needed to drive a motion sled) while the Dash format contains everything in Sled plus extra data useful for dashboards (like additional car status info). Both are binary packed structures of around 300 bytes. Forza’s approach shows a clear design for different use cases – if you only care about motion, you use the smaller Sled packet; if you want all data, use Dash. By using UDP, Forza allows telemetry to be received on a separate device (common for people who run a dash on a tablet, or motion platform controllers with their own PC). It’s a one-way broadcast; external apps do not send anything back. This system has been successful, with many community apps integrating Forza telemetry for custom dashboards and motion rigs.
Codemasters F1 Series: The F1 games (F1 2018 through F1 2023, and beyond) have a robust UDP telemetry system. Users can turn on UDP Telemetry in the settings and configure the UDP send rate (various rates from 10Hz up to 60Hz) and the format (year-specific format selection, e.g., 2023 or “Legacy” for older data structure). There is also a UDP Broadcast Mode toggle – when enabled, the game will broadcast the packets so multiple devices can receive them. The telemetry stream includes multiple packet types: motion data for the player’s car, telemetry for all cars, event notifications, lap times, etc., each with a common header. For example, the motion packet contains detailed physics for the player car (suspension positions, velocity, G-forces) ideal for motion simulators, and is about 1349 bytes in F1 2021 format. Other packets (e.g., Car Status) contain tire wear, damage, temperatures for all cars, useful for strategy dashboards. The game cycles through sending these packets in a sequence each frame. Because it covers all cars and many parameters, the F1 telemetry is quite comprehensive – it can drive motion rigs, LEDs (for shift lights), dashboards, and more. The presence of a broadcast option and adjustable rate shows consideration for different setups: a user with only one device might keep broadcast off for efficiency, whereas a streamer with multiple telemetry consumers can turn it on. The F1 telemetry has become a standard of sorts in the sim racing community, with countless applications and devices supporting it (from simple HUDs to full pitwall engineer apps).
Assetto Corsa (Kunos Simulazioni): Assetto Corsa (AC, 2014) took a different route by using shared memory for telemetry. The game creates a shared memory mapping that contains several structured sections (as mentioned earlier: static info, graphics, physics) and updates these every few milliseconds. AC does not have a built-in UDP output (though third-party tools can relay the shared memory to UDP if needed). The shared memory approach allowed many PC applications to interface with AC easily. For instance, the popular SimHub dashboard software reads AC’s shared memory to show telemetry on external displays. Another example is motion: the developers provided example code for reading the memory and converting it to motion cues. Since AC’s shared memory is well-documented (with an official reference of all fields), developers have used it for everything from telemetry logging to DIY data-driven projects. The limitation, of course, is that the telemetry consumer must run on the same machine (or one needs a forwarder). But on PC, this was acceptable and the very low latency data made it suitable for even delicate tasks like high-fidelity motion feedback and accurate dashboard syncing. Assetto Corsa Competizione (ACC), the newer title by Kunos, also provides a shared memory interface (with some differences in structure) and additionally can output over UDP (ACC has an option for UDP telemetry for certain use cases). This shows a trend of providing both methods: e.g., ACC shared memory for local apps (like motion software running on the same PC) and UDP for remote apps or when running on consoles (ACC on consoles likely uses UDP externally, similar to PCars engine heritage).
iRacing: As a PC-centric simulation, iRacing is a poster child for shared memory telemetry done right. It runs a background service (the iRacing SDK) that creates a memory-mapped file
Local\\IRSDKMemMapFileName
in Windows, which clients can open. The design includes a header with metadata and multiple buffers as previously described. iRacing’s telemetry output is extremely granular – it not only streams the kind of data other games do (speeds, orientation, etc.) but also many internal variables (like tire loads, temperatures at different points on the tire, damage states, etc.). Users can also save this telemetry to disk in.ibt
files for later analysis. Multiple apps can attach to the live telemetry feed simultaneously, which many iRacers use: for example, one might run the JRT timing screen, an external dashboard, a spotter app, and a motion seat all at once, all drawing from iRacing’s shared memory. The system runs at the sim’s internal tick rate (which is often 60 Hz for physics), ensuring timely data. iRacing’s commitment to an open telemetry interface (with documentation and sample code) has made it a favorite among sim hardware makers; almost any sim racing gadget you buy will list iRacing support due to how accessible its telemetry is. This case underlines the power of shared memory for a rich ecosystem – iRacing’s simulation is augmented by countless third-party utilities that rely on its telemetry, from simple VR overlays to entire driving school systems analyzing a driver’s telemetry.Project CARS / Automobilista 2: Project CARS (Slightly Mad Studios) originally had both shared memory and UDP output (with a user setting to choose the mode). Shared memory was often preferred on PC for its detail, while UDP was used for consoles or remote apps. Project CARS 2 moved towards a unified approach where even on PC the recommended method became UDP (with an updated format called “UDP 2.0”), partly to keep parity with consoles. However, the PC version still had the legacy shared memory for those who enabled it. Automobilista 2, which is based on the Project CARS 2 engine, inherits this. The developers of AMS2 provided an example app and header for the shared memory in the game’s install (for PC users) and pointed to the UDP definitions for network output. Users have noticed that in single-player, using shared memory was fine, but for multiplayer, sometimes external tools preferred UDP due to some quirks (one forum note mentioned SimHub working with shared memory offline but needing UDP in online races). This highlights that depending on how the game’s threading works (maybe in multiplayer the shared memory update had issues), having both options is useful to fall back on one or the other. Ultimately, these titles show that supporting multiple telemetry methods can cover more user scenarios – PCARS/AMS2 serve both PC hobbyists (shared memory) and cross-platform needs (UDP) within one game.
Flight Simulators (X-Plane): As a contrast to racing, flight sims also output telemetry (often called “data output” or “datarefs”). X-Plane 11, for example, allows users to enable a host of data channels that will be continuously sent via UDP to a given IP/port. X-Plane supports dozens of data sets (attitude, engine stats, control surface positions, etc.) and even allows multiple processes to get data by adding them as data output destinations. This is used by home cockpit builders to drive physical instruments (like altimeters, variometers, etc.), and by researchers interfacing X-Plane to hardware. Microsoft Flight Simulator (2020 and 2024) and Prepar3D uses a different approach (SimConnect API, which is more like a client-server API rather than raw telemetry). The key takeaway is that even outside of racing, telemetry is considered vital for serious simulation usage and training setups.
Each of these case studies reinforces the general points made earlier: Forza and F1 demonstrate the effectiveness of UDP for broad compatibility (including consoles and remote devices) and how to structure multi-purpose data streams; Assetto Corsa and iRacing showcase the power of shared memory for high-fidelity, multi-app integration on PC; and games like Project CARS/AMS2 illustrate the trade-offs and the value of offering both methods. Across the board, telemetry has enabled vibrant communities to extend these games in creative ways, from high-end simulators to DIY projects, validating the effort developers put into providing this data.
Conclusion
Telemetry output is a key technical feature that bridges a video game with the external world of simulators, displays, and devices. Through our exploration, we have seen that there are two primary methods to deliver telemetry from game to client: UDP networking and shared memory-mapped files, each with distinct strengths. UDP offers flexibility in reaching remote systems and is simple to implement across platforms, at the cost of unreliable delivery and slightly higher latency. Shared memory delivers unparalleled speed and supports multiple local clients with ease, but is confined to a single machine and demands careful synchronization.
A well-designed telemetry system often takes inspiration from both approaches. In fact, many game developers choose to implement both UDP and shared memory concurrently to reap the benefits of each. As suggested by developers in the simulation community, providing both options makes the system very flexible – users can pick what suits their setup best. For example, a game can output via shared memory for PC apps like motion software and simultaneously send UDP packets for a tablet dashboard on Wi-Fi. The overhead of doing so is low (since the game is mostly formatting data and either writing to memory or sending a packet). By toggling these outputs via a config, even users who need one or the other can be satisfied.
Technical best practices for telemetry include using efficient binary structures, separating static and dynamic data, ensuring thread-safe updates (with sequence numbers or double buffers), and documenting the format for third-party developers. Including versioning info in the telemetry data helps maintain compatibility as the game evolves. It’s also crucial to consider the frequency of updates – a balance between smooth data (higher Hz for fast response, e.g., motion) and CPU/network overhead. Many games settle around 60 Hz (matching frame or physics rate) for critical data, and lower for less critical streams. The ability for the user to configure the rate (as F1 games do) is a plus for adjusting to different hardware capabilities.
From motion platforms that literally move the player, to companion apps that display dashboards or flash shift lights, to analytics tools that parse driving lines, the uses of telemetry are diverse and continually expanding. By exposing telemetry, game developers effectively invite an ecosystem of extensions and mods that can greatly enhance the player’s experience and allow personalized setups. This is especially important in simulation genres where many players invest in custom hardware. The success stories from Forza, F1, Assetto Corsa, iRacing, and others make it clear that robust telemetry support can be a differentiator that appeals to the enthusiast community.
In conclusion, implementing telemetry output (via UDP, shared memory, or both) is a highly rewarding engineering effort for a game. It requires careful planning of data structures and consideration of concurrency and networking issues, but the result is a game that can interface with almost anything. As hardware like VR, AR, and haptic devices continue to advance, having a reliable telemetry interface ensures a game can integrate into future technologies seamlessly. Telemetry is what transforms a game from a closed box into a platform that interacts with the physical world – providing not just entertainment on a screen, but an experience that can be seen, felt, and analyzed in countless ways. The technical insights and examples discussed in this paper aim to guide developers in creating telemetry systems that are efficient, extensible, and capable of driving the next generation of immersive gaming peripherals.
References
Forza Motorsport Data Out – https://support.forzamotorsport.net/hc/en-us/articles/21742934024211-Forza-Motorsport-Data-Out-Documentation
Codemasters F1 24 UDP Specification– https://forums.ea.com/discussions/f1-24-general-discussion-en/f1-24-udp-specification/8369125
Assetto Corsa Shared Memory Documentation – https://www.assettocorsa.net/forum/index.php?threads/shared-memory-api-documentation.28720/
X-Simulator - Devs - how to add Telemetry output into a game + Unity and UE4 code - https://www.xsimulator.net/community/faq/devs-how-to-add-telemetry-output-into-a-game-unity-and-ue4-code.287/
Last updated