Quick answer: Pygame event.poll() missing events on busy frames? Poll returns one event per call; if your loop only calls poll once per frame, events pile up and eventually overflow.
Key presses occasionally drop. The main loop calls event.poll() once and assumes that’s enough; on busy frames multiple events queue and only one is consumed.
Drain Each Frame
for e in pygame.event.get():
handle(e)get() drains the queue. Loop processes all events per frame; nothing piles up.
Poll for Targeted Drain
while True: e = poll(); if e.type == NOEVENT: break; handle(e) — equivalent to get(), more explicit when you want to drain early.
Event Filtering
Combine with event.get(eventtype=pygame.KEYDOWN) to drain only specific types. Useful when handling subsets in different code paths.
Don’t Mix poll and get
Calling get() consumes events; subsequent poll() / get() in the same frame may return nothing. Pick one drain pattern per frame.
Verifying
Inputs feel responsive at all frame rates. No dropped key presses or mouse clicks; the event queue stays empty between frames.
“Drain the queue every frame. poll without loop = lost events.”
Stick with for e in event.get() as the default pattern — it scales from 0 events to thousands without code changes.