Implement client-side prediction with input broadcasting
Reduces perceived lag over internet by broadcasting player inputs immediately and predicting next positions on all clients before server update arrives. Protocol changes: - Added PLAYER_INPUT message type for broadcasting inputs - Server broadcasts player inputs to all clients on every MOVE message - Includes player_id, current direction, and full input_buffer (max 3) Desktop client (Python): - Tracks input buffers and predicted head positions for all players - On PLAYER_INPUT: predicts next head position using buffered input - On STATE_UPDATE: clears predictions, uses authoritative state - Renderer draws predicted positions with darker color (60% brightness) Web client (JavaScript): - Same prediction logic as desktop client - Added darkenColor() helper for visual differentiation - Predicted heads shown at 60% brightness Benefits: - Instant visual feedback for own movements (no round-trip wait) - See other players' inputs before server tick (better collision avoidance) - Smooth experience bridging input-to-update gap - Low bandwidth (only direction tuples, not full state) - Backward compatible (server authoritative, old clients work) All 39 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ class MessageType(Enum):
|
||||
GAME_STARTED = "GAME_STARTED"
|
||||
GAME_OVER = "GAME_OVER"
|
||||
ERROR = "ERROR"
|
||||
PLAYER_INPUT = "PLAYER_INPUT" # Broadcast player input for prediction
|
||||
|
||||
|
||||
class Message:
|
||||
@@ -114,3 +115,18 @@ def create_game_over_message(winner_id: str = None) -> Message:
|
||||
def create_error_message(error: str) -> Message:
|
||||
"""Create an ERROR message."""
|
||||
return Message(MessageType.ERROR, {"error": error})
|
||||
|
||||
|
||||
def create_player_input_message(player_id: str, direction: tuple, input_buffer: list) -> Message:
|
||||
"""Create a PLAYER_INPUT message for client-side prediction.
|
||||
|
||||
Args:
|
||||
player_id: ID of the player who sent the input
|
||||
direction: Current direction tuple
|
||||
input_buffer: List of buffered direction tuples (max 3)
|
||||
"""
|
||||
return Message(MessageType.PLAYER_INPUT, {
|
||||
"player_id": player_id,
|
||||
"direction": direction,
|
||||
"input_buffer": input_buffer
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user