Creating a node based track system for use in Train Sims. [More problems]

Hello fellow developers!
Recently I’ve been trying to improve upon my Train Chassis system. (Here)
The problem is, the script runs on the server side, and as we all no, updating CFrames on the server side wont always look smooth on the client. To combat this I send remote events containing the part CFrame to every client every heartbeat (60hz). This isnt good. Ive tried everything, ive tried offloading some of the script to the client but no luck. The problem is this part of the script:

-- Server Script
Heartbeat:connect(function()
		CentralPoint = (BogieOne.Position + BogieTwo.Position) / 2
		RootCFrame = CFrame.new(CentralPoint, BogieOne.Position)
		if RootCFrame ~= RootCFrame then
			if rs:IsServer() then
				updateCframe:FireAllClients(Root, RootCFrame)
			end
			
		end
		Root.CFrame = RootCFrame
		
	end)
-- local script
updateCframe.OnClientEvent:Connect(function(part, cframe)
	part.Cframe = cframe
end)

Any and all help is appreciated.
Link to the game so you guys can experience this for yourself if you have a bad internet connection:
Gospel Oak to Barking Line - Roblox

p.s. These trains need to be drivable and I haven’t seen anyone make a tweening train that is drivable

2 Likes

This seems to be a design issue. I can’t get the train at your place to drive at all, but if the train needs to be responsive to client input, you may need to set the network owner of the train parts to the client and offload the work to the client. That would open up an issue of possible exploitation however, which may or may not be an issue depending on if it effects other players to a large degree.

Another solution would be to send not just a cframe position, but a velocity as well. I don’t mean a physics velocity, but more a direction and information for the clients to smoothly transition the train in that direction until the next server update. This may be complicated though.

The train has a seat at the front, you can use W and S to change power.

@BanTech I hope you don’t mind me mentioning. But do you think you could give me a bit of insight into what parts of the movement system on SCR run on the client or server. And maybe a bit of feedback on my existing system (if you want, that’d be cool).

No problem, I’ve got further improvements planned for the system to make it a bit more efficient and to allow us to unload trains that are really far away.

For now, there are tracking parts that the rest of the train is welded to, and these parts are moved on the client. The parts are unanchored while the train is moving to allow network ownership to be given to the client, and a BodyPosition object is used to prevent the trackers from falling on the server between moves, and using a BodyPosition smooths things out a bit as it enables the server and other clients to do a little bit of prediction and interpolation. The server is also informed via remoteevent about where these trackers should be.

When the train arrives at a station, the trackers are anchored to allow the train to be stable, using the information sent to the server about where the trackers should be to allow them to be anchored at the right location. If you swapped network ownership and tried to anchor them quickly, you might find they are out of alignment with where the client wanted them to be.

My future improvements for the system involve removing the BodyPosition altogether, using only CFrame. Each client will load in a copy of the train and weld the parts to their local tracker, which will have its position synced via the server, tweening between received frames. This will allow clients to entirely unload trains that are outside of a given “render distance” setting, as well as preventing the issue of setting different network ownerships. The issue comes from passengers and seating, as you wouldn’t want the passengers to be floating in space due to minor delays in syncronising the positioning. I plan to do a lot of testing with simulated network delay to understand the details of that system.

But to answer your question simply, the train movement happens entirely on the client, focusing on giving the driver the best experience. The server and other clients are essentially on catch-up all the time.

3 Likes

Thank you so much. some of that I didn’t understand but I offloaded the processing to the clients and I send the speed of the train to the other clients so that they can do their own processing. When the train stops I update the position on the server. Works fine and its now live on the place.

1 Like