@dloizides/game-input
v1.0.0
Published
Framework-agnostic game input primitives. v1 ships safe, player-toggleable haptics (Vibration API wrapper, localStorage-gated, zero deps). Extracted from Aurora; consumed across EisaiPollis games.
Maintainers
Readme
@dloizides/game-input
Framework-agnostic game input primitives. v1 ships safe, player-toggleable haptics — a thin wrapper over the Web Vibration API that no-ops silently when disabled, unsupported, or blocked, so call sites can fire haptics unconditionally alongside their SFX/visual feedback.
Zero runtime dependencies. Isomorphic (no DOM lib required — navigator and storage are structural and
injectable), so it works in browser games, React Native shells, and tests alike.
Scope note: keyboard/gamepad normalization is intentionally not in v1. The games that were audited (Aurora, Morphe) implemented input with fundamentally different designs — there is no shared logic to extract yet. It will be added when a genuine 2nd same-stack consumer appears (extract-on-2nd-use).
Install
npm install @dloizides/game-inputUsage
import { createHaptics, HAPTIC_PATTERNS } from '@dloizides/game-input';
// One controller per game; the storage key namespaces the player's preference.
const haptics = createHaptics({ storageKey: 'aurora.haptics' });
// Fire unconditionally — disabled/unsupported just no-ops.
haptics.vibrate(HAPTIC_PATTERNS.tap); // menu navigation / selection
haptics.vibrate(HAPTIC_PATTERNS.success); // level cleared
haptics.vibrate([0, 14, 24, 14]); // or your own pattern
// Settings toggle — returns the new state, fires a confirming tick when enabling.
function onHapticsToggle(): boolean {
return haptics.toggle();
}
haptics.isEnabled();Semantic pattern vocabulary
HAPTIC_PATTERNS is a shared set of tuned vibration patterns keyed by intent, so every game uses the same
feel instead of re-picking magic durations:
| Intent | Pattern | Use |
|---|---|---|
| tap | 10 | menu nav / select / undo / restart |
| select | 12 | pick up a tool/charm/item |
| lock | 18 | something locks into place |
| bump | 24 | action blocked |
| navigate | 16 | portal / page turn |
| success | [0,40,50,90] | level/chamber cleared |
| error | [0,14,24,14] | fatal/destructive event |
| loss | [0,40,50,40] | player loses / falls |
| reveal | [0,14,20,18,26,24] | puzzle resolves / exit opens |
API
createHaptics(options?)→Haptics—{ isEnabled, setEnabled, toggle, vibrate }.options.storageKey(defaultgame.haptics) — localStorage key for the on/off preference.options.enableConfirmation(default a15ms tick; passnullto disable) — fired when turning ON.options.navigator/options.storage— inject for tests/RN; default toglobalThis.
HAPTIC_PATTERNS,DEFAULT_HAPTICS_STORAGE_KEY,DEFAULT_ENABLE_CONFIRMATION.
License
MIT
