Minecraft anticheat guide
Occlusion First-Hit Authority and Block Cache Warmup
Why an occlusion check can return unknown on the first hit, how FairPlay pre-captures block cells around online players, and what limits remain.
Why can the first hit return unknown?
When the blocks on a target's path have not been captured yet, an occlusion check returns unknown and does not cancel. Per FairPlay engineering notes dated 2026-10-19, FairPlay now refreshes the block cells around each online player's body in the background, before cached captures expire. A player who has been online through at least one warmup cycle is expected to have an embedded cobweb already observed.
FairPlay does not turn unknown results into fails. Confirmed evidence still decides the outcome.
What happened in the incident?
Two attacks against one target arrived about a second apart. The first returned unknown because the block snapshot was missing for every checked cell. Repair requests were queued only after that verdict. The second attack proved an embedded cobweb and failed.
The notes are careful here. The log had no capture timestamp, and the target's age was an entity age, not a block snapshot age. Expiry alone is therefore not proven as the cause. Cold cache, invalidation, capture latency, and packet replica lag are all possible.
What caused the gap?
How does the warmup work?
An asynchronous worker scans the block cells that overlap each online player's body, using the player's cached position. It only enqueues cells whose snapshot is missing or close to expiry, and it runs periodically rather than every tick. Each scan is capped per player and reuses the existing queue capacity limits.
Captures run on the scheduler of the region that owns the chunk. Packet callbacks and the async scan never call world or block APIs. Mutation invalidation, lifecycle checks, and world identity checks still apply, so a stale web cannot block a hit forever.
| Candidate | Decision | Reason in the notes |
|---|---|---|
| Pre-capture cells on online player bodies | Implemented | Captures the earliest missing evidence |
| Refresh cache before its lifetime ends | Implemented | Avoids unknown from expiry alone |
| Remove the confirmed cobweb downgrade | Implemented | Stops a separate, unproven bypass |
| Keep precise embedded-web geometry | Preserved | The second attack already proves it |
| Respect world, chunk, and cell invalidation | Preserved | No immortal stale web |
| Convert all unknown results to fails | Rejected | Creates unproven violations |
| Enlarge occlusion boxes or make blocks circular | Rejected | Degrades geometry and fairness |
| Scan whole chunks every tick | Rejected | Excessive CPU and memory pressure |
What does the debug output show now?
Debug output is one compact result line. It shows the result, server and client ticks, last movement age, ray distances, cache misses, pending repairs, attacker pose, target box, target age, the selected cobweb cell, the authority source, fallback use, and history proof.
When a verdict is unknown because a capture was missing, the line names that cause instead of a generic cache label. Per-cell detail stays opt-in and capped.
What was verified in this change?
The notes record a Java 8 compile of the changed code and four standalone geometry assertions that passed in the inspection environment. The Maven and JUnit suites and a live Folia replay were not run there, because the build dependencies were not available.
The notes list a compile, a targeted JUnit run, and a representative live replay as required before production use. Until you run that replay on your own server, treat the warmup as unverified there.
What are the limits?
Right after plugin activation, a world transition, or heavy world edits, captures may not exist yet. Verdicts in that window can be unknown. The notes say a full first-hit guarantee would need a separately validated damage-stage recheck or a packet delay. This change does not claim one, and it does not invent a verdict to cover the gap.
Expect the first minutes after a restart to be less conclusive, and read alerts from that window together with their debug lines.
FAQ
Does an unknown result mean the player was cleared?
No. Unknown means the check did not cancel and did not add violation level. It is an open question. Repair runs so that later attacks can be decided with real block data.
Does the warmup add server load?
The notes describe a periodic, capped scan that reuses existing queue limits and rejects per-tick chunk scans. They do not publish a load measurement, so check TPS and MSPT on a staging server with your player count.
Does this stop every cobweb hit?
No claim is made. A confirmed web with known authority fails and cancels. A web whose block data is still missing stays unknown while repair is queued, and the notes say the first moments after a change can remain open.
What belongs in a bug report about a first-hit miss?
Include the compact debug line, the attack time, whether the target had been online through a warmup cycle, and the cause the line reports. The notes do not state a timestamp source for block captures, so note any restart or world change nearby.