Client VS Server Authoritative Timing (ANTI-EXPLOIT)

Hey guys!
“The client should never be trusted” has killed me over one mechanic. I have a power bar UI that sets the power for a certain attack. This needs to be accurate to the client since it is UI and input based.

A remote event fires from the server to client to show and start the power bar locally. A remote event is then fired back to the server once input has been shot. This makes server/client consistency in value trackng tough with ping, network transit and packet priority.

The way i originally was handling it was by doing a config speed which was shared by the time the server send the remote event. The client would then send back a stop event where the server would try and assume where the power bar ended. This was so inaccurate EVERY TIME. And this is important in my game where depending on when the client clicks could determine win or loss.

I have right now resorted to the client sending the data of where they stopped the bar which on the server I am trying my BEST to validate this by clamping from 0 to 1 and trying to find inconsistencies such as sending the same value repeatadly over X amount of games. This feels the best to play but it doesnt sit right with me.

Some people may say “why does the exact float returned matter, surely the server’s one will do and the player wont know”, false in my case. The power bars exact output matters for the attack damage multiplier but it also has categories of “Okay”, “Good”, “Great” and “Perfect” which are simple visual colour goals on the bar. So sometimes the gap would mean the player hit Great but the server determined it as Great or vice versa which is not right at all.

The remote event communicating back passes two values:

    1. The zone it landed in (“Okay”, “Good”, “Great”, “Perfect”)
    1. The exact landed value float (anywhere between 0-1)

Current server validation checks:

  • Player must be in specific match instance
  • Player can only send this remote event once per state instance active
  • Value must be between 1 and 0
  • Zone name must be valid from config file
  • The value must be within the zones valid range

There is no way I can think of to accurately take the players input and align it with a server prediction to validate it. So in theory, an exploiter could still send “Perfect” and 0.99857477 and then the next go “Perfect” and 0.9736466 and my systems will think it is completely fine.

Any tips?

2 Likes

I’ll be honest, if this power system is something that an okay or skilled player can typically hit every time? It may not even be worth your stress patching, in fact I too don’t think it’s possible.

The real questions worth thinking about currently are:

  1. How do I keep it fair and accurate for legit players to compete with those cheaters?
  2. How do I make cheating not worth it?

Or if this power system IS a huge advantage and game breaking for other players if you get perfect every time, then..
3. If I really want server involvement, how do I design around latency instead of pretending it doesn’t exist?

I’ll say this but, I’m sure you’re smart enough to have done this:

  • Only accept “power result” in the exact state where the bar should exist.
  • Ignore packets that arrive at wrong times (like 3s after bar should’ve ended).

And for cases like these stop thinking “I must validate each event” and start thinking “I must validate the player over time.”

If you REALLY REALLY care you can:

  • Count # of attempts per match / per hour → (if high, likely exploit spamming the proper float)
  • Distribution of results:
    • % Okay / Good / Great / Perfect
  • Time between bar start and result (you can approximate on the server)

Then:

  • If a player has 90–100% Perfects over hundreds of attempts → suspicious.
  • If they do so across many matches, consistently → extremely suspicious.
  • Auto flag for manual review or auto-action depending on how hardcore you want to be brother

Goodluck, definitely a tedious case bro

2 Likes

If you wanted to pursue a completely server authoritative system, you could schedule skill checks several seconds in advance. Let’s suppose you have a shared tick system between the client and server; the server tells the client, “Hey, you are getting a skill check, it’s scheduled for tick 200.” The client, on tick 100 would get the message and schedule a UI skill check on tick 200. They perform the skill check, and send a response back to the server with an event precisely when they performed the action. You would then calculate what zone the skill check landed in by what time the client says they pressed their button at.

This is a way more complicated way of doing skill checks, and can surely still be exploited, but would be slightly more secure than being able to send a float value 0-1, and instead would have to report on the exact time expected within the skill check window.

Hope this helps, or gives you some ideas on how to approach this.

1 Like

Interesting! Yeah this is a good one which would work with the state I am working on. How would you go about establishing a shared tick system especially with ping? Only thing I could think of is it send an empty remote function or something and determine the delay but again this could easily fluctuate. Am I missing another method?

To be honest the system isn’t that make or break. The main combat still comes down to your aim realistically. But I think I am just trying to get into the habit of stopping exploiters earlier on in development as I learnt that the hard way :sob:
I appreciate your insights homie

1 Like

In this particular case, as others have said as well, I don’t think you realistically can do anything without seriously risking false positives. So I’d personally leave it as is. But if you realllly wanna try then you can add additional checks for how often / when / what values get sent, but sieving out anyone but obvious cheaters would be very difficult if not impossible.