Concepts
This page explains how play-u1 is structured so the rest of the guides make sense. When you are ready for the full API surface, continue to Input events.
The big picture
GamepadManager— one place for connect/disconnect, a singlerequestAnimationFrameloop overnavigator.getGamepads(), andGamepadDeviceinstances with named inputs via layouts.GamepadDevice— per-controller API: subscribe to presses, holds, sticks, triggers, rumble, and snapshots.
Raw Gamepad objects use opaque button indices and axis numbers. Layouts map them to stable names like A, LS, LT.
Lifecycle: start and stop
start()registersgamepadconnected/gamepaddisconnectedand runs the rAF polling loop.stop()tears that down: no more frames, no more connection listeners.
The first subscription to onConnect, onDisconnect, onAnyPress, or onAnyInput calls start() if the manager was idle—which is why the quick start can omit start() when you begin with onConnect.
In environments without window (SSR, some tests), start() is a no-op until a browser global exists.
Manager-level listeners
| API | When it runs |
|---|---|
onConnect | A new GamepadDevice is tracked for a physical gamepad. |
onDisconnect | A tracked device goes away. |
onAnyPress | Any named button goes down on any device — handler receives (event, pad). |
onAnyInput | Any input change on any device — handler receives the GamepadDevice. |
Each on* method returns a disposer. Call it to remove that listener.
Dead zone
Pass deadzone into createGamepadManager (or call setDeadzone later).
- A number — radial dead zone: small stick vectors snap to center; the outer range is rescaled so full tilt still reaches magnitude 1 by default.
DeadzoneOptions—radial, optional per-axisaxial, andrescaletoggles.
Exact math: resolveDeadzone and applyAxisDeadzone in the API reference.
Layouts (names instead of indices)
Each GamepadDevice uses a LayoutProfile: maps raw button and axis indices to names like A, LS, LT.
detectLayout(rawGamepad)picksxboxLayoutforstandardmapping or common Xbox / XInput IDs; otherwisegenericLayout(Button0,Axis0, …).createGamepadManager({ layouts: { 'VendorName': myProfile } })adds profiles. Keys match as case-insensitive substrings ofgamepad.id.manager.setLayoutForId('DualSense', playStationLayout)updates patterns at runtime.
Built-in exports: xboxLayout, genericLayout, detectLayout from @interfaces-technology/play-u1.