One-line summary
Add Settings → Hotkeys (name TBD) where users assign keyboard keys or chords to any currently available animation; pressing a hotkey plays that clip once, then restores whatever animation was selected in Gear → Animations (Default loop, a looping VRMA, etc.).
Problem / motivation
Power users and streamers want quick motions without opening the gear menu. Today every clip change goes through Animations and updates the persisted animationId. There is no way to fire a one-off gesture (wave, peace sign, custom VRMA) and return to the ongoing Default sequence or loop.
As the catalog grows (bundled pack + future custom folder), a dedicated binding UI scales better than memorizing menu order.
Proposed solution
Settings UI — Hotkeys / Keybindings section
- New accordion under Settings (desktop-first; browser dev may register keys only while page focused).
- Table/list of all selectable animations at runtime:
- Bundled Default + VRMA pack when Directories → Animations is Default.
- Custom folder clips when custom animations directory is active (see
16-custom-animations-directory.md).
- Each row: animation label (+ group hint) · Record / assign key control · Clear.
- Support:
- Single keys (e.g.
F5, 1…9 with modifier guardrails)
- Chords (e.g.
Ctrl+Shift+W)
- Multiple bindings for the same animation (e.g.
F3 and Ctrl+1 both → Peace Sign)
- Conflict detection: warn or block if the same chord is assigned twice; show which animation owns it.
- Optional: “Reset all hotkeys” row action.
Playback semantics (critical)
Hotkey triggers are overlays, not a new persisted selection:
- User has Gear → Animations set to Default (or any looping clip X).
- User presses hotkey for clip Y.
- Play Y with
playback: 'once' (even if Y loops when selected from the menu).
- When Y finishes, resume the menu selection (Default sequence / loop X) without changing saved
animationId or the active radio in the Animations menu.
- If another hotkey fires during Y, queue or replace per design (document: recommend replace current one-shot; ignore if same key spam — optional cooldown).
Do not write hotkey-triggered ids into animationId in config.yaml. Only the Animations menu selection persists as today.
Implementation hint: reuse or extend the existing animationRequest / mixer path in VrmAvatar so menu animationId stays stable while a transient one-shot runs.
Input scope
- v1: Hotkeys active when the AVATAR window is focused (overlay or windowed). Document limitation.
- Later (optional): Global shortcuts via Electron when overlay is pinned — needs design + OS conflict notes; not required for v1.
config.yaml
New block, e.g.:
animationHotkeys:
- animationId: vrma-03
keys: ["F3", "Ctrl+Shift+P"]
- animationId: lib-anim-my-wave-abc123
keys: ["F4"]
- Validate on load: drop bindings whose
animationId no longer exists (custom folder changed).
- Persist with autosave like other settings; cleared on Reset all settings.
- Document schema in User settings.
Edge cases
| Case |
Behavior |
| Hotkey for Default while Default is selected |
Run greeting/intro once, then resume main Default loop (or treat as no-op — decide in design) |
| Custom folder empty / switched back to Default |
Prune orphan bindings; UI shows “missing animation” for stale rows |
| Overlay menu open |
Hotkeys still work (preferred) or suppressed — pick one |
| Browser dev |
Local key listener only; no global hook |
Alternatives considered
Primary surface
Settings / persistence
Constraints you accept
Mock / sketch / reference (optional)
Settings → Hotkeys accordion: scrollable list, “Click to bind” pill per row, conflict toast. Gear → Animations unchanged; hotkey flash optional (out of scope v1).
Out of scope (separate issues)
One-line summary
Add Settings → Hotkeys (name TBD) where users assign keyboard keys or chords to any currently available animation; pressing a hotkey plays that clip once, then restores whatever animation was selected in Gear → Animations (Default loop, a looping VRMA, etc.).
Problem / motivation
Power users and streamers want quick motions without opening the gear menu. Today every clip change goes through Animations and updates the persisted
animationId. There is no way to fire a one-off gesture (wave, peace sign, custom VRMA) and return to the ongoing Default sequence or loop.As the catalog grows (bundled pack + future custom folder), a dedicated binding UI scales better than memorizing menu order.
Proposed solution
Settings UI — Hotkeys / Keybindings section
16-custom-animations-directory.md).F5,1…9with modifier guardrails)Ctrl+Shift+W)F3andCtrl+1both → Peace Sign)Playback semantics (critical)
Hotkey triggers are overlays, not a new persisted selection:
playback: 'once'(even if Y loops when selected from the menu).animationIdor the active radio in the Animations menu.Do not write hotkey-triggered ids into
animationIdinconfig.yaml. Only the Animations menu selection persists as today.Implementation hint: reuse or extend the existing
animationRequest/ mixer path inVrmAvatarso menuanimationIdstays stable while a transient one-shot runs.Input scope
config.yamlNew block, e.g.:
animationIdno longer exists (custom folder changed).Edge cases
Alternatives considered
animationId) — wrong UX; user loses Default loop selection.Primary surface
Settings / persistence
Constraints you accept
Mock / sketch / reference (optional)
Settings → Hotkeys accordion: scrollable list, “Click to bind” pill per row, conflict toast. Gear → Animations unchanged; hotkey flash optional (out of scope v1).
Out of scope (separate issues)