🔥 Advanced Feature
Controller button combos in Running Scripts use The Vault's Universal Button Mapping system, supporting 70+ button aliases across PlayStation, Xbox, and Nintendo controllers.
Controller Button Combos
Running Scripts can be triggered by controller button combinations, giving you complete control over in-game actions without touching the keyboard.
Syntax
Controller combos use the controller+ prefix followed by button names:
::controller+button1+button2 {
your code here
}Universal Button Mapping
The Vault's Universal Button Mapping system translates button names across different controller types. This means you can write scripts using friendly names that work with any controller:
PlayStation (DualSense / DualShock)
::controller+share+options {
-- Uses PlayStation naming
do shell script "kill -INT {{{PID}}}"
}Xbox
::controller+view+menu {
-- Same script, Xbox naming
do shell script "kill -INT {{{PID}}}"
}Nintendo Switch Pro
::controller+minus+plus {
-- Same script, Nintendo naming
do shell script "kill -INT {{{PID}}}"
}All three examples above are equivalent! The Universal Button Mapping system normalizes button names, so share = view = minus = select = create.
Common Button Aliases
A few of the most common aliases are shown below. The modifier (the held Select-style button) is create on a DualSense and capture on an NSO GameCube pad:
| Button Type | PlayStation | Xbox | Nintendo | Generic |
|---|---|---|---|---|
| Face Buttons | cross/✕, circle/○, square/□, triangle/△ | a, b, x, y | a, b, x, y | button1-4 |
| Shoulders | l1, r1 | lb, rb | l, r | - |
| Modifier (Center Left) | share, create | view | minus, capture | select |
| Center Right | options | menu | plus | start |
See Appendix C: Controller Reference for the complete Universal Button Mapping reference (70+ aliases across every vendor).
Real-World Examples
Example 1: Graceful Exit (ARMSX2)
Hold Share/Create (PlayStation) or View (Xbox) or Minus (Nintendo), then press Options (PlayStation) or Menu (Xbox) or Plus (Nintendo) to gracefully exit ARMSX2:
::controller+share+options {
-- Try graceful termination first
do shell script "kill -INT {{{PID}}}"
delay 2
-- Force kill if still running
do shell script "kill -9 {{{PID}}} 2>/dev/null || true"
}running-script-example-controller.png - Code example: controller combo script (1440x900)Example 2: Quick Screenshot
Hold L1 (PlayStation) or LB (Xbox) or L (Nintendo), then press Triangle (PlayStation) or Y (Xbox) or X (Nintendo) to take a screenshot:
::controller+l1+triangle {
do shell script "screencapture ~/Desktop/{{{GAME}}}_screenshot.png"
display notification "Screenshot saved!" with title "{{{GAME}}}"
}Example 3: Multiple Triggers
You can define multiple controller combos in one script:
::controller+share+options {
-- Exit emulator
do shell script "kill -INT {{{PID}}}"
delay 2
do shell script "kill -9 {{{PID}}} 2>/dev/null || true"
}
::controller+l1+triangle {
-- Screenshot
do shell script "screencapture ~/Desktop/{{{GAME}}}_screenshot.png"
}
::controller+r1+circle {
-- Quick save
tell application "System Events"
keystroke "f1" using command down
end tell
}How It Works (Priority 1 System)
Controller combos in Running Scripts use Priority 1 execution, which means they are checked before controller profile hotkeys (Priority 2). This ensures your custom scripts always take precedence over default hotkey mappings.
Execution Flow
- User presses buttons: Share + Options (or View + Menu, or Minus + Plus)
- UnifiedControllerService detects input: Normalizes button names using Universal Button Mapping
- Priority 1 check: GlobalHotkeyService checks for matching Running Script
- Match found: Execute script, stop propagation (Priority 2 not checked)
- No match: Continue to Priority 2 (controller profile hotkeys)
Debugging Controller Combos
If your controller combo isn't working:
- Check permissions: Ensure Input Monitoring is enabled (System Settings → Privacy & Security)
- Test with dialog: Replace your script code with a simple message box to verify detection
::controller+share+options { display dialog "Combo detected!" buttons {"OK"} } - Check console output: Look for "✅ [Priority 1] Found controller running script" in logs
- Try different aliases: Use
select+startinstead ofshare+options - Verify button names: See Controller Reference for all supported aliases
Best Practices
- Use friendly names:
share+optionsis clearer thancreate+buttonmenu - Test incrementally: Start with dialog boxes before implementing kill scripts
- Document your combos: Add comments explaining what each combo does
- Avoid conflicts: Don't overlap with critical emulator hotkeys (save states, etc.)
- Graceful > Force: Always try
kill -INTbeforekill -9
💡 Pro Tip
Controller combos work across all emulators that use the same Running Script. Define your combos once in a shared script, then reference it from multiple emulator configurations.