What do I want to achieve?
I’m trying to create a train driving system for a game based around railroading. The problems I’m having specifically relate to the system for driving the trains, however, there are some important elements of the game that may impact what system will work. Players must be able to drive the trains themselves, and trains must be able to be rerouted at switches to other lines. Trains may be just a locomotive or a series of cars coupled together. Ideally, trains would also be able to enter sidings and couple to different train cars, although this is a separate challenge to solve.
What is the issue, and what solutions have I tried so far??
I’ve tried several approaches to making a train, but each have had their own issues. As far as I can tell, there are three approaches I can take to making a train, and I’ve experimented with each. I’ve put some of the problems I’ve had and where I’ve gotten stuck with each one in the below sections.
1. Fully Physically-Based Train
This was the first approach I tried, many years ago when I started experimenting with making stuff in Roblox Studio. This approach involves using a CylindricalConstraint on a wheel with a small rim on the inner portion. I talked about this approach in some more detail in a previous post.
The Problem
While the most successful version of this approach I made can go decently fast with good stability on straight sections of track, it dramatically slows down on even minor curves. I suspect this is due to the inner rim being too close to the rail, getting stuck on curves, but my current attempt to recreate this system in my newer world with a new train and different wheels has been unsuccessful, as the wheels keep getting stuck inside the train for some reason.
Here’s the wheel design:
I’ve also noticed this system is pretty resilient to derailments, which is nice in normal conditions, although I’d like it if they could derail in some situations (such as too fast on a curve), but it’s not a requirement.
What I’m Asking Help For
I think this system would be more complicated than the next approach to implement, and I’ve played many games which have used a similar system where the trains were super buggy due to physics being weird, so I’ve been avoiding this approach for a while. However, if someone has an idea on how to make this work properly, I might reconsider using this approach.
2. Physics-Enabled Train (Gliders) with AssemblyLinearVelocity
This system is the one I’ve spent the most time working on. It still uses physics to stay on the rails by utilizing “gliders” or parts on one or more sides of the rail to keep the train bogeys aligned. As it approaches a curve, the gliders force the bogeys to rotate, which then rotates the train. By applying AssemblyLinearVelocity in the direction the train is facing, I can directly control the trains speed, while making track construction simple and enabling potential derailments in cases such as taking a curve too fast.
This is the portion of the script that controls the train’s movement. Note that TRAIN refers to the floor of the train and that speed is a value I can control as the player. DOWN_FORCE is an additional force applied directly towards ground in an attempt to reduce the train bouncing.
local function moveForward()
local a = coroutine.wrap(function()
while trainMoving do
local trainCFrame = TRAIN.CFrame
local speed = trainSpeed.Value
TRAIN.AssemblyLinearVelocity = Vector3.new(trainCFrame.LookVector.X*speed, TRAIN.AssemblyLinearVelocity.Y - DOWN_FORCE, trainCFrame.LookVector.Z*speed)
RunService.Heartbeat:Wait()
end
end)
a()
end
The Problem
I made a pretty successful version of this system, one that was good enough that I started trying to make a game with it, however, I messed up the scale, which made everything too big compared to the Roblox player. So, I tried again at a proper scale, however, it seems that by making the train and rails smaller, I significant reduced the stability of the system.
Previously, the train could operate at very high speed on straight sections of track with minimal bumps, and curves could be navigated at reasonable speed before a derailment occurred. Now, even traveling in a straight line, I cannot exceed much over 50-70 (I think it’s measured in studs per second) before the train either pops off the rails or the inner guide parts clip through the rail. Additionally, any movement whatsoever is very bumpy, and it seems more extreme when the train is traveling in reverse.
What I’ve Tried
I tried adding more parts to more completely surround the rail, however, any approach results in these parts clipping through the small rail. I also messed with many of the physics properties, such as friction, density, collision groups, etc. (I don’t fully remember everything I tried, as I’ve been working on this on and off for a long time)
I really prefer this approach, it seems like it has the potential to be the most stable, and it allows me to do things like collisions and derailments, but currently it is simply not stable enough for it to be enjoyable to use.
What I’m Asking Help For
I’ve seen a few other posts here with similar issues, but none of them seem to have solutions that are practical for my situation or the solutions didn’t work when I tried them. I’m pretty sure other train games have used gliders at the scale I’m working at successfully, but I don’t know how they made them work properly. I’d love to hear if anyone else has solved this problem or has advice on making the gliders more reliable.
3. CFrame/Tween Train
This is a new approach I am trying out. I have seen many people recommend using CFrame and Tweens to move the trains, and it has some obvious benefits. Most notably, it is the most stable, as you directly control where the train is going, and although derailments would never naturally occur, it could be programmed into it, giving me more control over the system.
I’ve come up with a system for building track (in this case, just nodes, visual tracks would be a separate problem) that would allow me to still utilize switches for the train, and I could even create more advanced bezier curves for the track, which could speed up how quickly I can build switches and track curves.
The Problem
This approach is far more complicated and quite complex mathematically. That’s not to say I couldn’t figure out the complex math involved, but it does pose some real challenges. One of the biggest problems is how will the player control the train. I can modify the time for a Tween movement to be performed, however, I don’t believe the speed can be modified during the animation. Consequently, it wouldn’t be possible to simply tell the train to move from point A to point B for straight segments. I’d have to make many very short Tweens along the entire route from one point to another, and only after each Tween could the speed be updated.
I am worried this approach would be require making too many calculations, leading to significant performance loss or lag. Additionally, even with many short Tweens, I am worried that the trains wouldn’t feel responsive enough due to the wait between the player input and the current animation finishing so the train can respond to the new input. It could cause the train acceleration and deceleration to be very rough.
Additionally, trains are usually made of several connected carriages, each with bogeys that rotate independently from the car. While I’m waiting to work on carriages until I have a locomotive that works properly, this approach also raises significant concerns, as each car or bogey would need to follow the path independently, but also maintain a fixed distance from each other.
What I’ve Tried
As previously mentioned, I’ve made some code to connect points and create bezier curves, and I’ve made some very basic code for moving a train along the path, which works perfectly fine for demonstration purposes. However, to make it player controllable would require a lot of work, which would be a lot of time wasted if the performance would be terrible, so I haven’t gone any further.
Here’s the current movement code, although it’s a mess, so I apologize in advance:
local function movePath()
local tweenTime = 1
local tweenInfo = TweenInfo.new(tweenTime, Enum.EasingStyle.Linear, Enum.EasingDirection.In)
-- For each node in the current test path I made
for i = 1, 10 + 2, 1 do
while currentPart.NextPart.Value == nil do
task.wait()
end
currentPart = currentPart.NextPart.Value
local tween = TweenService:Create(Model, tweenInfo, {CFrame = CFrame.lookAt(currentPart.Position, currentPart.NextPart.Value.Position)})
tween:Play()
task.wait(tweenTime)
end
end
What I’m Asking Help For
I’d like to hear if anyone else has tried anything like this so I don’t go wasting my time pursuing an approach that might already be known to be too performance intensive or just not practical for the type of game I’d like to make. I think if it could work, using CFrames and Tweens could work well.
Fully Physical-Based Train Video
Physics-Enabled Train with AssemblyLinearVelocity Video
CFrame/Tween Train Video
I’ve also heard about making trains using prismatic constraints, which I don’t believe would work for this situation, but I’d be open to ideas on how to utilize prismatic constraints for trains if they would be able to do all the things I’m looking for.
What am I looking for?
Simply put, I would like some advice on either how to fix some of the issues with these train systems and/or advice on which one is best suited for the type of game I am trying to make so I don’t waste my time trying to make something work which never will. I appreciate any advice you may have to offer.

