Lag compensation with hitscan revisited

I’m sure many of your are familiar with the concept of lag compensation. If not, here’s how the Valve Developer Community defines it. Personally I like how lag compensation gets around the annoying world of networking and tends to be pretty accurate with the proper safety checks implemented.

Obviously this isn’t as an easy task with Roblox due to the lack of an easy way to rewind the game’s state. So, after reading many DevForum topics on lag compensation in Roblox I’m having trouble collecting all my ideas into a good solution.

I’ve never noticed latency issues when it comes to other games with hitscan guns and thus it seems like its a trivial fix, but I’m not so sure. I’ve seen people record positions of every player on every physics step to be able to see when somebody could’ve hit another player. Surely that’s not a efficient use of server resources, right?

Along with that getting the player’s ping the make that calculation isn’t as easy as one might think too. Is this really the method people use? What’s the all around ideal system look like for this?

And before anybody mentions it, yes, I’m aware that you would have to implement sanity checks on the time rollbacks to prevent clients from being able to request a hit on a player from any point in their movement history.

The first solution, as it always should be, is to avoid fixing problems if they don’t exist :slight_smile: .

Implement your game without lag compensation first. If players complain about hitscan delays, or you notice them often, then you can think about it.

If I had to bet, you’ve never noticed latency issues not because those games compensate for lag, but because:

  • pings are pretty low on average so its not really an issue anyways
  • games are fast-paced and no one’s going to notice a few inches
  • who knows what ROBLOX does under the hood to synchronize these things?

Eh. Computers are fast and have a lot of storage space. Valve says that “The lag compensation system keeps a history of all recent player positions for one second.”

So say you’re storing the positions for twenty players on the server. Let’s say we just store one CFrame for each player each frame, and we store 60 frames in some kind of ring buffer.

(20 players) * (1 cframe/player) * (12 floats/cframe) * (4 bytes/float) * (60 frames) = 57000 bytes

So it takes about 57 KB to store cframe data on 20 players for every frame in the last second. That’s so low compared to the size of the rest of your game as to basically be negligible.

Presumably you’ve got some messages being passed between your server and client all the time anyways – just piggyback on that for ping.

3 Likes

Thanks for the answer! I won’t touch lag compensation for now, as you’ve suggested, but if I were to add it what would be the steps? What does a big game like Arsenal, for example, do to combat this issue? I’m sure they get plenty of complaints about lag compensation for many different reasons.

No idea what they do. But you’d need to maintain at least a table for each player, representing their CFrames and directions for the last 60 frames.

I just tried to take a quick crack at it, and it’s not the easiest thing in the world, which is why I really don’t recommend trying. Especially since ROBLOX doesn’t give you very fine control of their network stack.

2 Likes