Quick answer: Server-authoritative movement bugs live in the gap between the server position truth and client prediction. Players report rubber-banding, snapping, and rejected moves. Capture both the server authoritative position and the client predicted position at report time, plus the reconciliation correction applied and recent input history, then group duplicates so a real reconciliation bug separates from ordinary high-ping correction.

When the server owns the truth about where everything is, the client only predicts, and every movement bug lives in the gap between those two views. Server-authoritative movement is the right architecture for any competitive or cheat-sensitive game, but it makes for a confusing class of bug reports: players describe rubber-banding, getting snapped backward, walking into an invisible wall, or having a move simply rejected, and all of these are the visible symptom of the server and client disagreeing about position. The only way to debug them is to capture both positions at once. This post covers how to report and track server-authoritative movement bugs by capturing server truth alongside client prediction.

The architecture that creates the bug class

In a server-authoritative model the client predicts its own movement locally for responsiveness, sends inputs to the server, and the server, which holds the authoritative simulation, periodically corrects the client to match reality. This is the correct design for preventing movement cheats, but it means the client is routinely showing a position that is a prediction, not the truth. When the prediction and the authoritative state diverge enough, the server forces a correction, and the player sees a visible jolt. Most movement complaints are players experiencing these corrections, which are normal, mixed in with the few that are genuine bugs.

The whole difficulty of debugging this class is that the symptom, a position that suddenly changes, is identical whether it is correct behavior under bad network conditions or an actual reconciliation bug. A player on a high-ping connection will see legitimate corrections constantly. A player hitting a real bug, a desync that never reconciles, a correction that snaps to a wrong position, sees something that looks the same to them. You cannot tell these apart from the complaint, only from capturing what the server and client each believed at the moment of the jolt.

Capture server truth and client prediction together

The single most important practice for these bugs is to capture both the server authoritative position and the client predicted position at the same instant a problem is reported. One position alone is useless: the client position tells you what the player saw, the server position tells you what was true, and the bug is in the difference between them. Capture both, along with the timestamp and the tick they correspond to, so you can measure exactly how far apart they were and in which direction the correction pushed the player.

With both positions in hand, the diagnosis becomes concrete. A small, brief divergence that reconciles cleanly is normal prediction error under latency. A large divergence, a divergence that grows over time, or a correction that moves the player somewhere the inputs could never have taken them, is a real bug. Capturing the pair turns an unfalsifiable I keep rubber-banding complaint into a measurable quantity: the position error in units, how long it persisted, and whether reconciliation ever closed it. That measurement is the foundation for every other movement bug investigation.

Reconciliation and the correction mechanism

Reconciliation is the process by which the client, after receiving an authoritative update, rewinds to the corrected state and replays its unacknowledged inputs to get back to a plausible present position. This is where the genre subtle bugs live. If reconciliation replays inputs incorrectly, drops some, or applies the correction without replaying, the player gets snapped to a stale position and loses the inputs they made in the meantime. A reconciliation bug feels like the game stealing your movement, and it is maddening because the player did everything right.

To debug reconciliation, capture the correction event in detail: the authoritative state received, the buffer of unacknowledged inputs at that moment, and the resulting position after replay. When a player reports being snapped back unfairly, this record shows whether reconciliation replayed their inputs correctly or discarded them. A common bug is an input buffer that is too small under high latency, so inputs are dropped during replay and the player is corrected too far back. Capturing the input buffer alongside the correction is what reveals whether reconciliation itself is the culprit rather than the network.

Rejected moves, invisible walls, and collision authority

Because the server is authoritative, it can reject a move the client already predicted, which produces some of the most frustrating bugs in the genre. The player walks somewhere on their screen, the server says no, and they get yanked back, an invisible wall. This happens when the server collision or movement validation disagrees with the client, due to a geometry mismatch between server and client maps, a validation rule that is too strict, or a desync in the moving platforms and dynamic geometry the player is interacting with. The player experiences a wall that is not visibly there.

Capture the rejection context: the move the client attempted, the server reason for rejecting it, and the relevant collision geometry version on both sides. When a player reports an invisible wall, this shows whether the server and client are running different collision data or whether a validation check is firing incorrectly. Grouping these reports by location frequently reveals a specific spot on a specific map where the server and client geometry disagree, which is a concrete, fixable defect. Without the rejection reason and geometry version, an invisible-wall report is nearly impossible to act on, since you cannot see the wall the player is hitting.

Setting it up with Bugnet

Bugnet gives your game an in-game report button that captures movement state the instant a player flags a problem. Wire it to attach the server authoritative position, the client predicted position, the divergence between them, the last reconciliation correction with its input buffer, and any recent move rejection as custom fields and player attributes. Because these bugs are invisible without both the server and client view, this paired capture is what makes a rubber-banding report reproducible. Crashes during movement, such as a physics fault on a moving platform, arrive with full stack traces and device context for immediate diagnosis.

Occurrence grouping cuts through the steady background of normal corrections that players report as bugs. The many reports about getting snapped at one map location fold into a single counted issue, so a genuine geometry desync stands out from scattered high-ping corrections. Filter by map location, ping band, or client version using custom fields, and a reconciliation bug that only affects high-latency players or an invisible wall confined to one map spot becomes obvious in a single view. You prioritize by how many players each genuine bug affects, with the captured position pairs giving engineers a measurable starting point.

Testing under latency and tuning the model

Server-authoritative movement bugs hide at high latency, so you must test under simulated network conditions, not just on a fast local connection where prediction and truth rarely diverge. Use a network condition simulator to introduce realistic latency, jitter, and packet loss, and watch for corrections that fail to reconcile or input buffers that overflow. The position-pair data from real player reports tells you which latency ranges produce the most genuine bugs, so you can target your simulated testing at exactly the conditions your players actually experience rather than idealized ones.

Use the captured data to tune the model itself, not just to fix individual bugs. The distribution of position divergences across your player base tells you whether your interpolation, input buffer size, and correction thresholds are set right for real conditions. If high-ping players see frequent large corrections, the model is too aggressive and needs a larger buffer or smoother blending. Disciplined movement bug reporting, anchored in captured server-versus-client state, does double duty: it fixes the sharp bugs and continuously tunes the netcode so the whole population gets smoother, fairer movement over time.

Server-authoritative movement bugs are invisible from one side. Capture server truth and client prediction together and the rubber-banding becomes a measurable divergence.