Quick answer: Use bitwise AND, not equality: if event.mod & pygame.KMOD_SHIFT. event.mod is a bitmask of all active modifiers.
Shift+S should save the game. Players report it doesn’t work when Caps Lock is on. Your code does if event.mod == pygame.KMOD_SHIFT — which fails because event.mod has the Caps bit set too.
Bitmask vs Equality
Multiple modifiers can be active. event.mod is the OR of every active modifier:
event.mod = KMOD_SHIFT | KMOD_CAPS # Shift held + Caps on
Comparing with == KMOD_SHIFT requires Shift alone. Use AND to test presence:
if event.type == pygame.KEYDOWN:
if event.mod & pygame.KMOD_SHIFT and event.key == pygame.K_s:
save_game()
Tests only the Shift bit; other modifiers can be on or off without affecting the test.
Common Modifiers
- KMOD_SHIFT (either Shift), KMOD_LSHIFT, KMOD_RSHIFT
- KMOD_CTRL (either Ctrl), KMOD_LCTRL, KMOD_RCTRL
- KMOD_ALT (either Alt), KMOD_LALT, KMOD_RALT
- KMOD_CAPS (Caps Lock state)
- KMOD_NUM (Num Lock state)
- KMOD_META (Windows/Command key)
Querying Current State
mods = pygame.key.get_mods()
if mods & pygame.KMOD_SHIFT:
running()
For continuous checks (is shift currently held while moving), get_mods queries the live state independently of events.
Exclusive Modifier Test
If you specifically need “only Shift, no other modifiers”:
only_shift = (event.mod & ~pygame.KMOD_CAPS & ~pygame.KMOD_NUM) == pygame.KMOD_SHIFT
Strips ignored state (Caps/Num) and tests the remaining for exact Shift. Rare requirement; usually AND is what you want.
Verifying
Test Shift+S with Caps off, with Caps on, with Num on, etc. Save should fire in all cases. Without the fix, Caps-locked save attempts silently fail.
“event.mod is a bitmask. AND for presence. Equality is wrong unless you specifically want exact-state modifiers.”
Treat modifier checks like permission flags: AND-test for ‘has it’, not equality. Same pattern across most input APIs.