Currently, I am making a projectile system. Here is how it works:
Server uses a remote event to notify client to create projectiles. (Using RunService and CFrame multiplication to move projectile)
Server creates a “projectile” of its own without creating a new instance. (Same math as client)
IF client detects that the projectile made contact with something, it causes an explosion at the area.
IF server detects that the projectile made contact with something, then it creates an AOE in which enemies get damaged on the server.
Although this does work, sometimes, the client detects projectile contact while the server doesn’t and vise versa.
So here is my solution: Make ONLY the server handle the hitbox and use a remote event to make the projectile explode on the client.
example (server)
if ProjectileDetected then
Remote:FireAllClients("ExplodeProjectile", parameter)
end
However, the problem I’m facing is allowing the client to know which projectile to explode and destroy. Sure, I can assign a random ID for each individual projectile and use that ID to explode individual projectiles. However I don’t think that is quite optimized. Are there other ways to go about this?
Maybe when server notifies clients to create a projectile, the server send its own projectile that is the same (the part instance) so you use it as a reference in the client instead of an ID.
for exemple :
local clientProjectilesList= {}
CreateProjectileEvent:OnClientEvent(projectile)
local clientProjectile = ...
--create the same projectile on client
table.insert(clientProjectilesList, clientProjectile )
end
ProjectileDetectedEvent.OnClientEvent(projectile, parameter)
clientProjectile = clientProjectilesList[projectile]
--Explode it
end
Creating a new instance to act like a reference might be… GENIUS! The only concern with this is that I don’t want to create any new instances. However, I’m pretty sure it’ll not be that big of a deal if I just use something like a ValueBase.
Server creates a new valuebase and parents it in to cache folder
Server gives the path of the valuebase to the client
Client stores the valuebase in a dictionary and assigns it to a projectile
When the server detects a hit (I’m using GetPartsBoundInRadius), it uses a remote event and passes the valuebase assigned to that projectile, destroying it on the client
This is pretty unrelated to your issue, but why did you decide to have projectiles on the client and server, and why instead of using physics-based projectiles, you go for one that runs off of cframe-manipulation?
I actually don’t have an instance-based projectile on the server. It runs off of RunService and CFrame manipulation. (Calculations to find the current CFrame of the client projectile, and then use spatial query to check for hits) ONLY the client creates the projectile instance, which is visual. I am doing this to reduce load on the server.
I am using CFrame manipulation so I can detect projectile hits on the server without creating new instances. (and it syncs to the client)
Side Note: You CAN use physics-based projectiles but I personally prefer CFrame manipulation more as I don’t want to do extra calculations on the server.