Replicating Random Bullet Spread

I’m trying to create bullet spread for my guns, but I’m not sure how I would do this securely. Basically I render the bullet on the client when u click and send that data to the server. How would I make sure both the server and client have the same angle for spread?

After some research I saw that when the client starts it requests a remote function that returns a table of pseudorandom numbers which get iterated through every time u fire a bullet. As well as making sure that the remote function can only be called once by each player would make it so the exploiter would need to read throughout you’re script to get an accurate number for each spread.

Or another option was to just send a pseudorandom number through the remote event each time u fire, which could result in exploiters sending dead accurate shots each time. I was thinking that I could maybe do some checks so that the client can’t send a number that was already used before and then invalidate the shot.

The last option was to just screw it and send the number through the remote event making sure that the same number wasn’t sent in a row, but if it’s spot on, it’s spot on.

What are u feelin?

1 Like

You’ve essentially already mentioned the optimal solution: You use a random number generator on both the server and client that returns the same stream of random numbers on both. Roblox actually has a way for you to do this, through the Random class.

You’d essentially just need to initialize the random sequence with the same seed on the server and the client. You could just use a hard-coded seed for that as I don’t think players would notice it’s the same sequence of random numbers every time considering the fast-paced gameplay.

Important to note is that in order for this to work, the random number generators you use have to be used exclusively for bullets and have to be called at the same rate on both sides. Any slight difference is going to cause the state of the random functions to de-synchronize and cause bullets to appear differently for the client than they actually are.

3 Likes

What would happen if there’s a de-sync between the server and client and the client shoots 2 bullets that the server won’t detect? Wouldn’t that make the recoil on the server and client different from then on?

Wouldn’t a system where the server generates a new recoil value every time the client fires a bullet and fireclient() back that new recoil value each time be better… Or would cause too much network strain with the back and forth firing between the client and server?

Yeah, if it de-syncs, the server bullets are permanently different from the client bullets. Small offsets like one or two bullets won’t matter much with an automatic weapon but it could become quite jarring if individual bullets matter a lot. Normally this shouldn’t happen, though, as RemoteEvents guarantee that all information makes it across the server/client boundary as long as the player is connected.

You wouldn’t want to ask the server for a new value, not because it’d overload the network but because the client would then have to wait for a response from the server before firing a shot. My ping to Roblox game servers is between 50 and 150 milliseconds normally, so this would cause a very noticeable delay. If you’re firing an automatic weapon you’d also run into an issue where your rate of fire actually depends on how fast your connection to the server is, giving players that are physically closer to the server even more of an advantage than they already have.

The client doesn’t need to wait for the server to fire the gun it will just keep on shooting its client side bullets and firing to the server for the server to shoot its own server sided bullet.

In the case of de sync or lag spike the client would be corrected due to the server constantly sending what everybody else in the server sees as your current ammo, current recoil, etc.

I guess the only problem would be that the client under high ping might see extra bullets being shot?

Yes, this is what I originally suggested. The client and server both generate their own spread values and fire their own bullets - the only thing replicated to the server is the fact that a bullet was fired, from which position and in which direction. The server has all the other information already.

This is true, but you have to be careful about how you synchronize this information. If the server sends back a new packet every shot to update ammo counts and such, then the client would be able to fire more shots than what it has ammo for because the actual ammo count is lagging behind. You could work around this by keeping track of the ammo count on the client as well (you should do this anyways) and only sending an update packet a short while after the last bullet was fired, and ignoring that sync packet if the client fired more bullets in the time that it took to replicate.

Unfortunately, yes. There isn’t ever a perfect way to handle networking in such a fast-paced environment, so temporary desynchronizations are unavoidable. Roblox makes this relatively comfortable for us by guaranteeing that the data we send is also received by the other party, in the correct order, but that doesn’t take care of many of the jarring effects that such replication comes with, and handling those is where the difficulty lies.