Skip to content
Collision prevention for OpenTTD (
C++ C Squirrel Objective-C++ Objective-C HTML Other
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.


Type Name Latest commit message Commit time
Failed to load latest commit information.

Transport Tycoon Demo

OpenTTD collision prevention using Hazelcast Jet.


OpenTTD (Open Transport Tycoon Deluxe) is an open source simulation game based upon the popular Microprose game "Transport Tycoon Deluxe", written by Chris Sawyer. A player builds his empire by transporting people and material between cities and industries.

This demo extracts real-time vehicle data from OpenTTD and analyses it using Hazelcast Jet data processing engine. The analytical job in Jet predicts train collisions. A pedicted collision information is pushed back to the running OpenTTD game to stop the affected trains (and save lifes:-).

A goal is to demonstrate the possibilities of an in-memory streaming for a real-time (sub-second) processing on a large data streams.

Watch a demo recording

Watch the demo


The source code of OpenTTD was changed to export vehicle position data. This approach was inspired by Using OpenTTD to create a realistic data stream blog. For each vehicle, the changed game code exports a JSON record with the telemetry approximatelly 30x per second.

JSON record example:

	"Name":"Train 4",
	"X position":1880,
	"Y position":1480

The position records are sent to a the Hazelcast Jet cluster to be analysed. In-memory data structures of Hazelcast Jet are used for reliable low-latency messaging. OpenTTD is implemented in C++ and Hazelcast comes with C++ client. This allows a straightforward data extraction.

The message buffer is consumed by the analytical job residing in the Hazelcast Jet cluster. The analytical job observes the position updates for each vehicle. It predicts the vehicle position in next second based on a vehicle position one second ago and a vehicle position now (it simply extends it's motion vector). Collision is predicted if there is an intersection between two or more vectors.

Prediction visualised

This happens each 50 milliseconds. Higher resolution isn't possible as the frequency of the vehicle data is just 30 Hz (vehicle position update arrives each 30-40 millisecond for each vehicle).

The analytical job is implemented using the Pipeline API of Hazelcast Jet (see the code).

If a collision is detected, it's recorded to a K-V store in Hazelcast Jet. This store allows an event-driven programming. Storing new collision triggers an event that is delivered to the C++ client in OpenTTD. OpenTTD can stop the affected vehicles.




In-memory approach to meet the low-latency requirements (collision detection + train stop duration must happen within 1 second - prediction forecast interval). Possible thanks to combining in-mem messaging, processing, event-driven programming.

Scaling to handle millions of events per second to support many game instances

Fault-tolerance using in-memory replication.


openttd directory contains a fork of OpenTTD 1.9.2 source code extended with Hazelcast 3.11 C++ client to export the data and handle the collision events. See the openttd/src/log_events.h and openttd/src/log_events.cpp for the Hazelcast integration.

vehicle-telemetry-analytics contains the messaging and the analytical infrastructure: input message buffer, stream processing cluster with the analytical job, K-V store for the detected collisions

game-positions contains the saved OpenTTD game positions that can be used for a demonstration


Prerequisites of OpenTTD are covered in next section.

Building the Application

To build the Vehicle Telemetry Analytics, run:

cd vehicle-telemetry-analytics
mvn clean package

To build OpenTTD, please follow the Compiling instructions. For troubleshooting, please follow the Compiling OpenTTD guide.

Running the Application

Start Jet (Collision Detection is disabled now):

cd vehicle-telemetry-analytics
mvn exec:java -Dexec.mainClass="biz.schr.StartJet"

Start OpenTTD:

cd openttd/bin

Load the game position from game-positions/demo1.sav. Start all deployed trains by hitting the green flag from the train overview window and see the tragedy.


Start the collision detector within Jet:

cd vehicle-telemetry-analytics
mvn exec:java -Dexec.mainClass="biz.schr.StartCollisionDetector"

Reload game position, launch trains and let Jet save some lifes.


This demo is licensed under GPL 2 license

Hazelcast Jet and Hazelcast C++ client are licensed under Apache 2 license

OpenTTD is licensed under GPL 2. See more

Versions used

You can’t perform that action at this time.