fix: resolve room state synchronization and player display issues

- Fix room.state.players undefined error on component mount
- Wait for initial state sync before accessing room data
- Move message handlers from service to Game component
- Fix player count display in waiting screen (was showing 0/2)
- Prevent lobby component from clearing game room on unmount
- Separate leaveLobby() and leaveGame() methods for proper cleanup
- Ensure player names persist when moving from lobby to game
- Add proper error handling for state initialization
This commit is contained in:
2025-08-06 02:58:29 -06:00
parent a28bc286a1
commit 1392e5a652
5 changed files with 192 additions and 93 deletions

View File

@@ -61,67 +61,68 @@ class ColyseusService {
}
}
async quickPlay(): Promise<void> {
if (this.lobbyRoom.value) {
return new Promise((resolve, reject) => {
const room = this.lobbyRoom.value!;
room.onMessage("roomReservation", async (reservation) => {
try {
await this.joinGameByReservation(reservation);
resolve();
} catch (error) {
reject(error);
}
});
room.onMessage("error", (error) => {
reject(new Error(error.message));
});
room.send("quickPlay");
});
async quickPlay(): Promise<Room> {
if (!this.lobbyRoom.value) {
throw new Error("Not in lobby");
}
return new Promise((resolve, reject) => {
const room = this.lobbyRoom.value!;
console.log('Sending quickPlay message to lobby...');
const handleGameJoined = async (data: any) => {
console.log('Received gameJoined with roomId:', data.roomId);
try {
// Join the game room directly using the roomId
console.log('Joining game room with name:', this.playerName.value);
const gameRoom = await this.client.joinById(data.roomId, {
playerName: this.playerName.value
});
// Ensure the room id is set
if (!gameRoom.id) {
gameRoom.id = data.roomId;
}
console.log('Successfully joined game room:', gameRoom.id, gameRoom);
console.log('Setting gameRoom.value...');
this.gameRoom.value = gameRoom;
this.currentRoom = gameRoom;
console.log('gameRoom.value is now:', this.gameRoom.value);
// Don't register message handlers here - let the Game component handle them
resolve(gameRoom);
} catch (error) {
console.error('Error joining game room:', error);
reject(error);
}
};
const handleError = (error: any) => {
console.error('Received error from lobby:', error);
reject(new Error(error.message));
};
room.onMessage("gameJoined", handleGameJoined);
room.onMessage("error", handleError);
room.send("quickPlay");
});
}
async joinGameRoom(roomId: string): Promise<void> {
if (this.lobbyRoom.value) {
return new Promise((resolve, reject) => {
const room = this.lobbyRoom.value!;
room.onMessage("roomReservation", async (reservation) => {
try {
await this.joinGameByReservation(reservation);
resolve();
} catch (error) {
reject(error);
}
});
room.onMessage("error", (error) => {
reject(new Error(error.message));
});
room.send("joinRoom", roomId);
});
}
}
private async joinGameByReservation(reservation: any): Promise<void> {
async joinGameRoom(roomId: string): Promise<Room> {
try {
const room = await this.client.consumeSeatReservation(reservation);
this.gameRoom.value = room;
this.currentRoom = room;
room.onMessage("playerInfo", (data) => {
this.sessionId.value = data.sessionId;
this.playerName.value = data.name;
const gameRoom = await this.client.joinById(roomId, {
playerName: this.playerName.value
});
if (this.lobbyRoom.value) {
this.lobbyRoom.value.leave();
this.lobbyRoom.value = null;
}
this.gameRoom.value = gameRoom;
this.currentRoom = gameRoom;
// Don't register message handlers here - let the Game component handle them
return gameRoom;
} catch (error) {
console.error("Failed to join game room:", error);
throw error;
@@ -134,7 +135,31 @@ class ColyseusService {
}
}
leaveLobby(): void {
console.log('leaveLobby called');
if (this.lobbyRoom.value) {
this.lobbyRoom.value.leave();
this.lobbyRoom.value = null;
if (this.currentRoom === this.lobbyRoom.value) {
this.currentRoom = null;
}
}
}
leaveGame(): void {
console.log('leaveGame called');
if (this.gameRoom.value) {
this.gameRoom.value.leave();
this.gameRoom.value = null;
if (this.currentRoom === this.gameRoom.value) {
this.currentRoom = null;
}
}
}
leaveCurrentRoom(): void {
console.log('leaveCurrentRoom called - THIS SHOULD NOT BE USED');
// This method is deprecated - use leaveLobby() or leaveGame() instead
if (this.currentRoom) {
this.currentRoom.leave();
this.currentRoom = null;