Skip to main content

Room Callbacks

Standard Rooms provide comprehensive callbacks to monitor and respond to all room events. These callbacks allow you to create responsive multiplayer experiences by reacting to player joins, leaves, connections, and room state changes.

Available Callbacks

CallbackTriggerPurpose
onRoomCreatedRoom successfully createdHandle room creation success/failure
onJoinedRoomSuccessfully joined a roomHandle successful room join
onMessageReceivedMessage received from playerProcess incoming messages
onPeerJoinedNew player joins roomUpdate UI and game state
onPeerLeftPlayer leaves roomHandle player departure
onLeftRoomYou leave the roomClean up and return to lobby
onRoomConnectedRoom fully connectedStart gameplay
onRoomDisconnectedRoom connection lostHandle disconnection

Room Creation and Joining Callbacks

onRoomCreated

Called when your room creation request is processed:

onRoomCreated: (status, room) => {
if (status) {
console.log('✅ Room created successfully');
console.log('Room ID:', room.roomID);
console.log('Status:', room.status);
console.log('Auto-match wait time:', room.autoMatchWaitSeconds);

// Show room created UI
showRoomCreatedScreen(room);

// If auto-matching, show waiting screen
if (room.isAutoMatch) {
showAutoMatchWaiting(room);
} else {
// Private room - show invitation code
showInvitationCode(room.roomID);
}

// Start room state monitoring
startRoomStateMonitoring(room);
} else {
console.error('❌ Failed to create room');
showRoomCreationError('Unable to create room. Please try again.');
returnToLobby();
}
}

onJoinedRoom

Called when you successfully join a room:

onJoinedRoom: (status, room) => {
if (status) {
console.log('✅ Successfully joined room');
console.log('Room ID:', room.roomID);
console.log('Creator:', room.creatorID);
console.log('Current players:', room.participants.length);

// Display room information
showRoomInfo(room);

// Show list of current players
displayPlayerList(room.participants);

// Check if room is ready to start
if (room.status === 3) { // RoomStatus.ACTIVE
console.log('Room is active - ready to play!');
enableGameControls();
startGameCountdown();
} else {
console.log('Room is not yet active - waiting for players');
showWaitingForPlayers(room);
}

// Send join announcement
sendJoinAnnouncement();
} else {
console.error('❌ Failed to join room');
showJoinError('Unable to join room. The room may be full or no longer available.');
returnToLobby();
}
}

Player Management Callbacks

onPeerJoined

Called when a new player joins the room:

onPeerJoined: (room, participantList) => {
console.log('👋 New player joined the room');
console.log('Total players:', participantList.length);

// Find the new participant
const newParticipant = room.participants.find(p =>
!previousParticipants.has(p.participantID)
);

if (newParticipant) {
console.log('New player:', newParticipant.name);

// Show join notification
showPlayerJoinedNotification(newParticipant);

// Add to player list
addPlayerToUI(newParticipant);

// Play join sound
playSound('playerJoined');

// Update previous participants set
previousParticipants.add(newParticipant.participantID);
}

// Update player count display
updatePlayerCount(participantList.length);

// Check if room is now full
const maxPlayers = room.max_automatch_players || room.participants.length;
if (participantList.length >= maxPlayers) {
console.log('Room is now full!');
showRoomFullNotification();
startGameCountdown();
}

// Update game state if needed
updateGameStateForNewPlayer(room);
}

onPeerLeft

Called when a player leaves the room:

onPeerLeft: (room, participantList) => {
console.log('👋 Player left the room');
console.log('Remaining players:', participantList.length);

// Find who left by comparing with previous participants
const leftParticipantId = Array.from(previousParticipants).find(id =>
!participantList.includes(id)
);

if (leftParticipantId) {
// Find participant details from room data
const leftParticipant = room.participants.find(p =>
p.participantID === leftParticipantId
);

if (leftParticipant) {
console.log('Player who left:', leftParticipant.name);

// Show leave notification
showPlayerLeftNotification(leftParticipant);

// Remove from player list
removePlayerFromUI(leftParticipant.participantID);

// Play leave sound
playSound('playerLeft');

// Clean up player-specific data
cleanupPlayerData(leftParticipant.participantID);
}

// Update previous participants set
previousParticipants.delete(leftParticipantId);
}

// Update player count display
updatePlayerCount(participantList.length);

// Handle game state changes
if (participantList.length < 2) {
console.log('Not enough players to continue');
pauseGameplay('Not enough players');
showWaitingForPlayers();
} else {
// Check if game can continue
checkGameContinuation(room);
}

// Check if room creator left
if (leftParticipantId === room.creatorID) {
console.log('Room creator left - room may close soon');
showCreatorLeftWarning();
}
}

Connection State Callbacks

onRoomConnected

Called when the room is fully connected and ready:

onRoomConnected: (status, room) => {
if (status) {
console.log('🔗 Room fully connected and ready');
console.log('All players connected:', room.participants.length);

// Hide any loading/waiting screens
hideLoadingScreen();
hideWaitingScreen();

// Show game ready state
showGameReadyScreen();

// Enable game controls
enableAllGameControls();

// Start the game
startMultiplayerGame(room);

// Begin game state synchronization
startGameStateSync();

// Show connected notification
showNotification('All players connected!', 'success');

// Start game timer
startGameTimer();

// Enable voice chat if available
if (isVoiceChatEnabled()) {
enableVoiceChat();
}

// Log game start for analytics
logGameStart(room);
} else {
console.error('❌ Failed to connect room');
showConnectionError('Unable to establish connection with all players');

// Offer retry option
showRetryConnectionOption();
}
}

onRoomDisconnected

Called when the room connection is lost:

onRoomDisconnected: (room) => {
console.log('🔌 Room connection lost');
console.log('Room ID:', room.roomID);

// Show disconnection warning
showDisconnectionWarning('Connection to room lost');

// Pause game immediately
pauseGameplay();

// Disable game controls
disableGameControls();

// Show reconnection attempt
showReconnectionScreen();

// Start reconnection timer
startReconnectionTimer();

// Save current game state
saveGameStateForReconnection();

// Notify players
showNotification('Connection lost. Attempting to reconnect...', 'warning');

// Log disconnection for analytics
logDisconnection(room);

// Attempt automatic reconnection
attemptReconnection(room);
}

// Handle reconnection
function attemptReconnection(room) {
let attempts = 0;
const maxAttempts = 5;

const reconnectInterval = setInterval(() => {
attempts++;
console.log(`Reconnection attempt ${attempts}/${maxAttempts}`);

updateReconnectionStatus(attempts, maxAttempts);

if (attempts >= maxAttempts) {
clearInterval(reconnectInterval);
handleReconnectionFailure();
return;
}

// Attempt to rejoin room
// This would use your room reconnection logic
attemptRoomRejoin(room.roomID);
}, 3000); // Try every 3 seconds
}

Room Exit Callbacks

onLeftRoom

Called when you leave the room:

onLeftRoom: (status, roomID) => {
console.log('🚪 Left the room');
console.log('Room ID:', roomID);
console.log('Leave status:', status);

if (status) {
console.log('✅ Successfully left room');

// Clean up game state
cleanupGameState();

// Clear room-specific data
clearRoomData();

// Stop any ongoing timers
clearAllTimers();

// Reset UI to lobby state
returnToLobbyScreen();

// Show leave confirmation
showNotification('Left room successfully', 'info');

// Log room exit for analytics
logRoomExit(roomID, 'voluntary');

// Reset player tracking
previousParticipants.clear();

// Disable voice chat
disableVoiceChat();

// Clear message history
clearMessageHistory();

} else {
console.error('❌ Failed to leave room properly');

// Force cleanup anyway
forceCleanup();

// Show error message
showNotification('Error leaving room', 'error');

// Return to lobby anyway
returnToLobbyScreen();

// Log error for debugging
logRoomExitError(roomID);
}

// Reset connection state
resetConnectionState();
}

Complete Callback Implementation

Here's a comprehensive example with all callbacks:

const roomCallbacks = {
// Room creation and joining
onRoomCreated: (status, room) => {
if (status) {
console.log('Room created:', room.roomID);
initializeRoomUI(room);
if (room.isAutoMatch) {
startAutoMatchWaiting(room);
} else {
showInvitationCode(room.roomID);
}
} else {
console.error('Room creation failed');
showRoomCreationError();
}
},

onJoinedRoom: (status, room) => {
if (status) {
console.log('Joined room:', room.roomID);
displayRoomInfo(room);
if (room.status === 3) {
startGameplay(room);
} else {
showWaitingScreen(room);
}
} else {
console.error('Failed to join room');
showJoinError();
}
},

// Player management
onPeerJoined: (room, participantList) => {
console.log('Player joined. Total:', participantList.length);
updatePlayerList(room.participants);
checkRoomReady(room);
playSound('playerJoined');
},

onPeerLeft: (room, participantList) => {
console.log('Player left. Remaining:', participantList.length);
updatePlayerList(room.participants);
if (participantList.length < 2) {
pauseGameplay('Not enough players');
}
playSound('playerLeft');
},

// Connection management
onRoomConnected: (status, room) => {
if (status) {
console.log('Room connected and ready');
hideWaitingScreen();
startMultiplayerGame(room);
showNotification('Game starting!', 'success');
} else {
console.error('Room connection failed');
showConnectionError();
}
},

onRoomDisconnected: (room) => {
console.log('Room disconnected');
pauseGameplay();
showReconnectionScreen();
attemptReconnection(room);
},

// Room exit
onLeftRoom: (status, roomID) => {
console.log('Left room:', roomID);
cleanupGameState();
returnToLobby();
if (status) {
showNotification('Left room successfully', 'info');
} else {
showNotification('Error leaving room', 'error');
}
},

// Message handling
onMessageReceived: (messageData, senderID, isReliable) => {
handleIncomingMessage(messageData, senderID, isReliable);
}
};

// Use callbacks when creating or joining room
MoitribeSDK('my-game-id', 'createstandardroom', {
...roomParams,
...roomCallbacks
}, (result) => {
console.log('Room creation request sent');
});

Best Practices

Error Handling

  • Always check status parameters in callbacks
  • Implement graceful degradation for connection issues
  • Provide user feedback for all room events
  • Log errors for debugging and analytics

UI Updates

  • Update UI immediately in response to callbacks
  • Show loading states during transitions
  • Provide clear feedback for room state changes
  • Use animations for smooth transitions

State Management

  • Maintain consistent state across all callbacks
  • Clean up resources when leaving rooms
  • Save game state for potential reconnection
  • Reset state properly between sessions

Performance

  • Avoid heavy operations in callback handlers
  • Use debouncing for frequent updates
  • Implement efficient player list management
  • Cache frequently accessed data

Next Steps