Local parties, gamepads and phone controllers in PlayDrop games
Read physical gamepads and PlayDrop phone controllers through sdk.device, follow local player slots, declare controller support and local party sizes.
A local party is several people playing on one screen, each with a controller: a physical gamepad or a phone that PlayDrop turns into a controller by scanning a code. Your game reads every controller the same way through the SDK, on the website and in the apps.
Declare controllers and party sizes
{
"types": ["solo", "party"],
"party": { "local": [1, 2, 3, 4] },
"controller": { "support": "optional", "type": "simpler" }
}controller.supportisoff,optionalorrequired. Declare it on every game, includingoff.controller.typenames the minimum controls the game needs:any(directions, Confirm and Cancel),simpler(one stick, four face buttons and Menu; phone controllers qualify) orstandard(D-pad, two clickable sticks, four face buttons, two shoulders, two triggers and Menu).party.locallists the exact player counts on one screen; a1requires thesolotype. With controller support on, every listed count must be playable with controllers.
Read controllers
await sdk.device.enableControllerInput().catch(() => { /* keep keyboard and touch */ });
const stop = sdk.device.onButton(({ playerIndex, button, pressed }) => {
if (button === "south" && pressed) jump(playerIndex);
});
function update() {
for (const slot of sdk.device.localPlayers) {
const pad = sdk.device.gamepad(slot.playerIndex);
if (pad?.connected) move(slot.playerIndex, pad.axes[0], pad.axes[1]);
}
requestAnimationFrame(update);
}
update();- Call
enableControllerInput()once afterinit(). It rejects withcontroller_input_unavailableorcontroller_input_timeoutwhen the host cannot provide input; the game keeps running. gamepad(playerIndex)returns a snapshot in the browser's standard layout:axes(left x/y, right x/y from -1 to 1), seventeenbuttons,source(physicalorvirtual) andid.playerIndex0 is player 1.- Buttons have positional names such as
southandeast.pad.label("south")gives the prompt to show: "A", "Cross" or "B" depending on the controller.pad.has("dpad")tells whether a control exists. - Menu and Home belong to PlayDrop and always read released.
- Never call
navigator.getGamepads(): phone controllers only reach games through the SDK, and PlayDrop logs a warning.
Local player slots
sdk.device.localPlayers lists the slots players chose, { playerIndex, gamepadKey }, and onLocalPlayersChange(callback) reports changes. A disconnected controller keeps its slot. When the roster changes or becomes empty, return to a sensible menu instead of crashing. One controller on its own is ordinary input, not a party.
From a button, sdk.social.openParty({ mode: "local" }) opens PlayDrop's pairing window with the phone QR code and connected gamepads. Offer only the modes you declared.
Local or online, not both
The host starts a game either as a local party or an online one, never both: local players cannot join online rooms. For online play with friends see online parties and voice.
Design for the couch
Show each player's color and controller prompt, let anyone press a button to join, and keep the HUD readable from a sofa. Keep touch and keyboard controls for solo play.