Skip to content

vladoschreiner/transport-tycoon-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Transport Tycoon Demo

OpenTTD collision prevention using Hazelcast.

About

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

This demo extracts real-time vehicle data from OpenTTD and analyses it using the Jet engine data processing engine. The Jet application predicts train collisions. The predicted collision 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

Architecture

The source code of OpenTTD was changed to stream out the vehicle position data and receive back the predicted collisions. This approach was inspired by Using OpenTTD to create a realistic data stream blog.

For each in-game vehicle, it's position update is sent to Hazelcast approximately 30x per second. Position updates are serialized as JSON messages. See an example:


{
	"Name":"Train 4",
	"TimeStamp":"1562933209898",
	"X position":1880,
	"Y position":1480
}


The position records are sent to Hazelcast cluster using Hazelcast messaging services (EventJournal).

Hazelcast hosts a collision prediction job that is subscribed to the messaging service. It predicts the vehicle position by extendig the vehicle motion vector. In simple terms: the vehicle is expected to keep the direction and speed it carried from now - 1 second to now. Collision is predicted if there is an intersection between two or more vectors.

Prediction visualised

This happens every 50 milliseconds. Higher resolution isn't possible due to the game speed (~30 game loops per second).

The collision prediction job is implemented using the Pipeline API of the Jet engine (see the code).

Any predicted collision is stored to a Key-Value store in Hazelcast. This also generates an event that gets delivered to the Hazelcast client running in the game. The event handler stops affected vehicles using the OpenTTD API.

Pipeline

Performance

The in-game code uses async Hazelcast APIs to avoid negative impact on game performance.

The server-side components benefit from the low-latency architecture of Hazelcast for both messaging and compute. As a result, the whole prediction cycle takes just a few milliseconds to complete (mostly network-bound) giving enough headroom to stop the running trains.

Server-side components are straightforward to scale to handle millions of events per second to support many game instances

Structure

openttd directory contains a fork of OpenTTD 1.9.2 source code extended routines 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.

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

Prerequisites

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

Install Hazelcast C++ client to your system.

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
./openttd

Note for MacOS users: If starting the openttd binary fails, try building a Mac OS app bundle by running make bundle and start the game by launching OpenTTD from the bundle folder and allow the app to access the Documents folder.

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.

Pipeline

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.

Licensing

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