From 75f306f6504abe668d04b3da9f921d658312c2ee Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Sun, 2 Aug 2026 21:31:27 +0200 Subject: [PATCH] route the win-path restart through ResetCommand The Restart button on the Win dialog called Simulation::reset() directly, while the escape-menu and Game Over restarts enqueue a ResetCommand. That bypassed the command chokepoint every sim mutation is supposed to flow through (docs/replay_design.md), so a post-win restart was never recorded into the replay stream, and it had UI code calling a sim mutator directly. Mirror the Game Over path instead. The manual resetForNewGame() call goes away with it: GameWorldView::onFrame already resets the view when it drains a Reset command. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk --- src/ui/MainWindow.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ui/MainWindow.cpp b/src/ui/MainWindow.cpp index 2b2acb5..2dedab7 100644 --- a/src/ui/MainWindow.cpp +++ b/src/ui/MainWindow.cpp @@ -419,10 +419,12 @@ void MainWindow::handleEvent(std::shared_ptr /*event*/) { return; } - // Unlike the other two restart paths this one resets the simulation - // directly instead of enqueueing a ResetCommand; kept as-is. - m_sim->reset(std::move(*newConfig)); - m_gameWorldView->resetForNewGame(); + // Restart is a command boundary; the view resets when the drain applies it. + std::shared_ptr command = std::make_shared(); + command->config = std::make_shared(std::move(*newConfig)); + command->seed = std::random_device{}(); + EventManager::getInstance()->sendEventImmediately( + std::make_shared(command)); } else {