Having issues with client server synchronization[Solved]

I am making a projectile and the projectile object itself is on the client while the hit detection is done on the server. I am sending a time stamp from the server to the client to essentially find the time that has passed on the server as the client receives the event. After that I am trying to divide the time passed by the time it takes for one frame to pass in seconds, or basically getting the amount of frames that have passed since the server started detecting hits.

The reason for this is because I am using RunService.Heartbeat to move the projectile on both the server and client and I want the projectile on the client to be in sync with the server so I am spawning it at a distance that is equal to the amount of frames multiplied by the projectiles speed away from the player. The problem is that I am not sure which time measuring system to use tick or os.time or workspace:GetServerTimeNow. The other issue is that since frames are not consistent, the clients prediction is inaccurate. Here is the code I have so far :

Server :

SpawnEvent:FireAllClients( tick() , Direction , pos1 , ProjectileModule.Speed )

Client :

SpawnEvent.OnClientEvent:Connect(function(TimeStamp,Direction,Pos1,Speed)
	
	local frames = (tick() - TimeStamp) / 0.025
	print(frames)
	local startPos = Pos1 + (Direction * frames * Speed)
	local CurrentSpeed = Speed
	
	local knife = RS.StoredObjects.Knife:Clone()
	knife.Parent = game.Workspace
	knife.CFrame = CFrame.lookAt(startPos , (startPos + Direction))
	knife.Orientation -= Vector3.new(90,0,0)
	
	runService.Heartbeat:Connect(function()
		
		knife.Position += knife.CFrame.UpVector * CurrentSpeed
		
	end)
	
end)

If anyone has a better method for this please share it with me.

What are the issues are you having exactly?

The projectiles are out of sync(I spawned a test part on the server to see where it is detecting relative to the clients projectile)


I have experimented with different values for the division but there always seems to be an out of sync

I don’t think you can go better than this, there will always be an inconsistency, because ping isn’t a static thing. Maybe a way is to implement predictive hitboxes, where the server mimics the player’s ping on the hitboxes of other players so that the shots seem more fair.

Maybe, but which time measurement should I use? Should I stick with tick?

Tick if you want easy implementation: HeartBeat if you want accuracy

No I meant for the timestamp not the loop that moves the projectile

Heartbeat or the other one I don’t remember but you can use delta time which updates faster than tick

Well if you want the projectile to be smoother more synchronized too you could use networkownership maybe? Or you could try using coroutine/task library functions like coroutine.wrap or task.spawn so that these threads fire quickly.

I’m not too sure if this’ll help but you can try using SetNetworkOwnership. Basically this’ll allow all the physics and stuff to be controlled on a players client side.

Yeah what @Amritss said I mean what @iATtaCk_Noobsi said.

Does this not open the projectile up to major exploits?

Yes it does I think, I haven’t actually used this myself. I suggest you ask @Amritss for help, he seems to know more than me

NetworkOwnership would be a security concern, your game would be the target for aimbot users

Hey, don’t worry! Exploiters are scarce this time of year! Especially after byfron teamed up with synapse and what not.

Actually no no no. Ask @iATtaCk_Noobsi for help, he’s the pro at SetNetworkOwnerShip. I was just jealous of him.

I don’t see that huge of a benefit that’s all, giving up network ownership for 0.03~ more accuracy is crazy

Hey, it’s not crazy if it works!

1 Like

multiply the knife position with the heartbeat’s deltaTime, how much time it takes for physics to process varies from step to step so doing this would make the speed consistent.

1 Like