## 🐛 Bug Fixes
- **Fixed protection not working for most surface players** — a broken `effectiveVoidY`
calculation in the packet handler was setting the hide threshold to Y=-12 for players
between Y=15–47, making bases fully visible. Underground blocks are now always hidden
correctly at the configured `void-y`.
- **Fixed raycast and move handler fighting each other** — when a player dipped just below
`surface-y`, `onPlayerMove` would deactivate protection instantly, then the raycast task
would re-activate it 250ms later, causing rapid state flipping and chunk refresh spam.
The move handler now defers to the raycast task inside the raycast zone.
- **Fixed eye-Y vs feet-Y inconsistency** — the raycast task used eye position (~1.6 blocks
above feet) while the move handler used feet position, creating a dead zone where neither
system owned the state. Both now use feet-Y consistently.
- **Fixed raycast overshoot** — the vertical ray was cast `surfaceY - eyeY + 2.0` blocks,
overshooting past the surface and registering false positives from surface-level blocks.
## ✨ New
- **Raycast deactivation debounce** — protection now waits a configurable delay before
deactivating when a player leaves the raycast zone, preventing flicker at the boundary.
Configurable via `protection.raycast.deactivation-debounce-ms` (default: `500`).
## ⚙️ Config
- Added `protection.raycast.deactivation-debounce-ms: 500` — existing configs are
automatically migrated on first load (no manual edits needed).
Developer information
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle.
maven { name = "Modrinth"; url = "https://api.modrinth.com/maven" }