What is the best way to create a gun system that does not cause server lag? Here is my current system:
Client fires CanFire() function to check if weapon can fire on server-side.
If can fire, client fires Fire() event to server.
Raycasting, hit detection, bullet tracer and particles are then done on server.
Client plays firing animation.
With this system, I get problems when theres more than 6 players in server. The fire rate of gun is not constant, hit detection is bad, bullet tracers and particles lag behind. Any tips how to make a more smooth firing experience?
Whats the point of this, it isn’t secure either, an exploiter could just fire the Fire() remote, unless if you valid checks for this. What I do to reduce lag is create ammo on the client and the server. When a client shoots the server reduces the ammo count by 1, same for the client. And if the ammocount is 0 and the client shoots, the server doesn’t create a hit detection projectile for it. Since my server projectiles basically raycast to the next point of there destination, without a model. If they are hit then they do damage. So if the ammocount in the server is 0 then the server doesn’t create this hitbox projectile.
This eliminates the need for remotefunctions which does two way communcation which takes time. Just subtract the ammo on the server when the client uses the Fire() remote, and do the same on the client.
Client and server have there own ammo systems, client one for ledgit players, server one to prevent exploiters.
ALso how much is your firerate, I can handle 4 bullets made every frame just fine. So I can handle 240 bullets a second with no lag, depends on what your doing.
The lag starts when a few players start spamming their guns. I am not sure how many rounds per seconds, but it isn’t that high. I feel like the server-lag happens is due to everything being handled by the server. It is too much for the server to fire rays, create tracers which use tweens to animate and create particles.
Note: I am using a object pooling for both tracers and particles.
I am working on a new system, which fires gun on both local and server sides. The server only checks if the shot was valid and tells other clients to draw tracers.
After you work on that system, the lag will be reduced tremendously, by doing client side projectiles, and non model server projectiles, I can handle 800 projectiles a second.
What about too many raycasts? I have a custom mouse raycast to ignore some parts, then I have to raycast on client in the direction of where mouse hit, then the server has to raycast also in the direction of mouse hit, to make sure the shot was valid. I feel like the amount of raycasts might affect performance.
I raycast to the next point of my destination for each bullet, and they travel 400 studs, with a velocity of 400. This happens every frame so I create raycasts for EACH bullet 60 times. And I can handle 400 bullets a second so that;s a lot of raycasts, raycasting is a cheap process. Plus this is done on the server and the client.
Basically raycasting is super cheap and shoudn’t affect perofmrance. Anything else you do which you think affects performance those might be why?
Constant firerate? All I do is put a RednerStepped:wait() and it works, on the client, or do you mean for validlty checks on the server to see if theres to many bullets being shot by the client each second? For that just do a tick() check.
For higher amounts like 1 second just use a renderstepped loop and check if one second has passed between the last shot on the client.
Your using wait() right? Don’t use wait(1), instead run the loop each hearbeat and checked if an x amount of seconds hass passed before the last shot, using tick()
Combine CanFire() and Fire() into a single remote. The client should just fire Fire() and assume they did. The server can then allow or disallow that action and the client will just see their bullet not do any damage.
Also, clients should draw their own bullets as soon as they fire.
If I combine CanFire and Fire, how will the client know if shot happened? Due to security reasons, the canFire() function checks if there is enough ammo and firerate. So then how will the client know if there is enough ammo or if client can fire?
They do the check locally, and then the server confirms later. You don’t want a full round trip network delay between the client pressing fire and the gun firing!
Why are you doing client ammo checks on the server, just make an ammo system on the client and the server. Subtract 1 from the server and the client when they shoot. If the ammo is 0 then don’t register the server projectile for hit detection.
if im saying it confusilgly ask me so I can explain it better.