Help Understanding Proper Client Prediction With Server Validation (Preventing Exploits and Redundancy)

I’m currently working on a skill system for my Roblox experience, and I’m trying to understand how to implement proper client prediction without compromising server authority and security.

From what I understand, client prediction is supposed to reproduce actions before the server confirms them, which helps with responsiveness. However, I have a setup where players can choose between different game modes, and skills can only be used when a player is alive and inside the arena.

My issue is that with client prediction, some players are managing to trigger abilities in the lobby, before the server validates if they’re actually allowed to use them. I’m trying to figure out the best approach here:

  • If the client predicts and executes the skill first, how can I reliably validate that the player is in the correct game state (e.g., in the arena and alive) before showing effects or animations?
  • Adding checks on both client and server feels redundant. Is this normal or expected?
  • How do developers typically handle exploiters who might bypass client checks and force execution of abilities?
  • Would it be better to avoid client prediction altogether and stick to server-only execution, even if it introduces some input delay?

I’m trying to make the system feel smooth for players but still safe and structured. I’d really appreciate any insights or best practices on this topic before I continue building out my skills system.

If client makes something that is not possible at all even with ping delay then its 100% an exploiter and you should kick them.
Why are you overthinking so much anyway?Just check it on server lol.

Just check that they do have a character and humanoid has > 0 health

"Yeah let game guess if it can do something or not, what could go wrong? :thinking: "

Ideally?No!Even if its a dumb simulator.

I dont quite understand what do you mean by prediction?
Are you making an FPS game?
Bullet dirrection can be calculated on server using velocity and also you can’t really president most of stuff that is ahead for 2~ seconds in most cases anyway.

1 Like

My game is based on a “Hot Potato” style mechanic. So let’s imagine this scenario:

A player requests to use the skill called “Fugitivo”, which makes them temporarily invisible and adds some particles around them so other players can still roughly see their position. During this invisibility period, the player holding the potato cannot pass it to them.

How would client prediction work in a situation like this?

Also, about what you said:

“Just check if they have a character and if the Humanoid has more than 0 health”

Wouldn’t an exploiter be able to easily bypass a check like that and do much more?

And finally, I didn’t quite understand what you meant by:

“Ideally? No! Even if it’s a dumb simulator.”

Could you clarify what that means?

Exploiter has no access to that (unless you have reject character deletion disabled for some reason)

By that i mean that some sort of prediction is always good.

if the game doesnt have a lot of parkour you can try taking network ownership, im making one if u wanna test it out, but its pretty simple

  1. make the server set the network ownership of everything in the player’s character to nil
  2. make the client rebuild the player’s character to make the illusion that they have network ownership
  3. remake any broken systems (inventory, properties, etc)

And about the redundancy I mentioned earlier — would I really need to add the same validation both on the client and the server? If so, why? Do most developers actually do this?

For example, the stun animation that plays when the bomb explodes on a player (or when they die) is triggered directly from server code, and the particles are also created server-side during the explosion. That’s because all my game mode modules and the main controller module that manages them are located in ServerStorage.

So, in this structure, how would I go about doing those checks on the client if most of the logic is already handled on the server?

So client wont accidantly send data to server that it was meant not to.
That a common sense.
If you dont own for example a gamepass button you would be unable to send server event regarding that.
Althrough be careful with that incase client COULD somehow obtain access to that so you wont punish innocent players

I’m not sure if I misunderstood you or if your response wasn’t clear, but I didn’t mention anything about gamepasses :sweat_smile:

What I’m actually asking is: do I really need to add checks both on the client and the server, and how would I even do that if all the core game logic — like which game mode is active, whether I’m currently in the arena, or how many lives I have left etc… is handled only on the server?

That’s what I’m trying to figure out.

Personally, I’d make in-game functionality toggleable, that way I can fire to the clients to enable/disable their skills, combat system, or whatever. This would remove the need for client prediction and using extra memory doing checks when the player isn’t in the round. You should also have a table that keeps track of players in the match for server validation.

I think your issue stems from your game’s architecture since the way I’d describe pretty much resolves all the issues.

As for skills specifically, yes, you’d need to have the same checks on the client and server, such as health and distance between the player and opponent.

Do you think it would be a good idea to move all the game mode modules into ReplicatedStorage and keep only the main module that manages maps/modes in ServerStorage?

Inside these game mode modules, I have a function that accesses another module (which is also in ServerStorage) to grant XP/Coins when a player kills or explodes another player.

Also, the game mode modules store important data like the table of alive players, life counts, and other match-specific info.

What would be your best suggestion here?
This setup I described, or the one you mentioned earlier (which, to be honest, I didn’t fully understand either XD)?