Client Syncronization - Metro

If I’m creating a metro system and the clients move the Metro when the server requests it, how can I know when the clients are done moving the metro if it tweens 4 seconds to the destination.

Like, on the server do I fire all clients to move the train then open doors after about 6 seconds (2 seconds for delayed players / remote delay?)

Or how else do you think I should do this. I want the server to control the destination and data,
And the client to move train / open doors. I want to ensure the clients are in sync and it does not look funky (doors opening early for some, etc.)

You could use the Tween PlaybackState to see when it has completed the tween
I think you should let the server move and maybe even open the doors of the train so it looks in sync on all clients

2 Likes

Using the server for Tween is a no-no due to the lag and less frame rate as compared to the client. Effects should be carried out on the client.

1 Like

I’d create a folder in ReplicatedStorage with Value instances and connect listeners on the clients for when the Value property of these instances change. To me, it’s much more convenient though as you can connect and disconnect the listeners whenever need be, but I’m not sure if there’s a significant difference in performance.

For capturing when the players have arrived though, I suppose you’d have to use a RemoteEvent to let the server know and add those players to a table. Once the table is equal to the players who rode, you know all have arrived. You’d have to make sure to update the table of those who rode when a player leaves the server in case someone riding left the game.

Is this what you were asking? Sorry, a little confused.

Pretty much, I guess I will just experiment with it until I find something that works best.

Fire RemoteEvent to all clients telling to move train position, save this tick()

(server)

local MAX_MOVEMENT_TIME  = 10 -- allow a maximum of 10 seconds (or whatever) for trains to move on all clients before opening doors.
local move_time = tick()
move_train_remote:FireAllClients

Each client fires a remote back when the train has finished moving on their end

(client)

move_train_remote.OnClientEvent:Connect(function(position)
-- move the train to position, yield until move completed.
  train_moved_remote:FireServer() -- fire confirmation to server.
end

server tallies up the confirmed finished clients each time it receives the event from the client

(server)

local confirmed = {}
train_moved_remote.OnServerEvent:Connect(function(player)
    -- you could add a check here to ensure the player isn't already confirmed (stop possible exploits.. prob not a problem)
    table.insert(confirmed,player)
end

And then check

if (#confirmed >= #game.Players:GetPlayers) or (tick() - move_time >= MAX_MOVEMENT_TIME) then 
    OpenDoors() 
    -- reset your data.
end

the second condition in that if statement is a fallback, in-case a client never confirms back, it doesn’t never open the doors… just to be safe.

4 Likes

Is it okay that when I fire the train door open remote, I fire a close door event within 6 seconds wait on the server. (I’ll use your method for moving the train. Or should I do this for the doors too?)