Skip to content

Host rooms

Moderation

Keep a room pleasant with mutes, kicks, bans, passwords and join verification.

Mute

setPlayerMuted() silences a player's room chat, direct messages and typing indicator until you unmute them or they leave.

Kick and ban

kickPlayer(id, reason, ban) removes a player and shows them the reason. With ban: true, the service also refuses them for the rest of the room's life. A room holds up to 256 bans; lift them with clearBan() or clearBans().

JavaScript
const offensive = /\b(idiot|loser)\b/i;
const strikes = new Map();
room.onPlayerChat = (player, text) => {
  if (!offensive.test(text)) return;
  const count = (strikes.get(player.id) ?? 0) + 1;
  strikes.set(player.id, count);
  if (count >= 3)
    void room.kickPlayer(player.id, 'Repeated abuse', true);
  return false;
};

Bans are applied by the Ball2D service. If it cannot confirm a ban, the command rejects and the player stays, so handle the rejection.

Private rooms

A password keeps a room to people you invite. Set one at creation or later with setPassword(); pass null to open the room again. Leave public off to keep the room out of the list; it stays reachable by link.

Join verification

setRequireVerification(true) asks each joining player to pass a human verification challenge first. It slows automated joins without affecting players already in the room.

Watch for trouble

Handle onPlayerKicked to log what admins do from the game, and onPlayerActivity to find idle players:

JavaScript
const lastSeen = new Map();
room.onPlayerActivity = (p) => lastSeen.set(p.id, Date.now());
room.onPlayerJoin = (p) => lastSeen.set(p.id, Date.now());

// Move players idle for a minute to the spectators.
const timer = setInterval(() => {
  for (const player of room.getPlayerList()) {
    if (
      player.team !== 0 &&
      Date.now() - (lastSeen.get(player.id) ?? 0) > 60_000
    )
      void room.setPlayerTeam(player.id, 0);
  }
}, 10_000);
room.signal.addEventListener('abort', () =>
  clearInterval(timer),
);