I am currently working on my game and I have noticed a huge problem
The way the shots replicate in my game goes like this
– local script gets clients camera look vector
– local script fires a shoot remote event to the server
– server script raycasts from camera lookvector
– if the raycast hit a player, do damage.
This works but remote event delay is really pissing me off. If there is a certain amount of people in the game at once the remote events will start to delay and shooting will be annoying as it will be about a half of a second off
If I do it from the client though, It would leave my game extremely vulnerable to exploiters
Definitely keep raycasting on the server. How computationally expensive is your raycasting function? A simple ray between two points shouldn’t cause much lag at all, there might be something else you’re doing that’s making the function “heavy.” Are you creating visuals on the server by any chance?
If you really want accuracy and for it to look good too, do this…
have the server keep a list of player positions going back a few seconds
when you fire the gun, go ahead and do the effects on the client (like bullets fired or line drawn etc…)
2.5) also fire an event to the server with the server time that you fired the gun
server can look in its history, and see where everyone was when the shot took place, and do
raycasting to see if it was a legit hit
server performs kill and alternatively can let shooter client know it was a kill
This is more a network problem than a performance problem.
To OP, you could try simulating the shot on the client for visual feedback and on the server for the actual damage. This has a chance of desync issues where a hit registers on the client but not on the server, but I think it’s a worthy trade off.
The ONLY thing being pased through the remote event is the cameras lookvector. Here’s the code:
Client
function CheckHit()
spawn(function()
local Hit, Kill = nil, nil
local Hit, Kill = game.ReplicatedStorage.RemoteEvents.CheckHit:InvokeServer(game.Workspace.CurrentCamera.CFrame.LookVector.Unit * 100000)
if Hit ~= nil then
Player.PlayerGui.Game.Sounds.Hit:Play()
Crosshair.Image = "http://www.roblox.com/asset/?id=10090085956"
wait(.25)
Crosshair.Image = "http://www.roblox.com/asset/?id=409468479"
end
if Kill == true then
game.ReplicatedStorage.RemoteEvents.Kill:Fire(Hit)
end
end)
end
Server
game.ReplicatedStorage.RemoteEvents.CheckHit.OnServerInvoke = function(Player,Direction)
local Gun = Player.Character:FindFirstChildWhichIsA("Tool").Name
local Parameters = RaycastParams.new()
local ActiveFilter = {}
table.insert(ActiveFilter,Filter.GetFilter())
table.insert(ActiveFilter,Player.Character)
Parameters.FilterDescendantsInstances = ActiveFilter
Parameters.FilterType = Enum.RaycastFilterType.Blacklist
local Result = workspace:Raycast(Player.Character.Head.Position, Direction, Parameters)
local Target = Result.Instance
if Player.PlayerVariables.InSafeZone.Value == true then return end
if Target then
local Model = Target:FindFirstAncestorWhichIsA("Model")
if not Target:FindFirstAncestorWhichIsA("Tool") then
if Model then
if Model:FindFirstChild("Humanoid") and not Model.Name:match("DeathEffect") and Model.Name ~= "Skeleton" then
if Model.Humanoid.Health ~= 0 then
local Killed = false
local CalculatedDamage = (GunDamage[Gun] * LimbDamage[Target.Name])
Target.Parent:FindFirstChild("Humanoid").Health -= CalculatedDamage
if Target.Parent:FindFirstChild("Humanoid").Health == 0 then
Player.PlayerVariables.Stats.Current.Kills.Value += 1
Killed = true
Player.PlayerVariables.Stats.Total.Bottlecaps.Value += 10
game.ReplicatedStorage.RemoteEvents.GiveCurrency:FireClient(Player,10,false)
end
return Target.Parent, Killed
end
end
end
end
end
end
Hm, odd. You could try compressing your CFrame parameter and decompressing it in the server function to minimize the amount of data sent on each remote. Something like this:
I believe this was the solution. I initially raycasted from the clients camera forward to simulate the actual clients view of the shot and sent the raycasts result to the server. I then made another raycast from the server that went from the clients head to the result of the client. If the server raycasts result and the Client raycasts result were the same, then It’s synced and I don’t believe this can be exploited.