What's the most efficient way to make a slow moving projectile that can hit multiple people, but only once each?

What’s the most efficient way to make a slow moving projectile that can hit multiple people, but only once each? Has to be able to hit NPC’s and players.

What I’ve tried so far:
My first thought was to make a data table then add people to it the first time they got hit. If they weren’t on the table, they’d be added and the effect would resolve. If they were it would ignore them. The issue there was lag. Adding a debounce created a window where sometimes people in the crowd wouldn’t get hit because the attack was repeatedly hitting the same person, seeing they were hit before, then not doing anything until the debounce wore off.

I’ve been told to try raycast+whitelist but I don’t see an efficient way to do that without repeatedly firing it off like a pulse grenade, which seems inefficient.

3 Likes

You could detect when the player gets hit on the client, then tell the server they got hit. To prevent exploiting, do a sanity check on the server so nothing crazy happens.

EDIT: This obviously won’t work with NPCs…

4 Likes

It sounds like you’ve set up your debounce incorrectly. You should only disable hitting for that specific player, not hitting entirely.

2 Likes

Make a value in the projectile once a player is hit. Make the name or value of that value the players name or the player, then make sure that when someone is hit, their name isn’t already a value in the projectile. Alternatively, you could make a table and do the same thing.

1 Like

The issue I’m having there is that you need to check if they’ve been hit.

If you hit someone then check if you’ve hit them before and you have, then DON’T activate the debounce then the function for checking if they’ve been hit will fire a boat load of times. That’ll create lag.

It has to debounce after hitting someone unconditionally, even if it’s hit them before, otherwise the action it takes to check if it’s hit someone before will fire far too many times for efficiency

1 Like

It will not create lag

3 Likes

My first thought was to make a data table then add people to it the first time they got hit. If they weren’t on the table, they’d be added and the effect would resolve. If they were it would ignore them. The issue there was lag. Adding a debounce created a window where sometimes people in the crowd wouldn’t get hit because the attack was repeatedly hitting the same person, seeing they were hit before, then not doing anything until the debounce wore off.

Making it not debounce after hitting someone it’d hit before would cause it to fire too many times at once and create lag.

You say that but it already did. I’ve already tested it, but I’ll try again and get back to you

Perhaps he’s referring to latency?

I’m assuming your projectile and hit detection is done locally, if so, then it should instantaneously be able to create the value and prevent it from firing to many times, etc. It depends on what you’re doing for detection as well, but the methods I suggested should work without causing lag or hitting the player multiple times.

Good point. This post is too ambiguous – there are too many variables to account for. Can you upload a simple repro file?

2 Likes

My detection was done serverside from the script that created the projectile, I thought that having hit detection being done locally would make latency a bit more of a problem involving it. I’m not entirely sure how I’d go about making a projectile’s hit detection local, since you have to use a server script to make the projectile to begin with don’t you?

Would I just have to fire to the server to make the projectile, then fire back to the client once it’s made?

Fire the projectile on the server. On the player, detect if the projectile hits their character. If it does, tell the server it hit their character. This should make it feel less “laggy” since the client will be able to detect if it gets hit faster than the server.

There will be latency either way. If you do it on the server, every client has to receive that information from the server. If you do it on the shooter client, not only does the client have to send it to the server the server then has to send the data to everyone else. You might ask, why would anyone do this on the client then? It’s more latency than on the server. The benefit, is that it feels good on the shooter client, because the reaction is instantaneous.

I would recommend making this a physical part on the client, send a remote to the server so it also creates a part the, set the network ownership of that part to the client so that they can control it instantly, and when the client texted the server has created the projectile, delete the local one and replace it with the server, moving it to where it was on the client. You need to do it this way because you cannot set network ownership on the client. Since the projectile is using roblox’s native physics, assuming you’re using a vector force or similar, Roblox will handle the interpolation and similar stuff for you. Once this is done, you can do hit detection on the server, and while there will be latency, it will not be very severe because the projectile is slow moving.

3 Likes

Make the part on the server then set the network ownership to the client, then do what?

Are you saying to make the projectile serverside, give network ownership of it to the client, then once it’s hit the target delete the projectile and recreate it at the point of impact serverside? I’m still a bit new to this so this is a bit foreign to me.

1 Like

I was suggesting just detecting if the rocket touches someone on the client.

Projectile.Touched:connect(function(part)
   if part.Parent == game.Players.LocalPlayer.Character then
      --Tell the server projectile was touched by us.
   end
end)

I’d have to communicate back to the client what the rocket is though wouldn’t I, since it’s created serverside.

The idea I’m getting is to create the projectile serverside, then detect clientside when it collides with someone, then fire to the server once that happens and make stuff happen

1 Like

EDIT: Your idea is exactly what I mean.

No, you can listen for the rocket on the client, assuming you’re parenting it somewhere the client has access to.

Alright I’ll give it a try

EDIT: I’m gonna try both, whichever I can get working to the best of my ability I’m gonna post as a barebones free model for anyone that stumbles upon this thread because they have/had the same issue as me.

1 Like

I highly recommend not using touched or at least only if the projectile is going to use something like cylindrical casting instead of raycasting as first of all it is a bit inaccurate (especially if not done on client) and it is also harder to customize the projectiles motion and get stuff like the surface normal of what it hit. Also the best way to go about doing this is to simulate the projectile on all clients and have server check if the hits from the client were valid (or server itself simulates it but accounting for latency). Anyway you can also do something like this in order to ignore people you hit

local list = {mycharacter}
--in movement loop
local hit,pos,norm,mat = workspace:FindPartOnRayWithIgnoreList(myray,list)
--check if hit person
table.insert(list,hitcharacter) --ignore this character and its descendants