Guns Have insane latency on Main Roblox App, perfectly fine in studio

I am making a gun framework for my game
Notes and Script Samples:

  • I am raycasting on the server via a seperate module functions
Summary
function GunFunctions.ShootGun(MousePosition, Gun, Character)
	
	if Gun then
		
		
		-- Physical Gun Variables --
		local GunModel = Character:FindFirstChild(Gun)
		local FirePoint = Character:FindFirstChild(Gun):FindFirstChildWhichIsA("Model").FirePoint
		
		-- Gun Stats --
		
		local Range = GunInformationTable[Gun]["Range"]
		local Damage = GunInformationTable[Gun]["Damage"]
		local FireRate = GunInformationTable[Gun]["Fire Rate"]
		local Offset = GunInformationTable[Gun]["Spread"]
		local GunSound = GunInformationTable[Gun]["Gun Shoot"]
		
		local RandomFunc = Random.new()
		local RandomOffset = Vector3.new(RandomFunc:NextNumber(-Offset, Offset), RandomFunc:NextNumber(-Offset, Offset), RandomFunc:NextNumber(-Offset, Offset))
		
		MousePosition += RandomOffset
	
		
		-- Raycasting --
		local Params = RaycastParams.new()
		Params.FilterDescendantsInstances = { Character , GunModel:GetChildren() }
		Params.FilterType = Enum.RaycastFilterType.Exclude
		
		local Origin = FirePoint.Position
		local Direction = (MousePosition - Origin).Unit * Range
		
		local RayCast = workspace:Raycast(Origin, Direction, Params)
	
		ReplicatedStorage.GunRemote:FireAllClients("Effects", FirePoint, Direction, GunSound, RayCast)
		
		if RayCast then
			
			local InstancedResult = RayCast.Instance
		
			if InstancedResult then
				
				
				
				if InstancedResult.Parent:FindFirstChild("Humanoid") then
					local Humanoid =  InstancedResult.Parent:FindFirstChild("Humanoid")
		
					for i, v in pairs(Damage) do
						
						if tostring(InstancedResult) == i then
							Humanoid:TakeDamage(v)
							
						
						end
					end
				else
					--print("not humanoid")
					--print(InstancedResult)
					ReplicatedStorage.GunRemote:FireAllClients("Bullet Holes", nil, nil, nil, InstancedResult, RayCast.Position, RayCast.Normal)
				end
			end
			
		end
		
	end
end
  • Effects are on the client using :FireAllClients
Summary
GunRemote.OnClientEvent:Connect(function(Purpose, FirePoint, Direction, ShootSound, InstancedResult, RayPos, RayNorm)
	
	if Purpose == "Effects" then
		
		if not FirePoint:FindFirstChild("MuzzleFlash") then
			for i, v in pairs(ReplicatedStorage.GunFx.MuzzleFlash:GetChildren()) do
				local Particle = v:Clone()
				Particle.Parent = FirePoint
				if Particle:IsA("SpotLight") then
					
					Particle.Enabled = true
				end
			
				Debris:AddItem(Particle, .15)
				
			end
			if not FirePoint:FindFirstChild("GunSmokeEffect") then
				local GunSmoke = ReplicatedStorage.GunFx.GunSmoke.GunSmokeEffect:Clone()
				GunSmoke.Parent = FirePoint

				Debris:AddItem(GunSmoke, 3)
			end
		end
		
		--[[
	local midpoint = FirePoint.Position + Direction/2

	local VisibleRay = Instance.new("Part", workspace)
	VisibleRay.Name = "Bullet"
	VisibleRay.Anchored = true
	VisibleRay.CanCollide = false
	VisibleRay.Material = Enum.Material.Neon
	VisibleRay.BrickColor = BrickColor.new("Yellow flip/flop")

	VisibleRay.CFrame = CFrame.new(midpoint, FirePoint.Position)

	VisibleRay.Size = Vector3.new(.1,.1, Direction.Magnitude)

	Debris:AddItem(VisibleRay, .5)]]
	
	------------------------------------------------------------

	
	
	local GunShotSound = Instance.new("Sound", FirePoint)
	GunShotSound.SoundId = ShootSound
	GunShotSound:Play()
	
	Debris:AddItem(GunShotSound, 1)
	
	elseif Purpose == "Bullet Holes" then
		
		
		local ImagePart = Instance.new("Part", workspace.BulletHoles)
		ImagePart.Transparency = 1
		ImagePart.CanCollide = false
		ImagePart.Anchored = true
		ImagePart.Size = Vector3.new( .5, .5, .5 )
		ImagePart.CFrame = CFrame.new( RayPos, RayPos + RayNorm)
		
		local BulletImage = Instance.new("Decal", ImagePart)
		BulletImage.Texture = bulletHoleImageIdsBasedOnMaterial[InstancedResult.Material] or ""
		BulletImage.Face = Enum.NormalId.Front
		
		Debris:AddItem(ImagePart, 10)
		
		--
		
		
	elseif Purpose == "Reload" then
		-- print("firing clients, reloading")
	

		local GunReload = Instance.new("Sound", FirePoint)
		GunReload.SoundId = "rbxassetid://8245961296"
		GunReload:Play()

		Debris:AddItem(GunReload, 1)
	end
end)

Issue: I have been developing this framework for the past 3 days, and latency/lag wise, there has been absolutely 0 issues. That is however, until I opened my game and told my friends to join to do some stress testing, just incase, also for the purpose of some constructive critiscm.
Comparisons and Clips below TW: Gun shots, they are loud I advise turning down your volume

In Roblox Studio: testing, the guns work amazing; there are no lag issues, no frame drops, everything works how it is supposed to

Roblox Studio Testing

In Main Roblox App: Latency is beyond horrendous, raycasts take forever to fire, or they literally never do. My guns have a bullet spread system so guns are not 100% accurate, at first I thought the reason nobody was hitting anything was for this( I thought I had to tweak the spread system). This was NOT the issue as I went in roblox studio right afterwards, keeping the same values and it was fine. The raycasts just take forever to fire. The script rate isn’t even high.

Main Roblox App 1
Main roblox App 2

Also: Even when I am in the main roblox game, even by myself with nobody else in the server it still lags

I need help with this ASAP, I’ve never had to deal with these type of problems.

3 Likes

It’s because when you test play on studio, the server is on your own computer, and when you’re playing on the client, the client connects to the closest server to you geographically and for some places like on South America that doesn’t have servers the ping is around 100-170ms, aka lag

1 Like

Is there anyway to fix this? There are many games without latency to this extent, there has to be a solution

I don’t know for sure but if you get the player’s ping, you can average out or predict where the bullet will be for the client, this problem is called vision lag, because apparently on your case, the client is calculating the physics so for other players the bullet might be lagging and the collision may not be accurate

I’m not understanding? The bullets are being fired via the server? Also how would i even begin to implement this scriptwise… how can I predict something like that , can you provide an example ?

1 Like

Im sorry that I didn’t read the all the topic before reply

if this script is running on the server, it really shouldn’t because when you are getting the player’s mouse from the server, it takes additional time to process it because the client has to send that information to the server and it consequently takes more time for the whole script to happen

If you could, you can just put when it calculates the raycast on the client and then fire the server that raycast info

But if you need that the raycast calculation be on the server you can use unreliable remote events to reduce lag, but it can fail because it’s unreliable

1 Like

Forgive me because I have never raycasted on the client before

So what you’re saying is I should raycast on the client, I am questioning what raycast info would I send? the origin, direction?

  • How would I control and validate damage detections ( server and client-wise);
  • How would I handle all ray-hits in general; I want this system to be somewhat secure, but at the same time it needs to be playable and this input lag clearly conflicts that.
    Sorry if I’m asking too much but can you go into more detail on how I would raycast on the client and do all server checks in my case. Some topics on the devforum that describe this are incredibly vague.

Also wouldn’t any exploiters be capable of changing the direction variable, from mouse.position to their target’s position value so they could in theory just have aimbot. It seems very exploitable

Raycast on the client instead of the server. Aimbot is quite literally still going to happen either on the server or not. Only difference is players are going to dislike your game because the delay between ACTUALLY CLICKING and then FIRING a remotevent with the users mouse position, just makes combat way harder and more annoying. Don’t be so reluctant just because 1 out of 50 people that play your game might be an exploiter.

1 Like
  1. So, you do just the raycasting on the client, the remaining things you do on the server

  2. Raycasting on the client is actually the same thing from raycasting from the server so you can use your skills on that too

  3. It’s very easy, because it connects to the event so you just need the player that the raycast is coming from and the raycast itself

  4. That’s one downside of making the raycast on the client and I don’t know how to prevent aimbot users

Okay, so for example if the client raycast hits something, I can send a remote even to the server, get the part that the ray hit, person or regular part, and I can send the raycast information ( origin, direction, range) and do checks such as magnitude checks. Is this atleast a decent way to make sure it’s somewhat secure?

1 Like

I am not sure if it is secure enough to combat aimbot usage but that’s it basically

1 Like