Quick answer: Pygame queues max 128 events. Mouse motion at 1000Hz pollers can flood it and drop key events. Block MOUSEMOTION via pygame.event.set_blocked and read mouse position/delta via pygame.mouse.get_pos/get_rel each frame.

Here is how to fix Pygame games where moving the mouse during gameplay causes key presses to be dropped or laggy. The event queue is bounded; high-frequency motion events can crowd out everything else.

The Symptom

Player swings mouse and presses keys. Some key events never reach your code. Or input feels laggy when the mouse moves a lot.

What Causes This

Bounded queue. 128-event default capacity. Overflow drops oldest events.

High mouse poll rate. 1000Hz mice generate ~16 motion events per frame at 60 FPS.

Per-frame consumption insufficient. If pygame.event.get is called less than once per frame, the queue fills.

The Fix

Step 1: Block MOUSEMOTION events.

import pygame
pygame.init()
pygame.event.set_blocked([pygame.MOUSEMOTION])

Stops motion events from queuing. Other events get full queue capacity.

Step 2: Poll mouse state directly.

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: running = False
        # handle KEYDOWN, MOUSEBUTTONDOWN, etc.

    # Mouse state via polling, not events
    mx, my = pygame.mouse.get_pos()
    dx, dy = pygame.mouse.get_rel()   # delta since last call
    handle_mouse(mx, my, dx, dy)

get_rel reports cumulative delta since the previous call — equivalent to summing all dropped MOUSEMOTION events.

Step 3: Always drain the queue each frame. Call pygame.event.get exactly once per frame at the top of your loop. Skipping frames lets the queue fill.

Step 4: For raw mouse delta in FPS games, use mouse.get_rel after pygame.event.set_grab.

pygame.event.set_grab(True)
pygame.mouse.set_visible(False)
# In loop:
dx, dy = pygame.mouse.get_rel()
# Use dx/dy for camera rotation

Step 5: Verify queue health with peek.

n = len(pygame.event.peek())
if n > 100: print(f"Queue near full: {n}")

If consistently high, there is a queue consumption problem.

“Block MOUSEMOTION. Poll position via get_pos/get_rel. Drain every frame. Keys never drop.”

Related Issues

For Pygame multi-monitor tearing, see Display Flip Tearing. For mixer end events, see mixer.music End Event.

set_blocked MOUSEMOTION. get_pos/get_rel. Drain queue. Inputs reliable.