Skip to content

[WIP] Fix stuck 'Waiting' state in start-game flow#1

Draft
Copilot wants to merge 1 commit into
mainfrom
copilot/fix-stuck-waiting-state
Draft

[WIP] Fix stuck 'Waiting' state in start-game flow#1
Copilot wants to merge 1 commit into
mainfrom
copilot/fix-stuck-waiting-state

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 21, 2026

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

Fix stuck "Waiting" state in start-game flow by clearing stale game state on disconnect. In signaling-server/server.js, when a player disconnects, if the room becomes empty, delete rooms[roomId] and gameState[roomId]. If the current game exists and the disconnected socket was the speaker, clear gameState[roomId] and emit "reset-game" to the room so a new game can start. Ensure existing room-update behavior remains. Provide minimal change, keep current start-game guard logic intact.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: can you check the code, cause after i click start its stuck for waiting

Assistant: I couldn’t access the repo via search (it appears inaccessible). Please confirm the repository is public or grant access, and tell me which branch to inspect (e.g., main). If you can share a link to the file where the “Start” button logic lives (or paste that snippet), I can pinpoint why it gets stuck on “waiting.”

User: this repo

Assistant: Likely cause: the game never starts because the server refuses to start unless at least 2 players are in the same room, so the UI stays on “Waiting…”.

From your server code:

  socket.on("start-game", roomId => {

    const room = rooms[roomId];
    if (!room || room.players.length < 2) return;

    // 🚫 prevent start ONLY if active game exists
    const game = gameState[roomId];
    if (game && !game.won) return;

So if you click Start with only one player, it silently returns and nothing happens.


✅ What you should do

  1. Open the game in two browser tabs (or two devices)
  2. Join the same Room ID in both
  3. Then click Start → it should begin immediately

(Optional) Improve the UI with feedback

Right now the user gets no warning if start is blocked. I can help add a message like:

“Need at least 2 players to start”

If you want, I can prepare the exact fix or even open a PR.

User: its happening even if 2 players are joined

Assistant: Most likely cause: your client is connecting to the hosted server on Render, not your local server — so the two players you joined locally never exist on the server you’re actually sending start-game to.

In client/script.js the socket points to:

const socket = io("https://taboo-game-l02a.onrender.com");

If you’re running the server locally (localhost:3000), the client still sends events to Render, so start-game never fires for your local players. That leaves the UI stuck on Waiting.


✅ Fix (choose one)

Option A — Run everything against local server

Change this line to:

const socket = io("http://localhost:3000");

Option B — Use Render server

Make sure both players open the deployed client that connects to Render (not your local HTML file).


Quick check

Open DevTools → Console and confirm you see ✅ Connected.
If you see ❌ Disconnected or no log at all, it’s not connecting to the correct server.


If you want, tell me how you’re running the app (local vs deployed), and I’ll give the exact steps to fix it.

User: not using local server its running on vercel

Assistant: Most likely cause now: the server blocks start-game if a previous game exists and wasn’t marked won, and that state is never cleared on disconnect. So if a game was started and someone left (or tab refreshed), gameState[roomId] stays stuck, and all future starts are ignored.

Here’s the block that causes it:

socket.on("start-game", roomId => {

  const room = rooms[roomId];
  if (!room || room.players.length < 2) return;

  // 🚫 prevent start ONLY if active game exists
  const game = gameState[roomId];
  if (game && !game.won) return;

And on disconnect, you never clear gameState[roomId]:

socket.on("disconnect", () => {

  for (let roomId in rooms) {

    rooms[roomId].players =
      rooms[roomId].players.filter(p => p.id !== socket.id);

    emitRoomUpdate(roomId);
  }
});

✅ Fix (recommended)

Clear the game if the room becomes empty or if the current speaker left. Example:

// inside disconnect loop, after removing the player
if (rooms[roomId].players.length === 0) {
  delete rooms[roomId];
  delete gameState[roomId];
} else {
  const game = gameState[roomId];
  if (gam...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants