Fly: the gravity curve is the whole check
An airborne player in Minecraft is not free to be anywhere. Their vertical velocity decays every tick according to a fixed rule, whatever they are doing: subtract a constant, then scale by a constant. A jump is that curve starting from a fixed initial velocity; it lasts about a second and gets a player a little over a block off the ground. A fall is the same curve running negative and accelerating.
So the check almost writes itself: while a player is in the air, their height must obey that curve. Two things are asked, and neither can be answered by sending more packets or by jittering the reported height, because both are measured against the wall clock rather than against packets, and both against the most generous legal trajectory:
- They must come down, at a rate far below gravity's but far above a hover's. Every effect that legitimately slows a fall and is invisible to the proxy — slow falling above all — still brings a player down by metres a second. A hover does not.
- They must never get far above where the stretch began, because nothing that starts at a jump's initial velocity and decays gets more than about a block and a quarter up.
The hard part is knowing they are in the air
Here is the trap. The movement packet carries a flag saying whether the client believes it is standing on something, and a fly module simply sets that flag to true. A check that reads it is checking a value the cheat authored.
The only honest source is the world the server streamed to the client. The proxy keeps a window of the blocks around the player and reconstructs what is under their bounding box.
Two details make the difference between a check that works and one that accuses innocents:
It has to use the bounding box, not one column. A player standing on the corner of a block is over four different columns at once. Ask about the single column at the player's rounded position and a fly module that parks itself on a block boundary reads as standing over nothing at all — which is a flag against a player who is genuinely standing still.
"Not solid" and "unknown" are different answers. A block table that only vouches for certain full cubes will report the same "not a full cube" for a slab, for a fence, and for air. Collapsing those into "no floor" means every player standing on a slab is in free air by the check's reckoning. The verdict needs three states, and the accusing one — nothing is holding this player up — has to be a proof. An unloaded chunk, a carpet, a boat, a ladder or a block the build has no opinion on all fall short of proof, and on those the check must say nothing at all.
Timer: the rate is the cheat
A vanilla client sends one movement packet per tick, twenty times a second, because that is what its tick loop does. A timer hack raises the loop's rate, and everything the client does speeds up with it — moving, mining, attacking, all of it. That makes the movement packet rate not a symptom of the cheat but the cheat itself, which is why it is one of the strongest signals available.
Measuring it naively flags everybody, though. Networks stall, and when a stalled connection recovers the client's buffered packets arrive in a burst. A check that counts packets in a fixed window sees that burst as a timer hack.
The fix is a token bucket run backwards: every movement packet spends a token, and tokens refill at exactly the vanilla tick rate. A client that has been quiet — because its connection stalled — has banked credit, so the catch-up burst costs it nothing. A client genuinely ticking faster than the game does drains the bucket continuously and cannot stop, because slowing down is the thing the cheat exists not to do.
Speed: measure the sustained average, not the tick
Horizontal speed sounds like the simplest check of all and is the one most likely to go wrong, because the legal maximum genuinely varies. Ice, slime, elytra, potions, mounts and a dozen plugin effects all raise it, and a proxy that cannot price every one of those does not know the exact ceiling for this player at this moment.
The wrong answer is to guess a tight budget and flag honest players. The right one, absent full block context, is a generous ceiling on a sustained average — a value no lag spike and no single fast tick can reach, and no speed module can stay under, because staying under it is the same as not cheating. The check is deliberately loose and it still works, because a speed hack's whole purpose is to be sustained.
No-clip: the cheapest possible test
If a player claims to be standing where a full solid cube is, they are inside it. That is one comparison against the block window and needs no history.
What makes it safe is the block table being conservative. Only blocks that are certainly full cubes count as solid, so a slab, a fence, a door or a pane of glass is treated as passable and brushing one never accuses. And one tick inside a block is a client and server disagreeing for a moment — a door swinging, a piston firing, a landing on a laggy connection. It is the sustained run that means a player is simply ignoring collision.
Jesus: walking on liquid
A player crossing water is either in it or on something. Jesus is the third case: the body stays above the surface, nothing solid is underneath, and the crossing continues. One tick of that is a jump over a puddle, so it takes a sustained run to accuse — and the run has to cover real ground, or bobbing at the edge of a pool would look the same.
What honest players do that looks like cheating
Worth stating explicitly, because these are the situations a badly written check punishes:
| Ordinary situation | What a careless check sees | What stops the false positive |
|---|---|---|
| Connection stalls, then catches up | A burst of movement packets — a timer hack | Banked credit in the token bucket |
| Standing on a block corner | Nothing under the player — flying | Testing the whole bounding box |
| Standing on a slab or carpet | No solid floor — flying | "Not a full cube" and "no floor" kept distinct |
| Elytra, ice, a speed potion | Impossible horizontal speed | A ceiling on a sustained average, set generously |
| A door swinging into the player | Standing inside a block — no-clip | Requiring a sustained run |
| Jumping across a stream | Standing on water — Jesus | Requiring sustained travel over liquid |
Every one of those is why a movement anticheat should accumulate a decaying violation level rather than act on a moment, and why a corrective teleport is a better first response than a kick. Both ideas are covered in What is a Minecraft anticheat?.
Combat cheats leave completely different evidence and are covered in Killaura and reach hacks.