I am going to have client side obstacles in my game, so that they act properly with parts that have the network ownership set to the player. Some of these obstacles will spin, some will move around, and some will do both.
Simply put, is there a way I can keep all of these obstacles in sync across all clients, so their effects will replicate for everyone?
Well no, not really, other than players joining late.
Have you also considered if you’re going to have a spectate system, late joiners spectating will see out of sync things from their view? Although you could just disable spectate for new joiners.
Then again, there could be a much more efficient way to doing this however this is the first method that came to my mind.
Clients can desync this way due to Physics Throttling. I would recommend creating “handler” parts controlled by the server. These parts can resync CFrame, Velocity, and RotVelocity if needed. Essentially the server will control the sync parts and the client can check if the server part is too far away on RunService.Heartbeat and if it is resync. For example, if the part is more than 2 studs away or its rotation is off by more than 5 degrees.
Edit:
Also I would recommend doing these checks server side if you’re worried about exploiting at all.
You should sync client clocks. Not an easy task but there are plenty of ways to do it on ROBLOX nowadays. I’m sure you can come up with a solution.
The simplest way, but not efficient, would be to use os.time() and send a future time for all clients. For example. Let’s say you want to move the ball after 5 seconds. The server will send to all clients os.time() + 5. They will receive it and then they will move the ball when their os.time() matches with the time sent by the server. I don’t know if i made any sense, but that’s a pretty complicated idea to explain by typing. Let me know if you still need any further explanation.
It sounds like you don’t want client side obstacles but instead have them on the server to replicate, you can still set network ownership to a certain player if you want/need. If the parts are created locally then they will not exist for other clients.