Client was sending Time.get_ticks_msec() (e.g. 12345) as the input tick, but the server's drain_for_tick only processes inputs where tick <= current_tick (a small frame counter). Inputs accumulated in the queue and were never processed, making movement keys unresponsive in live mode. Use GameState.current_tick from the latest snapshot. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>