Where an anticheat sits
Protecting a Minecraft server has two halves that people often confuse. The first is admission: stopping floods, screening connections, asking uncertain ones to prove an account or a human. That is covered in Minecraft bot attacks and Minecraft server DDoS protection.
The second half starts after all of that succeeds. Every admission gate is bounded — hold a real account, read a code, reconnect once — and each is a cost a determined person pays once and then forgets about. A player who holds a genuine account, solved every challenge and whose client ticks exactly like a real one can still fly across the map, hit somebody through a wall, or walk through a locked door.
An anticheat is the layer that watches what a session does, one packet at a time, and asks whether it was possible.
Why the game's own physics are the ruler
Minecraft's movement is not vague. An airborne player's vertical velocity decays by an exact rule every tick, whatever they are doing. A jump is that curve starting from a fixed initial velocity and lasting about a second, and reaching a little over a block of height. A fall is the same curve running negative. A vanilla client sends one movement packet per tick, twenty times a second, because that is what its tick loop does. A player's arm reaches about three blocks.
Those are not thresholds somebody tuned. They are the game, and that is what makes cheat detection tractable at all: you are not asking "does this look suspicious", you are asking "is this consistent with the only physics the client is allowed to have".
The subtlety is that the client is the thing reporting its own position, and every value in that report is something a cheat can lie about. The most-abused example is the "on ground" flag: a fly module simply sets it to true and claims to be standing. So a check that trusts that flag is checking nothing. The fix is to reconstruct what is holding the player up from the blocks around them — the world the server streamed, which the client did not author.
And that reconstruction has to be honest about its own uncertainty. A slab, a ladder, a boat, an unloaded chunk or a block this build has no opinion on all mean the same thing: no proof either way. The correct behaviour there is to say nothing at all, not to guess. "Nothing is holding them up" has to be a proof, not a default, because everything that gets built on top of it accuses a player.
Violation levels, not verdicts
The second structural idea is that a check should not produce a verdict on one packet. It produces a violation level.
Every check contributes to a running score for that player, and the score decays continuously over time. A player who trips a check once an hour — a lag spike, a mispredicted landing, a plugin doing something unusual — never accumulates anything. A player running a module trips the same check constantly and climbs. Different consequences hang off different heights of that score: nothing at all, then a corrective teleport, then a kick, then a temporary ban.
Decaying the score continuously rather than resetting it on a timer matters more than it sounds. It means there is no window boundary for a cheat to hide behind, and nothing has to sweep old records to keep the system honest.
Setbacks: the correction that is not a punishment
Kicking is not the right first response to a movement violation, and neither is ignoring it. The correct response is to make the movement not have happened.
If the offending movement packet is dropped, the server never learns about it — but the client keeps predicting locally and the two drift apart. So after dropping, the player is sent back to the last position that was forwarded. From the cheater's side this is the rubber-banding everyone recognises: they fly, and they snap back. From the server's side the illegal movement simply never occurred. Nobody is removed, no appeal is needed, and the cheat produces no advantage — which is a better outcome than a ban, because it does not require anyone to be certain.
The categories of cheat
Different cheats leave completely different evidence, so they are covered by separate checks with separate logic:
- Movement — fly, speed, no-clip, walking on water, and timer hacks that speed up the whole client tick loop. See Minecraft fly, speed and timer hacks.
- Combat — killaura, reach, aimbots, autoclickers and velocity modifiers that ignore knockback. See Killaura and reach hacks.
- World — X-ray, nuker, scaffold and tower. See X-ray, nuker and scaffold detection.
- Protocol — clients that simply send more than a client can send. An in-session packet flood is its own category, and it is not the same thing as a connection-level rate limit: a client that joined legitimately and then opens the taps costs the server exactly as much as a connection flood does, and nothing at the connection layer counts it.
Why false positives are the expensive failure
This is the design decision that shapes everything else. The cost of a missed cheat is one annoyed server for a while. The cost of a false positive is a paying customer's real player being thrown off their own game, with no idea why, and no way to argue about it. Those are not symmetrical, so the defaults should not be either.
In practice that means: tolerances that widen with a session's round-trip time, because a distant player is genuinely swinging at where a target used to be. Sustained runs rather than single events, because one moment of anything has an innocent explanation. Statistical checks kept deliberately weak. And a monitor mode, where every check runs and records but nothing acts, so an operator can see what enforcement would have done before turning it on.
There is a good cautionary example in the history of aim detection. A tempting rule says that a real mouse reports whole counts scaled by a sensitivity setting, so genuine rotation deltas should share a common divisor while an angle computed from a target's position does not. It is elegant, and it is wrong: Minecraft's yaw step lands on the protocol's angular quantum cleanly at essentially one sensitivity setting and at no other, so the shared divisor collapses and the rule flags nearly every honest player. A rule that catches cheaters and honest players alike is not a strict anticheat, it is an outage.
Why the proxy is a good place for it
A traditional anticheat is a plugin. That works, and it has one structural weakness: it lives inside the server, competing for the same tick budget it is trying to protect, and it depends on the server operator keeping it updated across game versions.
Running the checks in the protective proxy in front of the server changes three things. It sees the raw packet stream in both directions, so it can measure what the client sent against what the server told the client. It does not spend the server's tick budget. And there is nothing on the player's machine for a cheat client to disable, because the analysis is not on the player's machine.
It also has a real cost worth stating plainly: to read packets, the proxy has to speak the game protocol for that client's version rather than just relaying bytes, and play-state packet numbering shifts on nearly every Minecraft release. That is why deep inspection is opt-in per server rather than the default, and why a version whose format is not proven degrades to no inspection rather than to guessed inspection. A wrong guess about a packet layout is a reach flag against an innocent player.
What good anticheat evidence looks like
When a check fires, the useful record is not "player X was flagged". It is which check fired, what the measured value was, what the legal value was, and when. That is what makes an operator able to answer a complaint, and it is what makes a check that is too strict visible as a spike of one specific reason rather than as a vague rise in unhappiness.
Kick messages should say the opposite: as little as possible. Naming the rule that fired tells whoever wrote the cheat exactly which half to fix next. The reason belongs on the flag record, for the operator who needs it — not on the screen of the person trying to beat it.
Itnetic's game protection runs these checks at the edge, in front of the server, with monitor and enforce modes and a per-check configuration.