Projectile Spawn Latency/Delay

So The problem is the server thinks the spawn position of the bullet is behind the character while moving any fix for this.

game.ReplicatedStorage.RemoteEvents.Shoot.OnServerEvent:Connect(function(plr, Look, hit)
	local char = game.Workspace:WaitForChild(plr.Name)
	if char.Shot.Value == false then
		char.Shot.Value = true
		local Bullet = game.ReplicatedStorage.Dupes.CellBullet:Clone()
		Bullet.CFrame = CFrame.new(char.Eye.Position,hit)
		Bullet.Parent = game.Workspace.SpawnedBullets
		
		local CharName = Instance.new("StringValue", Bullet)
		CharName.Name = "CharName"
		CharName.Value = char.Name
		
		local BulletHit = Instance.new("BoolValue", Bullet)
		BulletHit.Name = "BulletHit"
		
		local BodyVelocity = Instance.new("BodyVelocity",Bullet)
		BodyVelocity.Velocity = Look * 200
		BodyVelocity.maxForce = Vector3.new(math.huge,math.huge,math.huge)
		
		game:GetService("Debris"):AddItem(Bullet,3)
		char.Shot.Value = false
		
		Bullet.Touched:Connect(function(t)
			if t and t.Parent == game.Workspace then
				print("Server"..t.Name)
			end
		end)
	end
end)
1 Like

I wouldn’t call this the best solution, but…

One solution I could possibly give you is to get the CFrame information from the local script and send it through your RemoteEvent. It might help a little bit, but latency is a little hard to fight on ROBLOX (to my knowledge, anyways).

Someone will probably come up with a better solution… that’s all I can really give you.

4 Likes

Try parenting the Bullet after you add the velocity to it.

What is char.Eye? Obviously, char is the character, but what is the Eye? Is that a custom part? Is it welded to the character?

This is because when you send data over the internet, it takes time for the data to arrive at the other end of the internet pipe. This is called “Latency”. To compensate for this latency, you need to calculate the relative position based on the latency time and velocity. Furthermore, you can create a local projectile just for your local latency-free viewing pleasure.

What is strange is he is on a Studio test, which only simulates the network, and doesn’t suffer from ping spikes as it isn’t really on a live server.

The bullet is based on the position of the character’s “eye”, which is checked on the server, not sent from the local script.

In a studio test, in this case, I would expect the part to be synced up pretty closely to the position of the character.

That is why I suggested the velocity gets created before the bullet is reparented. If you watch the GIF above in the OP’s original post, the bullet takes almost a second to get moving even when the character isn’t moving.

See what I tried was to set the velocity first then spawned the bullet onto the player but still the same thing and I also tried adding a fake bullet so the player firing can have no latency but the bullet on The server is still firing after the client so they both don’t hit the same target

I will attempt some of those solutions but am open to more solutions.

This issue has to do with the network ownership changing. While I recommend you use FastCast for this type of system. The solution that would resolve what you’re encountering is to set the player as the network owner of the bullet.

...
Bullet.Parent = game.Workspace.SpawnedBullets
Bullet:SetNetworkOwner(plr) -- This is what you need added to keep the player as the network owner

For details of what you’re encountering the bullet is spawned with the network owner as the player (since it is the closest to it) and as it moves away the server has to take ownership which causes the lag you see.

1 Like

Thank you for the response I will try this when I can and mark you as solution if it works.

Still does the same thing as showed above even making the plr network owner

game.ReplicatedStorage.RemoteEvents.Shoot.OnServerEvent:Connect(function(plr, Look, hit)
	local char = game.Workspace:WaitForChild(plr.Name)
	if char.Shot.Value == false then
		char.Shot.Value = true
		
		local Bullet = game.ReplicatedStorage.Dupes.CellBullet:Clone()
		Bullet.Parent = game.Workspace.SpawnedBullets
		Bullet:SetNetworkOwner(plr) 
		local BodyVelocity = Instance.new("BodyVelocity",Bullet)
		BodyVelocity.Velocity = Look * 200
		BodyVelocity.maxForce = Vector3.new(math.huge,math.huge,math.huge)
		Bullet.CFrame = CFrame.new(char.Eye.Position,hit)
		game:GetService("Debris"):AddItem(Bullet,3)
		char.Shot.Value = false
		
		Bullet.Touched:Connect(function(t)
			if t and t.Parent == game.Workspace then
				print("Server"..t.Name)
			end
		end)
	end
end)

In this example you are still setting the parent of the bullet before creating the velocity. Did you try setting the parent after?

So I had a similar problem except it was with bombs falling out of the plane. I found that if you weld the object quickly it seems to work better, but my situation is a bit different to yours so it might not work quite as well.

This is an issue relating to how physics and replication works in Roblox. The only real way to fix this as much as possible is to manually replicate things, accounting for ping all throughout the path.

For example, firing a bullet locally and telling server
Server adjusts their bullet for ping and tells other clients
Clients adjust the bullet for their ping and fire it locally