#Voice chat

Voice is a shared arcade capability, like multiplayer and leaderboards. Arcade.voice gives a 1v1 game peer-to-peer WebRTC audio over a realtime room you already have. There is no media server, and audio never touches our backend. It rides on the room's WebSocket as the signaling channel, so if your game already does PVP over Arcade.realtime, adding voice is a couple of lines.

#Drop it into a PVP game

You need a connected RealtimeRoom (see multiplayer).

const room = await Arcade.realtime.join("match:abc123");
const voice = Arcade.voice.attach(room);    // does NOT grab the mic yet
const unmount = voice.mountControls(hudEl); // mic button + peer speaking dot
// …later, on teardown:
voice.leave();   // stop mic, close the connection, tell the peer
unmount();       // remove the widget (safe to re-mount on another screen)

attach() is cheap and grabs nothing; the mic is requested only when the player clicks Join voice (browsers require a user gesture). The remote audio plays through a hidden element on document.body, so a session survives swapping out your screen's DOM. Attach in a lobby, re-mount the controls in the match, and the call never drops.

#API

voice.join();                // acquire mic + negotiate (user gesture)
voice.setMuted(true);        // mute/unmute local mic, tells the peer
voice.leave();               // full teardown; safe when idle
voice.on("state", (s) => …); // fires immediately, then on every change
voice.mountControls(el);     // returns an unmount fn

state: { status: "idle"|"connecting"|"connected"|"failed", muted, peerPresent, peerMuted, speaking, peerSpeaking }. Use mountControls for the stock widget, or build your own UI off on("state").

#Reliability

STUN-only today (Google's public STUN). Direct P2P works on most home/office networks but can fail behind strict/symmetric NAT or VPN, where status goes to "failed". To add a TURN relay, change getIceServers() in packages/sdk/src/index.ts to fetch short-lived creds from a new /realtime/voice-ice endpoint (same pattern as the realtime token); no other code changes.

#Limits

1v1 only. No multi-peer, recording, push-to-talk, or text chat.

View docs/guides/voice.md on GitHub ↗