A free, open-source roller coaster simulator built in Unreal Engine 5, aimed squarely at the gap NoLimits 2 has left open for a decade: engineering-grade precision, a modern interface, and a real block-signalling and ride-control system that neither NoLimits 2 nor Planet Coaster has attempted.
Track is curvature-continuous by construction, physics is energy-exact, and the G-forces are the ones a rider would actually feel — not a plausible-looking curve.
This drawing is not an illustration. It is produced by compiling the project's own prototype headers
against the layout in Source/TrackUnlimited/TUCoasterRide.cpp
and running the ride profile over the result. Sixteen typed segments, authored as numbers, riding
inside the engine and reading out on screen.
Full figures and how to reproduce them: Docs/REFERENCE_LAYOUT.md.
A track is an ordered list of typed parametric segments, each defined by values or expressions. The 3D view is a read-only preview, not the editing surface. This is a deliberate rejection of direct-manipulation editing, and it buys three things at once: exact geometry, an editor that is Unreal's own Details panel rather than a bespoke UI, and a save format that produces a one-line diff when you change a helix radius.
Every segment carries curvature varying linearly over arc length — a straight is κ = 0, a
constant-radius curve is κ = const, a clothoid is κ linear — and geometry comes from integrating
a moving orthonormal frame along that profile. C² continuity is therefore a property of the
representation, not something fitted afterwards, and transition curves are the native case instead
of special handling. The reference layout is continuous to 1e-9 across all fifteen joints, with
nothing solved to make it so.
Gravity is applied as an exact energy exchange rather than an integrated force, so a frictionless circuit conserves energy at any timestep — halve the timestep and the answer does not drift. Rolling resistance follows the actual normal load, so it rises in a valley and falls toward zero at airtime. The train has length, so a crest is paid for at the whole train's mean height rather than the lead car's — which is why the back car gets thrown harder than the front over an asymmetric airtime hill, and why over a symmetric one it does not.
→ Docs/ARCHITECTURE.md#physics
Not "train present / absent". Each block is a state machine that withholds CLEAR for a configurable safety overlap after a train has physically left it — the real-railway overlap concept. A train occupies a range of blocks, nose to tail, so it holds two while it straddles a boundary.
Two trains run one circuit, interlocked. A train is held by commanding the device under it to zero, never by declining to simulate it — so a station is not a special case, and a block brake holds a train mid-course while the block ahead is occupied and releases it when it clears. Where a train may be held is itself checked: a friction brake can stop a train and never start one, a launch can start one and never stop one, and a block that is too short to stop what it receives is a trim brake whatever it is labelled.
Manual dispatch is designed but not built — the interlocks are meant to apply identically whichever way the timing is decided, which is precisely why manual is not a second code path.
Walk the same ordered block and segment list that drives the geometry and the physics: each block emits an indicator, each powered segment emits a VFD module with target speed, motor feedback, torque and ramp rate. The point is to make the causal chain visible — a sensor trips, an indicator lights, the logic evaluates, an actuator responds — rather than collapsing it into an invisible if-statement. This one is a settled design with nothing implemented behind it yet; every other feature on this page is running code.
→ Docs/SIGNALLING.md#the-generated-control-panel
Every claim on this page has a number behind it, and the numbers come from running the code. The ride profile measures the whole ride at edit time — speed, all three felt-G axes, roll rate and height, sampled by arc length — so an author learns a hill is too tall before watching a train fail to crest it.
Phase 2 — Physics & Ride Feel. Phases 0 and 1 are complete.
What exists today, all of it engine-free and assert-tested under Prototypes/, with a thin Unreal
actor over the top:
| Track geometry | curvature profile over arc length; straight, arc, clothoid, helix |
| Authored data model | typed segment list, diffable JSON, exact round trip |
| Validation | reports, never repairs — including self-clearance |
| Circuit closure | damped Gauss-Newton over the parameters you free — and one layout that closes by shape instead, exactly |
| Undo / redo | snapshots, with the save format as identity |
| Train physics | energy-exact motion, zones, a train with length |
| Ride profile | the whole ride measured at edit time |
| Block signalling | state machine, overlap, permissives — and up to four running trains that trip them |
| Block brakes | hold, and release on a permissive — with the layout checked for whether it can stop a train there |
| Braking distance | derived from the layout: a dispatch clears to the next block that can actually stop the train |
| NL2 interop | CSV and live telemetry — validation fixtures, not an authoring path |
| Starter layouts | four worked examples of the vocabulary, each measured before shipping — one of them a closed circuit |
| In-engine slice | builds against UE 5.8, rides, reads out speed, G and block state |
→ Docs/ROADMAP.md for what each phase ships and what is left.
The riskiest maths is standalone C++17 with no engine dependency, so you can build and run it without an Unreal install — the lowest-friction way into this codebase.
cd Prototypes/TrackSpline
clang++ -std=c++17 -Wall -Wextra -O2 -o test_trackspline test_trackspline.cpp && ./test_tracksplineSame shape for Prototypes/BlockSignal and Prototypes/TrainPhysics. Run each from inside its own
directory — the tests include their headers by relative path.
For the full engine build, see CONTRIBUTING.md.
→ Docs/PROTOTYPES.md for what each prototype proves.
| Document | What it covers |
|---|---|
Docs/ARCHITECTURE.md |
Track representation, physics model, meshing, rendering, save format — and the constraints that are not up for negotiation |
Docs/AUTHORING.md |
The segment vocabulary, roll vs bank, validation, closure, undo, the file format |
Docs/SIGNALLING.md |
Block states, buffer/overlap, dispatch permissives, the generated control panel |
Docs/CONTROL_ARCHITECTURE.md |
Design only, nothing built: how a scriptable control and show layer could be shaped, and the real standards it would follow |
Docs/PROTOTYPES.md |
The five standalone prototypes: what each proves, how to build and run them |
Docs/ROADMAP.md |
Phases, shippable artifacts, current status |
Docs/REFERENCE_LAYOUT.md |
The canonical measured figures for the reference layout |
Docs/PROJECT_PLAN.md |
The full plan: vision, market context, all five pillars, risks |
Docs/PHASE0_FINDINGS.md |
What was proven, what was disproved, and the known-limitations ledger |
Docs/GLOSSARY.md |
Heartline, clothoid, holonomy, felt G — what the words mean on a real coaster |
Docs/DEFERRED_DECISIONS.md |
Open choices, what was done in the meantime, and what changing costs |
CHANGELOG.md |
What has landed, newest first |
Three places, three jobs: the repo docs are the design reference, Trello is live task status, and GitHub Issues is the inbound channel for bugs and proposals.
Design discussion and prototyping help are worth more right now than polished PRs. Start with
CONTRIBUTING.md, and read Docs/PHASE0_FINDINGS.md
before changing any prototype header — several obvious-looking fixes have already been measured and
found to make things worse, and that page says which and why.
Working with an AI coding agent? CLAUDE.md is the onboarding file: the non-negotiable
constraints, the current phase, and the vocabulary. Read it before generating code here.
MIT — see LICENSE. This repository contains project code and content only, not
Unreal Engine source; you will need your own Unreal Engine installation, per Epic's
Unreal Engine EULA. No real manufacturer trademarks or
ride designs are used anywhere in this project.



