diff --git a/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx b/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx index 1d4ccf8e5..2d5c33203 100644 --- a/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx +++ b/apps/ai-game-creator-shell/src/features/app-shell/WorkspaceLauncher.tsx @@ -58,10 +58,13 @@ export function WorkspaceLauncherShell({ title: string; message: string; } | null>(null); - const [agentRuntimeMode, setAgentRuntimeMode] = useState<'design' | 'game'>( - 'game', - ); - const [suppressInitialGameTurn, setSuppressInitialGameTurn] = useState(false); + // 「做成游戏」切换记录按项目上下文(路径 + createdAt)定位。运行模式必须随 + // currentProjectContext 同步派生,不能靠 effect 后置修正:首帧挂错 lane 会先 + // 以游戏运行时挂载并消耗首轮 claim,重挂后的策划实例再也发不出首轮。 + const [gameRuntimeSwitch, setGameRuntimeSwitch] = useState<{ + projectPath: string; + createdAt: number; + } | null>(null); const developerAgent = useDeveloperAgentPanel(launcherView); const homeProject = useHomeProjectCreation({ setStatus, @@ -85,15 +88,17 @@ export function WorkspaceLauncherShell({ createHomeDraftAutomatically, openProject, } = homeProject; - useEffect(() => { - setSuppressInitialGameTurn(false); - setAgentRuntimeMode( - currentProjectContext?.startMode === 'planning' ? 'design' : 'game', - ); - }, [currentProjectContext?.projectPath, currentProjectContext?.startMode]); + const switchedToGameRuntime = + gameRuntimeSwitch !== null && + currentProjectContext !== null && + gameRuntimeSwitch.projectPath === currentProjectContext.projectPath && + gameRuntimeSwitch.createdAt === currentProjectContext.createdAt; const planningStartMode = - currentProjectContext?.startMode === 'planning' && - (agentRuntimeMode === 'design' || !suppressInitialGameTurn); + currentProjectContext?.startMode === 'planning' && !switchedToGameRuntime; + const agentRuntimeMode: 'design' | 'game' = planningStartMode + ? 'design' + : 'game'; + const suppressInitialGameTurn = switchedToGameRuntime; const activeProjectContextRef = useRef(currentProjectContext); const manifestMergeRef = useRef(null); activeProjectContextRef.current = currentProjectContext; @@ -258,8 +263,10 @@ export function WorkspaceLauncherShell({ projectPath: nextProjectPath, activeRuntime: 'game', }); - setSuppressInitialGameTurn(true); - setAgentRuntimeMode('game'); + setGameRuntimeSwitch({ + projectPath: nextProjectPath, + createdAt: currentProjectContext?.createdAt ?? 0, + }); } const currentHelpTitle =