How should I handle projectile ammo to prevent server lag?

I’m currently working on a 3rd person food themed pvp game and thought it kinda makes sense to have projectiles instead of just instant hits.

My original plan was to make the projectiles on the server and then insert a BodyVelocity so that it moves in the direction the player shot and have a script with a touched event inside so that when it’s touched it’ll deal damage and then destroy itself.

I realise that this is now a bad idea, especially if most players use a Minigun as it’ll noticeably lag the server.

Then my next thought was to make the projectile on the client that shot and then fire to the server so that it’s seamless for them, and then fire to all the clients apart from the player that shot and make the projectile. But then another problem arises where the player could just remove the BodyVelocity inside the projectile and then set the position of the bullets to whoever they want to kill.

I’m not quite sure what other method there is to handle projectiles. Any help would be appreciated!

This is what I do. The OP is the only important part.

You still seem to fire the projectile on the server though which returns to my problem with my original plan. If users are using a Minigun, that’s a lot of bullets fired per second and it would most definitely lag the server.

Are the projectiles anything more than a visual effect? I don’t see why a minigun should have projectiles in the first place.

Raycasting should work fine for that, if not, you could handle the damage separately from the bullet script.

EX:
Player shoots
Bullet appears and goes to the position where the shot went
Bullet disappears
Server Handles Damage

It’s a food themed PvP game so the weapons use food as ammo which is why i’m doing projectile based. Plus I think it would be a nice effect.

I was planning on having a touched event in the projectiles so that when they’re touched, they’ll damage if there’s a humanoid and then destroy themselves.

I can’t think of any other way to determine if the projectile hits someone.

I’m doing Projectile bullets.

How would the Server handle damage if I don’t use a touched event? I don’t know how to determine if a bullet hits a player without using a touched event.

You’re right, but still RayCasting is the best way to make a bullet projectile from what I know, you could clone the bullet and add it to debris, at same time, move it using raycast.

I don’t understand what you mean by “moving it using raycast”.

I know how to make a projectile, but I’m trying to think of what the best method is to handle it such as do I just do it on the server so it replicates to all players; but then that would definitely cause lag on the server if i’m also using a touched event in each bullet.

If I do it on the client, then the client can just TP the bullet to the player and pretty much instantly kill them.

I mean using the raycast as a source for the bullet to spawn(moving around the beam, rotating and dealing damage), but the bullet will actually only be a model that destroys itself once it touches someone.

I should actually put as a source this script from 2013 I just found…

function MoveBullet(Bullet)
while Bullet.Transparency < 0.9 and Bullet do
local ray = Ray.new(Bullet.CFrame.p, (Bullet.CFrame.lookVector).unitBulletSpeed/10)
local hit, position = game.Workspace:FindPartOnRay(ray, Player.Character, false, true)
local toIgnore = script.Parent.Parent:GetChildren()
while hit and not hit.CanCollide and Check(hit) == “Ignore” do
table.insert(toIgnore, hit)
hit, position = game.Workspace:FindPartOnRayWithIgnoreList(ray, toIgnore)
end
if hit then
Hit(position, Bullet, hit)
Bullet.Transparency = 1
elseif not hit then
for i = 1,10 do
wait(0.01)
Bullet.CFrame = Bullet.CFrame + Bullet.CFrame.lookVector
BulletSpeed/100
end
end
end
end

This will definitely cause lag on the server though, which right now is the problem i’m trying to fix and the point of this post.

Though I could of named the title better and I’ve redone that.

The server should be the one to handle projectiles so that each player is only affected by their own latency, rather than their latency and the latency of the person shooting at them. Doing otherwise also allows some players to exploit altering their latency.

To handle the graphical portion, you could use a Beam. This beam would need to be created by whoever is the network owner of the gun to keep it in sync.

To handle the physics portion of the bullets, instead of ray casting once per bullet you could weld a single part between the source and destination. This avoids having to raycast often (which doing repeatedly is slow because it doesn’t cache relevant information between calls) and relies upon the much faster collision physics. This collision part should be owned by the server.

If you use special physics to introduces curves (like gravity) then I’d use multiple collision parts to recreate the path to the desired accuracy. It is unfortunate there is no ‘let me know when something obstructs this path’ event. The alternative is to perform a raycast for each segment repeatedly to obtain the desired accuracy… which I do not recommend. :slight_smile:

In general the principle is the same: Since each bullet is doing about the same thing, combine the computations for them.

Hope this helps!

You can also just handle all projectiles locally and server will just hitcheck with lag compensation and trajectory. Ammo checks can be done over time similar to fire rate checks. Lag makes it harder to detect either so if it happens frequently it is easier to spot.

I definitely had a brain fart when posting this question haha.

Quick question though, say I do it like this:

Player Shoots
Bullet is created client side
Fire Remote Event on Server and then fire another remote event to all the other clients to create the same bullet

Do you think there will be any noticeable difference in the original projectile and the ones created on all the other clients? I don’t want Player A to hit someone, while on Player B’s screen the bullet hasn’t touched yet

Can be compensated for by doing something such as sending player pings to the clients so they can figure out the ratio of their ping to someone elses and travel back in time to shoot from there

That went right over my head.

the pings can be used to estimate how much time it took for the data to reach the client. i.e. client A has 50 ms ping and client B has 50 ms ping, would go back about 1 second and shoot from there. that or shoot toward where they aimed at at that time instead of shooting it from that point.

Here are my questions/comments:
(a) when you say handle all projectiles locally, are you talking about the client actually creating the bullets locally without being replicated to the server for graphics? That’s a pretty good idea,! Some testing would have to be done to see if clients can handle multiple rail guns.

(b) This sounds like what I was suggesting, but with compensation for lag. I’d say that the server’s representation is a happy medium of all the clients so needs no lag compensation. When lag is compensated for, it reintroduces the possibility for clients’ lag to affect each other, allowing exploits. Running on the server, each person is only affected by how much lag they have. The client shooting can have their graphics interpolated to make the lag less noticeable.

(c) An ammo check isn’t ringing a bell to me, could you expound a bit?

(d) same as above

(e) The pronoun ‘it’ seems to be ambiguous here; are you talking about ammo checks or fire rate checks?

both, you do not want to do a one-time check because it could be lag. make sure ping and shots during that request are somewhat aligned. also make sure they dont shoot like 1.25x their clip before a reload event is fired