#How can I incorporate lag compensation into my game?
1 messages · Page 1 of 1 (latest)
specifically what are you sending with the remote event?
ReplicatedStorage.Events.Remotes.React.OnServerEvent:Connect(function(
player: Player,
ball: BasePart,
touchedAt: CFrame,
touchingPart: BasePart,
reactDeclineCooldown: number,
timestamp: number
)
if not validateReact(player, ball, touchedAt, touchingPart, reactDeclineCooldown, timestamp) then
warn(`{player.Name} react declined`)
return
end
reactDeclineCooldown = math.clamp(reactDeclineCooldown, 0.1, 0.75)
local playerToReact = player
local finalCFrame = touchedAt
if not reactRequests[player] then
reactRequests[player] = {timestamp = timestamp, touchedAt = touchedAt}
end
task.wait(0.2)
if getLengthOfDictionary(reactRequests) > 1 then
local earliestTime = math.huge
local earliestPlayer = nil
for player, reactData in reactRequests do
if reactData.timestamp < earliestTime then
earliestTime = reactData.timestamp
finalCFrame = reactData.touchedAt
earliestPlayer = player
end
end
playerToReact = earliestPlayer
end
if ball:GetAttribute("NetworkOwner") ~= playerToReact.UserId then
if ball:GetAttribute("ReactDecline") then
return
end
ball:SetAttribute("ReactDecline", true)
task.delay(reactDeclineCooldown, function()
ball:SetAttribute("ReactDecline", false)
end)
if ball.AssemblyLinearVelocity.Magnitude > 75 then
if finalCFrame then
ball.CFrame = CFrame.new(finalCFrame.Position)
end
end
end
table.clear(reactRequests)
ball:SetNetworkOwner(playerToReact)
ball:SetAttribute("NetworkOwner", playerToReact.UserId)
end)
so
I actually tried to implement my own lag compensation before this
using timestamps that the client sends
and the server waits a small amount and checks whoever sends it the earliest
didnt end up being a good system, was buggy and didnt work at times
is it possible to do all the logic on the server instead
that way it would be laggy for everyone
instead of for some people
😁
that would still be laggy though
but that way its fair
a lot of people told me to just use an invisible server ball and visualize it on all clients but the server is slow with physics
compared to just using network ownership
it would take away from the quality of the game is the problem.
perhaps create a boolean that confirms the ball state serverside? that way the first person to fire the event will be the only one shooting?
what do you mean by the "ball state"?
local ballinair = false
or if this doesnt effect those with <150 ping you could also leave it be 🤷♂️
someone also told me I could try making a custom replication system for this somehow
but adding interpolation or whatever to that is something that's too advanced for me id only know the basics
im unsure how this would even work, could you ask for more details from that someone?
yup this is what i suggested? the ballinair boolean will minimize the ball to one player at a time, that being who the server thinks was first.
so you're saying if that state is active then only one person should end up actually winning the "duel" or whatever
and again how would I verify "who the server thinks was first."
thats what i failed to do with my timestamps
yes, that way atleast the ball wont teleport back
when the event fires simply check if the ballinair variable is true, if it is then return end, if it isnt then set it to true
this should hypothetically limit the ball to one player
and ofcourse set the variable to false when the velocity is applied
should it be fired on every touch?
if ball:GetAttribute("NetworkOwner") ~= playerToReact.UserId then
if ball:GetAttribute("ReactDecline") then
return
end
ball:SetAttribute("ReactDecline", true)
task.delay(reactDeclineCooldown, function()
ball:SetAttribute("ReactDecline", false)
end)
end
thats basically what I was doing with my react decline attribute except it only done on your first ever touch with the ball where you didnt have network ownership with it
would it be good to
do this on EVERY touch?
never tried how it would affect gameplay so
in theory it should give off the same result, again we're just limiting the ball's velocity addition to one player at a time
alright
lmk how it goes! 
theres still one more issue which is sort of related to this
lemme see if i can find a clip
okay!
its basically what i was talking about in the beginning with "lag compensation" but the video I sent was something different, basically if you're on 300 ms and you are receiving the ball mid air (in a close duel situation with other players) then you probably are almost never going to touch that ball first because you arent going to send the remote event signal to touch the ball as fast as say a 50 ms player would
even if you touched it first, if a 50 ms player was right behind you and they also touched the ball too they would still get it
isnt this a problem throughout all soccer games?
its an annoying mechanic in my game and its become like a big thing
i guess so
this is more or less a roblox issue and not something a developer could fix, atleast i'd imagine so 🤷♂️
as long as my system involves network ownership i guess you're right
i was just told by someone that this could work
this could definitely work but it could be annoying to those with high pings, especially on how much delay you add.
you need to compensate for the norm, not for everyone
yea thats what I was doing in the original script, guess i did it badly haha 😭
say for instance i have 1000 ping, would it be fair to the norm that has low ping that they wait a full second just to shoot a ball?
true
i guess like even just enough delay so that a 150 ping player has a chance against a 50 ping player
but when I test
yes, a delay of .1s (100ms) should be good enough
yea
is there any way I can make the transition between the player touching and the delay better
because rn the ball just kinda freezes
or
stutters
id say
can you send over a recording of said stutter
if thats not possible id possible recommend a animation of sorts to play?
that might just be something to do with my system
no worries, you could make 2 animations, "hit" & "fail" if the player is the sole event firer through the 100ms delay play the hit anim otherwise use fail
that way shooting will look appealing
Ok
besides all the previous stuff we were talking about, does this script work for the waiting a small amount and checking timestamps idea or no? or should I polish it
im just not sure if i implemented the idea correctly
im just adding a player to the reactRequest table and checkign it after .1 seconds ideally
you are delaying my 200ms which is pretty unreasonable for low ping players, if you plan on doing animations this is perfectly okay otherwise you should lower it to 100ms; also you limit the velocity addition to one player at a time with the ball state variable i suggested prior #1391400914828660894 message
alright
im gonna make these changes and see how it goes
tysm for ur time
reactDeclineCooldown = math.clamp(reactDeclineCooldown, 0.1, 0.75)
local playerToReact = player
local finalCFrame = touchedAt
if not reactRequests[player] then
reactRequests[player] = {timestamp = timestamp, touchedAt = touchedAt}
end
this is fine
if getLengthOfDictionary(reactRequests) > 1 then
local earliestTime = math.huge
local earliestPlayer = nil
for player, reactData in reactRequests do
if reactData.timestamp < earliestTime then
earliestTime = reactData.timestamp
finalCFrame = reactData.touchedAt
earliestPlayer = player
end
end
playerToReact = earliestPlayer
end
this too but doesnt the event still fire for all players who touched it despite the earliest player? you should check if player == earliestplayer in else cases return end
running it multiple times is likely going to cause issues
no worries, i hope your implementation goes well!
wdym? inside the loop?
OH WAIT
"this too but doesnt the event still fire for all players who touched it despite the earliest player? " i understand what you mean by this