Option to raycast considering latency

  • I click on someone
  • My bullet travels and hits them on my screen
  • 0.5s later, the server gets the input and simulates a shot in the same direction
  • The server misses because the target player is now 1s forward into the future

This is a standard problem in shooters. The correct solution is to account for the latency between the shooter and the server by casting the ray into against state that the geometry was in when the client fired the shot, not the state the geometry is currently in according to the server.

Right now in roblox this is very difficult and annoying to do. It would be great if I could just give FindPartOnRay an amount of time to scroll back into the geometry history. e.g. FindPartOnRay(ray, ignore, nil, nil, 1) will cast against the geometry as it was 1 second ago.

5 Likes

Wouldn’t that require saving all of the part positions/change in positions and such 60 times a second, (Memory intensive), therefore causing lag?

It’d be 20 times a second since that’s the network refresh rate. I think Sharksie’s idea/intentions are good but something about this feels flawed. There’s still ping variants to account for. If I have 40 ping and the other guy has 200 ping we will likely never see the same things happening at the same time.

3 Likes

While saving geometry data and such from previous times seems expensive, it’s not unheard of, as there are a lot of time-control games (not on ROBLOX of course), but that means it could probably be done on here via the program’s base. However, it is possible to do yourself, as I did manage to make some fairly simple time controls too (on ROBLOX), it just requires a decent bit of memory and property manipulation, which means it could potentially be CPU expensive (I’m not one for optimizing my code very well, oops).

However, I do have another solution if this is ever an issue for fighting games with latency potential:
I’m not sure if this’d work for the scenario you have, but on the Star Wars game Patrickblox and I have been working on, I made it so whenever a saber hits a player, both players have to be within 8 studs of eachother from the server’s perspective in order for the hit to be successful, regardless of if the saber is touching them from the server’s perspective or not. This is only a basic anti-lag system, but prevents players from lagging like mad and attacking from what appears to be across the map, a problem my own game seems to face a lot (because it’s old code, haha).

What you could do is have the client send the “hit” packet with a position of where the bullet landed on the client’s screen too, then do a quick distance check on the server for a rough guess of “well it probably hit them if it was only this far.” I know it’s not entirely precise, but it’s a quick and easy solution, and if anything, you can change it later without much trouble.

That’s not the intention. All I care about is what the shooter saw on his screen. This is called favor the shooter and it is a standard solution to this problem that most popular shooters use, e.g. Overwatch

3 Likes

While I would definitely use this I wonder how practical your implementation is. The game would have to track all moving parts under the impression that you might raycast back in time, instead it makes more sense to have to specify parts to track and then add a way to raycast through them at some time (and perhaps all other parts).

Just yesterday I created a bullet system that required me to solve this very same issue. I produced a clock synchronization module which will certainly help to an extent Roblox-Miscellaneous/shift at master · bradsharp/Roblox-Miscellaneous · GitHub

3 Likes

O
But actually wouldn’t the only geometry needed to be saved are the players’ characters (assuming map is static)? (Just save the upper torso/humanoid root part cframe and the animation the player is in)

Then when you want to Raycast, make fake npcs positioned there (transparent and not cancollide) and ignore the regular characters.

Having non static map would really complicate things though (and be very memory intensive, even if u choose not to use the function!), so I think if roblox implements this feature, they should only do it for character previous positions (most maps are static anyways)

What I do is convert it to a unit ray, then use ClosestPoint to compare the point the server gets and the ray of the client to check if conceivably it could have hit (hacky but works)