5.9 KiB
Editor Agent Guide
This file is for agents working in editor/** and tests/UI/Editor/**.
Treat the current code and tests as source of truth. If this guide drifts from
the checkout, update it in the same change.
Current Priority
The editor is not in a "split more layers for their own sake" phase.
The primary product line is still runtime/product loop closure:
- extend the bound
EditorRuntimeCoordinatorinstead of adding panel-local shortcuts forrun.*, scene document commands, or project scene opens - keep play mode transactional:
EditorRuntimeCoordinatormust enter play throughEditorSceneRuntime::BeginPlaySession, andRuntimeLoopmust run the play-session runtime scene rather than the editable document scene - bind a real script assembly builder behind
scripts.*; until then the coordinator must keep the command honestly disabled - keep
Game,Scene,Inspector,Selection, andConsolecoherent across runtime transitions
Do not burn time on broad architectural churn unless it directly unlocks that product loop or removes an active architectural hazard.
Engine Boundary Status
The old public EditorEngineServices god interface is gone.
The current editor-to-engine boundaries are narrow and must stay narrow:
EditorSceneBackendFactorySceneViewportEngineBridgeGameViewportEngineBridgeEditorShaderProviderEditorEngineLifecycle
EngineEditorComposition in editor/app/Services/Engine/EngineEditorServices.*
is an internal composition root that hands out those narrow interfaces. It is
not a new shared facade for features to depend on.
Rules:
- do not recreate
EditorEngineServices - do not add a replacement god interface under a different name
- do not make new panels, passes, or runtimes depend on a catch-all engine service locator
- keep render-pass dependencies low-level: passes may depend on
EditorShaderProvider, not on scene backend creation or lifecycle code - composition owns assembly; features and passes must receive explicit dependencies
Product Truths
GameViewportFeature,GameViewportRenderService, and related tests exist.EditorRuntimeCoordinatoris now the app-level owner for play-mode command routing and usesRuntimeLoopfor the active play-session scene.- Play mode is a scene transaction. The engine scene backend snapshots the
editable scene, replaces it with a runtime scene for play/step, and restores
the editable scene when the play session ends. Do not start runtime playback
directly from
EditorSceneRuntime::GetActiveScene(). EditorHostCommandBridgedelegatesfile.*,run.*, andscripts.*to a bound runtime owner. If no owner is bound, it must continue exposing honest disabled messages.EditorSceneRuntimeowns raw scene editing behavior.EditorRuntimeCoordinatorowns scene document state: current path/name, dirty flag, new/open/save routing, and runtime-mode transitions.ProjectPanelmay identify an openable scene asset, but scene document loading must go throughEditorFrameServices::RequestOpenSceneAssetand the coordinator. Do not reintroduceProjectRuntimepending-open queues.scripts.rebuildhas a bound coordinator owner, but no in-process script assembly builder is currently wired. Keep it disabled and explicit until that builder exists.- the old shared
EditorPanelServicesdependency bag is gone. Workspace and utility panels now receive explicit bindings or panel-local contexts; do not recreate a catch-all mutable panel service bundle under a new name
Working Rules
- prefer explicit owner/coordinator/runtime-service seams over direct panel to engine hookups
- keep panel dependencies explicit. If a panel needs more data or actions, add a narrow panel-local context or binding instead of routing everything through a generic shared services struct
- when changing runtime or document flow, inspect
EditorSession,EditorRuntimeCoordinator,EditorHostCommandBridge, the relevant feature, and the matching tests - if a change affects ownership, state flow, or command routing, add or update
tests in
tests/UI/Editor/unit - keep multi-window work behind runtime/document correctness; do not move it ahead of core ownership closure
Do Not Regress
- no new service-locator style editor-to-engine dependency
- no new low-level render pass dependency on scene backend creation or lifecycle
- no silent fallback where a command should fail honestly
- no panel-local shortcut that bypasses the intended runtime owner
- no new shared mutable panel-services bag or service-locator style panel dependency bundle
- no scene-open side channel in
EditorProjectRuntime; project UI must call the panel service request hook - no play-mode path that mutates the editable scene in place or skips
EditorScenePlaySession
Good Entry Points
editor/app/Bootstrap/Application.cppeditor/app/Composition/EditorContext.cppeditor/app/Composition/EditorShellRuntime.cppeditor/app/Services/Runtime/EditorRuntimeCoordinator.cppeditor/app/Rendering/Viewport/ViewportHostService.cppeditor/app/Services/Engine/EngineEditorServices.heditor/app/Services/Scene/EditorSceneRuntime.cppeditor/app/Core/Commands/EditorHostCommandBridge.cppdocs/plan/editor-next-stage-runtime-plan.mddocs/plan/editor-engine-services-refactor-plan.md
Verification
Minimum verification for editor app/core changes:
cmake --build build --config Debug --target editor_app_core_tests
cmake --build build --config Debug --target editor_app_feature_tests
When the executable path is affected, also rebuild:
cmake --build build --config Debug --target XCEditor
Relevant focused tests include:
test_editor_host_command_bridge.cpptest_editor_runtime_coordinator.cpptest_game_viewport_runtime.cpptest_project_panel.cpptest_scene_viewport_render_plan.cpptest_scene_viewport_runtime.cpp