> ## Documentation Index
> Fetch the complete documentation index at: https://docs-ts.playservices.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Room Management

> Game room creation, player connections, session handling, and tournament room lifecycle management

# Room Management

Room Management handles the creation, configuration, and lifecycle of game rooms for tournament play. This includes player connections, session state synchronization, and room cleanup after tournament completion.

## Room Creation Process

### Tournament Room Initialization

When a tournament becomes active, the Game Platform creates a dedicated game room:

```javascript theme={null}
class TournamentRoomManager {
  constructor(internalApiKey) {
    this.apiKey = internalApiKey;
    this.rooms = new Map();
  }
  
  async createTournamentRoom(tournamentId) {
    try {
      // Get tournament configuration
      const config = await this.getTournamentConfig(tournamentId);
      
      // Create game room instance
      const room = {
        roomId: `room_${tournamentId}_${Date.now()}`,
        tournamentId: tournamentId,
        gameSlug: config.gameSlug,
        maxPlayers: config.maxPlayers,
        currentPlayers: 0,
        status: 'waiting',
        gameConfig: config.gameConfig,
        players: new Map(),
        createdAt: new Date(),
        lastActivity: new Date()
      };
      
      // Initialize game-specific settings
      await this.initializeGameRoom(room, config);
      
      // Store room reference
      this.rooms.set(room.roomId, room);
      
      console.log(`Tournament room created: ${room.roomId}`);
      return room;
      
    } catch (error) {
      console.error(`Room creation failed for tournament ${tournamentId}:`, error);
      throw error;
    }
  }
  
  async initializeGameRoom(room, config) {
    // Game-specific initialization
    switch (config.gameSlug) {
      case 'crash-classic':
        room.gameState = {
          currentRound: 0,
          roundStartTime: null,
          crashPoint: null,
          bets: new Map()
        };
        break;
        
      default:
        room.gameState = {};
    }
    
    // Set up room events
    room.events = {
      onPlayerJoin: this.handlePlayerJoin.bind(this),
      onPlayerLeave: this.handlePlayerLeave.bind(this),
      onGameEvent: this.handleGameEvent.bind(this)
    };
  }
}
```

### Room Configuration

```json theme={null}
{
  "roomId": "room_12345_1642089600",
  "tournamentId": "12345",
  "gameSlug": "crash-classic",
  "status": "active",
  "maxPlayers": 100,
  "currentPlayers": 87,
  "gameConfig": {
    "maxRounds": 10,
    "roundDuration": 300,
    "eliminationRate": 0.5
  },
  "roomSettings": {
    "allowSpectators": true,
    "chatEnabled": true,
    "pauseOnDisconnect": false
  },
  "createdAt": "2024-01-15T20:00:00Z",
  "lastActivity": "2024-01-15T20:25:30Z"
}
```

## Player Connection Management

### Player Join Process

```javascript theme={null}
async handlePlayerConnection(roomId, jwtToken, socketConnection) {
  try {
    // Validate JWT token
    const validation = await this.validatePlayerToken(jwtToken);
    
    if (!validation.valid) {
      throw new Error(`Invalid token: ${validation.error}`);
    }
    
    // Get room reference
    const room = this.rooms.get(roomId);
    
    if (!room) {
      throw new Error(`Room ${roomId} not found`);
    }
    
    // Check room capacity
    if (room.currentPlayers >= room.maxPlayers) {
      throw new Error('Room is full');
    }
    
    // Create player session
    const playerSession = {
      playerId: validation.playerId,
      displayName: validation.playerInfo.displayName,
      socket: socketConnection,
      joinedAt: new Date(),
      lastActivity: new Date(),
      status: 'connected',
      gameData: {
        position: null,
        score: 0,
        isEliminated: false
      }
    };
    
    // Add player to room
    room.players.set(validation.playerId, playerSession);
    room.currentPlayers++;
    room.lastActivity = new Date();
    
    // Send room state to player
    await this.sendRoomState(playerSession.socket, room);
    
    // Notify other players
    await this.broadcastPlayerJoin(room, playerSession);
    
    console.log(`Player ${validation.playerId} joined room ${roomId}`);
    
    return playerSession;
    
  } catch (error) {
    console.error('Player connection failed:', error);
    throw error;
  }
}
```

### Session State Synchronization

```javascript theme={null}
async syncPlayerState(roomId, playerId, gameState) {
  const room = this.rooms.get(roomId);
  const player = room?.players.get(playerId);
  
  if (!player) {
    throw new Error('Player not found in room');
  }
  
  // Update player game data
  player.gameData = {
    ...player.gameData,
    ...gameState,
    lastUpdate: new Date()
  };
  
  player.lastActivity = new Date();
  room.lastActivity = new Date();
  
  // Sync with tournament system if significant change
  if (gameState.score || gameState.position) {
    await this.reportPlayerUpdate(room.tournamentId, playerId, gameState);
  }
}
```

## Room Lifecycle Management

### Room Status States

| Status      | Description                       | Actions Available           |
| ----------- | --------------------------------- | --------------------------- |
| `waiting`   | Room created, waiting for players | Player connections          |
| `active`    | Tournament in progress            | Gameplay, player management |
| `paused`    | Temporarily paused                | Resume, player reconnection |
| `completed` | Tournament finished               | Results, cleanup            |
| `cancelled` | Tournament cancelled              | Player cleanup, refunds     |

### Room Cleanup Process

```javascript theme={null}
async cleanupRoom(roomId, reason = 'completed') {
  const room = this.rooms.get(roomId);
  
  if (!room) {
    console.warn(`Room ${roomId} not found for cleanup`);
    return;
  }
  
  console.log(`Cleaning up room ${roomId} - reason: ${reason}`);
  
  try {
    // Disconnect all players
    for (const [playerId, player] of room.players) {
      try {
        await this.disconnectPlayer(player.socket, reason);
      } catch (error) {
        console.error(`Failed to disconnect player ${playerId}:`, error);
      }
    }
    
    // Archive room data
    await this.archiveRoomData(room);
    
    // Remove room from active rooms
    this.rooms.delete(roomId);
    
    console.log(`Room ${roomId} cleanup completed`);
    
  } catch (error) {
    console.error(`Room cleanup failed for ${roomId}:`, error);
  }
}
```

## Connection Management

### WebSocket Connection Handling

```javascript theme={null}
class RoomConnectionManager {
  constructor(roomManager) {
    this.roomManager = roomManager;
    this.connections = new Map();
  }
  
  handleConnection(socket, request) {
    const url = new URL(request.url, 'http://localhost');
    const token = url.searchParams.get('token');
    const roomId = url.searchParams.get('room');
    
    if (!token || !roomId) {
      socket.close(1008, 'Missing token or room ID');
      return;
    }
    
    this.authenticateAndConnect(socket, roomId, token);
  }
  
  async authenticateAndConnect(socket, roomId, token) {
    try {
      // Connect player to room
      const playerSession = await this.roomManager.handlePlayerConnection(
        roomId, token, socket
      );
      
      // Store connection reference
      this.connections.set(socket, {
        roomId: roomId,
        playerId: playerSession.playerId,
        connectedAt: new Date()
      });
      
      // Set up socket event handlers
      this.setupSocketHandlers(socket, roomId, playerSession.playerId);
      
    } catch (error) {
      console.error('Connection authentication failed:', error);
      socket.close(1008, error.message);
    }
  }
  
  setupSocketHandlers(socket, roomId, playerId) {
    socket.on('message', async (data) => {
      try {
        const message = JSON.parse(data);
        await this.handlePlayerMessage(roomId, playerId, message);
      } catch (error) {
        console.error('Message handling failed:', error);
      }
    });
    
    socket.on('close', () => {
      this.handleDisconnection(socket, roomId, playerId);
    });
    
    socket.on('error', (error) => {
      console.error(`Socket error for player ${playerId}:`, error);
    });
  }
}
```

### Player Reconnection

```javascript theme={null}
async handlePlayerReconnection(roomId, playerId, newSocket) {
  const room = this.rooms.get(roomId);
  const player = room?.players.get(playerId);
  
  if (!player) {
    throw new Error('Player session not found');
  }
  
  // Close old connection if exists
  if (player.socket) {
    player.socket.close(1000, 'Reconnected from new session');
  }
  
  // Update player session with new socket
  player.socket = newSocket;
  player.lastActivity = new Date();
  player.status = 'reconnected';
  
  // Send current room state
  await this.sendRoomState(newSocket, room);
  
  // Notify other players of reconnection
  await this.broadcastPlayerReconnect(room, playerId);
  
  console.log(`Player ${playerId} reconnected to room ${roomId}`);
}
```

## Room Monitoring & Analytics

### Room Health Monitoring

```javascript theme={null}
class RoomMonitor {
  constructor(roomManager) {
    this.roomManager = roomManager;
    this.monitoringInterval = setInterval(() => {
      this.monitorRooms();
    }, 30000); // Monitor every 30 seconds
  }
  
  monitorRooms() {
    for (const [roomId, room] of this.roomManager.rooms) {
      this.checkRoomHealth(room);
    }
  }
  
  checkRoomHealth(room) {
    const now = new Date();
    const inactiveThreshold = 5 * 60 * 1000; // 5 minutes
    
    // Check for inactive rooms
    if (now - room.lastActivity > inactiveThreshold) {
      console.warn(`Room ${room.roomId} inactive for ${now - room.lastActivity}ms`);
      
      if (room.currentPlayers === 0) {
        // Clean up empty inactive rooms
        this.roomManager.cleanupRoom(room.roomId, 'inactive');
      }
    }
    
    // Check for disconnected players
    for (const [playerId, player] of room.players) {
      if (now - player.lastActivity > inactiveThreshold) {
        console.warn(`Player ${playerId} inactive in room ${room.roomId}`);
        // Handle player timeout
        this.handlePlayerTimeout(room, playerId);
      }
    }
  }
  
  generateRoomMetrics(room) {
    return {
      roomId: room.roomId,
      tournamentId: room.tournamentId,
      status: room.status,
      playerCount: room.currentPlayers,
      maxPlayers: room.maxPlayers,
      utilization: (room.currentPlayers / room.maxPlayers) * 100,
      uptime: new Date() - room.createdAt,
      lastActivity: room.lastActivity,
      averageLatency: this.calculateAverageLatency(room),
      messageCount: this.getMessageCount(room)
    };
  }
}
```

### Performance Optimization

```javascript theme={null}
// Efficient room state broadcasting
async broadcastToRoom(room, message, excludePlayer = null) {
  const promises = [];
  
  for (const [playerId, player] of room.players) {
    if (playerId === excludePlayer) continue;
    
    if (player.socket.readyState === WebSocket.OPEN) {
      promises.push(
        new Promise((resolve, reject) => {
          player.socket.send(JSON.stringify(message), (error) => {
            if (error) reject(error);
            else resolve();
          });
        })
      );
    }
  }
  
  // Wait for all messages to be sent
  try {
    await Promise.allSettled(promises);
  } catch (error) {
    console.error('Broadcast failed:', error);
  }
}

// Memory-efficient player state updates
updatePlayerStates(room, updates) {
  const batch = [];
  
  for (const [playerId, update] of Object.entries(updates)) {
    const player = room.players.get(playerId);
    
    if (player) {
      Object.assign(player.gameData, update);
      batch.push({ playerId, ...update });
    }
  }
  
  // Broadcast batched updates
  this.broadcastToRoom(room, {
    type: 'player_states_updated',
    updates: batch
  });
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Real-time Communication" icon="bolt" href="/game-platform-integration/real-time-communication">
    Implement real-time messaging and event patterns for tournament gameplay.
  </Card>

  <Card title="Event Reporting" icon="bell" href="/game-platform-integration/event-reporting">
    Report tournament events via SQS for external system notifications.
  </Card>
</CardGroup>
