Skip to content

[Issue]: Game Mode Start Game snaps back mid-stream and produces duplicate [Start the game] messages #321

Description

@Romuromylus

Summary

In Game Mode 1.5.6, clicking Start Game on a freshly-set-up game shows the intro typewriter, then snaps back to the Start Game screen mid-stream. The user clicks Start again and the chat ends up with two [Start the game] user messages — the GM frames the second one as a session continuation and the game starts at "scene 2".

Expected behavior

After clicking Start Game once on a new Game Mode chat, the intro typewriter plays through, the GM streams the opening scene, the Continue button replaces the Start screen, and the chat history contains exactly one [Start the game] user message.

Actual behavior

After clicking Start Game:

  1. Intro typewriter appears with the world overview (correct).
  2. Mid-stream the screen falls back to the idle Start Game screen (genre/setting tags + Start Game button, no overview visible).
  3. User has to click Start Game again.
  4. Chat persists two [Start the game] user messages and the GM treats the second one as a "session continuation" framing — the game effectively starts at "scene 2".

Reproduces consistently across Opus, GPT, and DeepSeek as the GM model, so this is not a model-output issue.

Steps to reproduce

  1. Create a new Game Mode chat.
  2. Run through /game/setup (any genre / setting / tone — reproduced with Fantasy / Adventure / Smut / Harem / Heroic).
  3. Wait for the world overview to be ready and the Start Game button to appear.
  4. Click Start Game.
  5. Observe: intro shows briefly, then the screen snaps back to the Start Game button mid-stream.
  6. Click Start Game a second time.
  7. Open the chat history — there are two [Start the game] user messages, and the GM is narrating "scene 2".

Environment

  • Marinara Engine version: 1.5.6
  • Install type: source (VPS, git clone)
  • OS + version: Ubuntu (VPS host)
  • Browser or app shell: Chromium-based browser

Logs, screenshots, or video

Screen state when the bug fires (idle Start Game phase reappearing after the first click):

Image Image

Additional context

Likely root cause (server-side race):

  • packages/server/src/routes/generate.routes.ts captures chat.metadata once at request start (~line 397) and writes the parsed copy back later via chats.updateMetadata. updateMetadata replaces the metadata column wholesale (see packages/server/src/services/storage/chats.storage.ts:105-110).
  • /game/start flips gameSessionStatus from "ready""active" while the [Start the game] generation is in flight.
  • Several stream-side persistence sites (preset entry-state-overrides, lorebook entry-state-overrides x3, lastMapPosition, game-state-patch gameMap sync, chat_summary, mariContext) do NOT re-fetch metadata before merging, so they clobber the freshly-set gameSessionStatus: "active" back to "ready" when they fire mid-stream.
  • The combat agent at generate.routes.ts:6361-6365 already handles this correctly with a re-fetch-then-merge pattern.

When the stale write lands first, the client's chatMeta refetches "ready" again. GameSurface's clearing effect at packages/client/src/components/game/GameSurface.tsx:5159-5164 had already fired (it ran while status was briefly "active") and cleared startGameRequested. With sessionStatus === "ready" and introPresented === false, the surface drops back to the idle Start Game phase — the visible bug.

A previous attempt at this bug (3e13514, reverted by 518dc92 on a contributor's fork) tried to fix this client-side via query invalidation. That couldn't have worked because the actual race is server-side metadata clobbering.

PR with proposed fix: #320.

Template check

Please uncheck (untick) the box below before submitting so we know you read the template. It is intentionally pre-checked:

  • I DID NOT read this template and provide the requested details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions