Quick answer: set_allowed and set_blocked mutate one shared event filter. A later set_allowed can re-permit what you blocked. Configure the filter once, in one place.

A game calls pygame.event.set_blocked(pygame.MOUSEMOTION) to skip mouse-move spam, but the events keep coming — another part of the code called set_allowed later.

One Shared Filter

There’s a single event-allowed filter. set_blocked(x) removes x from it; set_allowed(x) adds it back. They’re not separate lists — whichever runs last for a given type wins.

Configure It Once

# at startup, in one place
pygame.event.set_allowed(None)   # block everything
pygame.event.set_allowed([
    pygame.QUIT,
    pygame.KEYDOWN, pygame.KEYUP,
    pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP,
])   # then allow exactly what you handle

An allow-list is clearer than scattered block calls: it states exactly which events your loop cares about, and nothing else gets through.

set_allowed(None) Resets

set_allowed(None) blocks everything; set_blocked(None) allows everything. Start from a known state, then build your list — don’t append to whatever the filter happened to be.

Pump Still Processes Blocked Events

Blocked events are still generated — they just don’t reach event.get(). pygame.event.pump() and internal state still update. Blocking is a get-filter, not a global mute.

Verifying

MOUSEMOTION no longer appears in your event loop. The events you allow-listed all arrive. No other code re-permits what you excluded.

“One filter, last-write-wins. Set the allow-list once at startup instead of scattering block calls.”

An explicit allow-list also documents your input surface — anyone reading it knows exactly which events the game handles.