Creating a "powers" system that ensures security and accuracy

I’m helping a friend make a game, but my scripting skills (or lack thereof) will be the death of me.

In this game, players will have abilities that they can activate by pressing a key bind while the correct tool is selected. The abilities vary in range, but what I want to focus on for now is making two: one that is a large projectile that moves in the direction of the player, and another that is a large area of effect expanding outward from the center of the player. I’ve already learned how to make the effects and everything for this, but my problem comes from the fact that my multiple implementations of it either look laggy for players, or the visual effect is an inaccurate representation of hitbox.

Right now I’m trying to make a system that uses modulescripts in replicated storage. I did some research on the forum and modulescripts are good for when you don’t want to repeat your code. I don’t want to have 2 scripts (local and server) with exactly the same thing on it so that’s why I’m using one module in rep storage. The module contains all the code for making the actual effect and hitbox. Here’s how it works:

  1. In both the localscript (in the tool) and normal script (in serverscriptservice), require the same module

  2. On player input, localscript checks that tool is equipped properly then invokes a remote function to server

  3. When server receives invocation, it will check if the player is alive return true for invocation

  4. On the local side, it will check if true was returned then use the module to create a local version of the module code (what the player can actually see). As soon as CFrame parameters for making the effects of the ability (startPosition and lookVector) are put into variables, it will fire these to the server with a RemoteEvent

  5. On server side, it will take the parameters from the remote event and use the module to do the same thing that the local script is doing except only the server version handles damage

The reason I’m splitting it up into a server and local version is because if I made a server only version, the abilities look very laggy. Making the local version makes it look very smooth but I want to have the hitbox calculations on the server to ensure security. Unfortunately the end result from this plan is that the hitboxes are delayed behind the actual effect. Here’s a representation of what I’m talking about:

The blue effect is the only thing the player will actually see. The white outline is the hitbox and I’ve only outlined it for viewing purposes. As you can see, the hitbox is significantly delayed behind the actual effect. While it might not look that bad in the example I provided, it will be worse when the target is moving/farther/smaller.

I want to know if there’s a good way to sync these up so that the abilities don’t feel delayed to the player but still keep the effects looking smooth.

(On a side note: the white button called serversight is supposed to toggle the view for the hitboxes on and off by controlling a boolean value in workspace. In the script that makes the outline, it checks the value before making the outline. The button works in terms of controlling the bool value but for some reason, the server’s version of the modulescript is not able to see any change. If I set the value to false when I start the test server, the modulescript will always see that the value is false, despite any changes. Why is this happening and how can I fix it?)

2 Likes

just :MoveTo() the hitbox to the effect.

The server can’t see the effect as the effect is only made on the client.

ok then just do the same thing for the position for the server as the client(eg. run the client script without the visual part)

What you would want to do is have the hitbox be create on the client AND the server - the one on the client will be used for instant feedback, whilst the one on the server will be used for verification.

I’m not sure what you mean. Can you please elaborate?

I see what you mean but I don’t think it will work very well. For example say I’m a hacker and I’m flying around spamming the visual effect portion of the script. If I implemented the “instant feedback” then whenever I use the ability a person will go flying before the server says “oh wait that is not valid, you are not allowed to do that”

Hey so, i’m not exactly sure what you are trying to do here. If you are trying to do a hitbox detection then I would suggest doing an area of effect aka grab the magnitude between the position of the effect and the character’s humanoidrootpart. If you are trying to make it a design, just cframe it to the effects position. Box.CFrame = effect.CFrame

The problem I’m trying to tackle is making it so that what the player sees (handled in local script) and the actual effect (hitbox handled in server script) matches as close as possible. In the GIF above, it does not match since what the player sees does not match up with the hitbox (the blue doesnt match up with the white). The reason is because of network latency: The server has to wait before it receives the parameters from a remote event fired by the local script. If I did not have this remote event then the server might not use the same parameters that the effect does (because if I walk or move my camera in game, it takes a small delay for the server to see that).

Could try to use things like tick to get an idea of time and the difference, then just move the hitbox faster to the end point. This way depending on ping overall, you can try to get an ability that matches but it won’t be perfect in every situation.

Hmmm… while this might work for moving hitboxes, a problem is still presented with things like stationary AOEs.

You could use ping and previous locations of the players, and store them within a specific threshold. Then, just check if they were within the aoe for the tiny amount of time they would’ve been. This is my best guess to be honest, but the threshold would have to have a max distance as well with the time.

1 Like

First off, this is a little bit off-topic from your post but I’ll get onto your question in a minute:

This isn’t a very secure way of handling this information. From your GIF, I am assuming you are using the HumanoidRootPart to decide where and how a projectile moves. So surely if this is the case, you wouldn’t have to send this information over from the client to the server, as player movement replicates to the server anyway. Making it a server-side based feature would be way more secure because you aren’t defining an area where the projectile can start, and it would mean that exploiters can’t predefine a location in which the projectile is created and sent off too.

I’m not quite sure why you’d need a unique hitbox for it when you have a very basic one already! An attachment in, or The Projectile Mesh itself can be used to track collision detection. Relying on two individual parts moving on both client and server will open up a range of issues and a lot of it comes down to latency. I say, get rid of the problem by removing the hitbox, and merely tracking the first moving mesh. (so that’ll require you to make the mesh hitbox on the server)

As for the projectile moving less smoothly due to it replicating from server to client (which happens if you tween on the server), you will need to work out a solution for this. As for the aesthetics of the projectile, you can probably continue to tween them on the client if you wish, I think using something like CollectionService will help with projectiles if you aren’t using it already, as you can listen into when a specific projectile has been made and tagged, and you can perform any transparency or colour changes through the client.

3 Likes

Wow I didn’t even know that existed. Thanks! The reason why I used a remote to fire the starting position is to account for the delay between the client and server. Whenever I use what the server thinks is the position of the humanoid root part at any given time it’s always behind what the client sees and it kinda look weird when the ability is created from behind.

1 Like