feat(render): Campaign V slice V11 commit 1 - delete ImGui, Studio, and the DevTools frontend

The ImGui developer-tools stack (AcDream.UI.ImGui), UI Studio
(src/AcDream.App/Studio), and the DevToolsFramePresenter/
SettingsDevToolsCompositionPhase ImGui composition machinery are removed.
Vulkan never composed a DevTools frontend (DevToolsEnabled already forced
false whenever the backend was Vulkan); this commit makes that permanent by
deleting the only implementation rather than leaving a dead branch behind.

What moved: Studio/SampleData.cs is a live production dependency
(InteractionRetainedUiComposition's character-sheet fallback, plus three
UI.Layout test files) - git mv'd to src/AcDream.App/UI/Layout/SampleData.cs,
namespace AcDream.App.UI.Layout, and trimmed to the SampleCharacter API that
is actually still called (BuildObjectTable/AddItem/AddEquipped/the item-guid
and icon constants had zero callers left once the Studio fixture provider
that used them was deleted).

What survives as backend-neutral seams, per the tests that still exercise
them: IDevToolsFrameLifecycle (moved into RenderFramePreparationController.cs,
now always bound to null), IFramebufferDevToolsTarget/FramebufferDevToolsBinding
in FramebufferResizeController.cs (its concrete DevToolsFramebufferTarget
adapter is deleted), and IDevToolsGameplayCommands in
GameplayInputCommandController.cs (DevToolsGameplayCommands becomes a
documented no-op instead of forwarding to the deleted presenter). A follow-up
re-homes Settings/Debug onto the retained UI through IPanelRenderer; until
then keybind remapping falls back to editing keybinds.json.

DevToolsEnabled is now `private const bool DevToolsEnabled = false`.
RuntimeOptions.DevTools is unchanged and still reaches VulkanGraphicsContext
for the optional debug-utils extensions; Program.cs now logs one line when
ACDREAM_DEVTOOLS=1 explaining that the ImGui UI is gone and the flag is
Vulkan-only now.

Removed: AcDream.UI.ImGui (project + ImGui.NET/Silk.NET.OpenGL.Extensions.ImGui
package refs), src/AcDream.App/Studio (minus SampleData.cs),
DevToolsFramePresenter.cs and everything only it constructed
(ISettingsDevToolsCompositionFactory, RetailSettingsDevToolsCompositionFactory,
DevToolsCompositionOwner, IGameWindowSettingsDevToolsPublication,
SettingsDevToolsOptionalDependencies, the "developer tools" shutdown-ledger
stage and its DevTools-typed fields on IngressShutdownRoots/
RenderShutdownRoots), the ui-studio Program.cs verb, and the cimgui native
manifest entries in GraphicalHostPlatformServices. GameWindow.cs's DevTools
composition branch, its _vitalsVm/_debugVm/_devToolsComposition/
_devToolsFramePresenter/_devToolsCommandBus fields, and every settingsDevTools
.DevTools?.* access across FrameRootComposition.cs/SessionPlayerComposition.cs
are gone with it.

Build green; complete Release solution suite 8,830 / 5 skips (App Tests
4,097/3 skips run standalone - one #250-family zero-allocation test flakes
under the full parallel `dotnet test AcDream.slnx` run, a pre-existing,
documented class unrelated to this change).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-07-28 23:56:04 +02:00
parent db4426d5ef
commit 844cf092a1
48 changed files with 227 additions and 6201 deletions

View file

@ -26,7 +26,6 @@ public sealed class GameWindow :
IGameWindowPlatformPublication<GameWindowGraphics, IInputContext>,
IGameWindowHostInputCameraPublication,
IGameWindowContentEffectsAudioPublication,
IGameWindowSettingsDevToolsPublication,
IGameWindowWorldRenderPublication,
IGameWindowInteractionRetainedUiPublication,
IGameWindowLivePresentationPublication,
@ -91,11 +90,11 @@ public sealed class GameWindow :
private readonly AcDream.App.Rendering.WorldSceneDebugState
_worldSceneDebugState = new();
// Phase I.2: the old StbTrueTypeSharp DebugOverlay was deleted in
// favor of the ImGui-backed DebugPanel (see _debugVm below). The
// TextRenderer + BitmapFont fields stay alive because they're shared
// Phase I.2: the old StbTrueTypeSharp DebugOverlay was deleted in favor of
// the ImGui-backed DebugPanel, which Campaign V slice V11 removed in turn.
// The TextRenderer + BitmapFont fields stay alive because they're shared
// with UiHost and reserved for the future world-space HUD (D.6 —
// damage floaters, name plates) where ImGui can't reach into the 3D
// damage floaters, name plates) where ImGui couldn't reach into the 3D
// scene. They are no longer used for any debug overlay.
private TextRenderer? _textRenderer;
private BitmapFont? _debugFont;
@ -379,12 +378,9 @@ public sealed class GameWindow :
public AcDream.Core.Player.LocalPlayerState LocalPlayer =>
_runtimeCharacter.LocalPlayer;
// Phase D.2a — ImGui devtools UI overlay. Null unless ACDREAM_DEVTOOLS=1.
// See docs/plans/2026-04-24-ui-framework.md for the staged UI strategy.
private AcDream.App.Rendering.DevToolsFramePresenter? _devToolsFramePresenter;
private AcDream.App.Rendering.DevToolsCommandBusSource? _devToolsCommandBus;
private DevToolsCompositionOwner? _devToolsComposition;
private AcDream.UI.Abstractions.Panels.Vitals.VitalsVM? _vitalsVm;
// Phase D.2a — ImGui devtools UI overlay. Removed at Campaign V slice V11;
// see docs/plans/2026-04-24-ui-framework.md for the staged UI strategy and
// docs/plans/2026-07-27-vulkan-campaign.md for the removal.
private AcDream.UI.Abstractions.Panels.Chat.ChatVM? _retailChatVm;
// Phase D.2b — retained host + composition runtime. Null unless ACDREAM_RETAIL_UI=1.
private AcDream.App.UI.UiHost? _uiHost;
@ -418,19 +414,13 @@ public sealed class GameWindow :
_creatureAppraisalFramePresenter;
// Phase D.2b Task 9 — plugin UI registrations buffered before OnLoad; drained in OnLoad.
private readonly AcDream.App.Plugins.BufferedUiRegistry? _uiRegistry;
// Phase I.2: ImGui debug panel ViewModel. The devtools presenter owns
// its panel; the VM remains here because runtime feedback producers bind
// directly to it during composition.
private AcDream.UI.Abstractions.Panels.Debug.DebugVM? _debugVm;
// DevToolsEnabled reads through typed RuntimeOptions.
//
// Campaign V slice V6h: the developer frontend is ImGui, which is not ported
// to Vulkan and which slice V11 deletes outright, so a Vulkan host composes
// none regardless of ACDREAM_DEVTOOLS. The flag still reaches
// VulkanInstanceFactory, where it selects the optional debug-utils
// instance extensions.
private bool DevToolsEnabled =>
_options.DevTools && _options.RenderBackend != RenderBackendKind.Vulkan;
// Campaign V slice V11 deleted the ImGui developer-tools frontend along
// with the OpenGL backend it required, so no host ever composes a
// developer UI regardless of ACDREAM_DEVTOOLS. The flag still reaches
// VulkanGraphicsContext, where it selects the optional debug-utils
// instance/device extensions — see the ACDREAM_DEVTOOLS log line in
// Run() below, which is the one remaining observable effect of the flag.
private const bool DevToolsEnabled = false;
// Phase G.1-G.2 world lighting/time state. The environment owner keeps
// the clock, selected day group, and weather transitions coherent.
@ -922,26 +912,6 @@ public sealed class GameWindow :
_audioSink = value.HookSink;
}
void IGameWindowSettingsDevToolsPublication.PublishDevTools(
DevToolsCompositionOwner value)
{
ArgumentNullException.ThrowIfNull(value);
if (_devToolsComposition is not null
|| _devToolsFramePresenter is not null
|| _devToolsCommandBus is not null
|| _debugVm is not null)
{
throw new InvalidOperationException(
"The GameWindow composition shell already owns developer tools.");
}
_devToolsComposition = value;
_devToolsFramePresenter = value.Presenter;
_devToolsCommandBus = value.CommandBus;
_vitalsVm = value.Vitals;
_debugVm = value.Debug;
}
void IGameWindowWorldRenderPublication.PublishBindlessSupport(
BindlessSupport value) =>
PublishCompositionOwner(
@ -1048,7 +1018,6 @@ public sealed class GameWindow :
{
_uiHost = retained.Host;
_retailUiRuntime = retained.Runtime;
_vitalsVm ??= retained.Vitals;
_retailChatVm = retained.Chat;
_characterSheetProvider = retained.CharacterSheet;
_frameScreenshots = retained.Screenshots;
@ -1347,65 +1316,15 @@ public sealed class GameWindow :
Console.Error.WriteLine),
this).Compose(platformResult, hostInputCamera),
(platformResult, hostInputCamera, contentEffectsAudio) =>
{
SettingsDevToolsOptionalDependencies? optionalDevTools = null;
if (DevToolsEnabled)
{
var devToolsWorldEntities =
new DeferredCanonicalWorldEntityCountSource();
var devToolsFrameDiagnostics =
new DeferredRenderFrameDiagnosticsSource();
var devToolsPlayerModeCommands =
new DeferredDevToolsPlayerModeCommands();
var devToolsFacts = new DevToolsRuntimeFacts(
_localPlayerMode,
_playerControllerSlot,
hostInputCamera.CameraController,
devToolsWorldEntities,
_animatedEntities,
_debugVmRenderFacts,
_physicsEngine,
_worldSceneDebugState,
_renderRange,
hostInputCamera.CameraPointerInput,
_worldEnvironment,
Lighting,
contentEffectsAudio.ParticleSystem,
devToolsFrameDiagnostics);
IRuntimeKeyBindingTarget? keyBindingTarget =
hostInputCamera.InputDispatcher is { } settingsDispatcher
? new RuntimeKeyBindingTarget(
settingsDispatcher,
_applicationPaths.KeyBindingsFile)
: null;
optionalDevTools = new SettingsDevToolsOptionalDependencies(
devToolsFacts,
keyBindingTarget,
devToolsWorldEntities,
devToolsFrameDiagnostics,
devToolsPlayerModeCommands);
}
return new SettingsDevToolsCompositionPhase(
new SettingsDevToolsCompositionPhase(
new SettingsDevToolsDependencies(
_window!,
_runtimeSettings,
new RuntimeSettingsStartupTargets(
new SilkRuntimeDisplayWindowTarget(_window!),
_displayFramePacing,
hostInputCamera.CameraController,
contentEffectsAudio.Audio?.Engine),
_hostQuiescence,
_runtime,
optionalDevTools,
_runtimeDiagnosticCommands,
_combatFeedback,
_keyBindings,
_frameProfiler,
_framebufferResize,
Console.WriteLine),
this).Compose(platformResult, hostInputCamera, contentEffectsAudio);
},
contentEffectsAudio.Audio?.Engine)))
.Compose(platformResult, hostInputCamera, contentEffectsAudio),
(platformResult, contentEffectsAudio, settingsDevTools) =>
{
const uint initialCenterLandblockId = 0xA9B4FFFFu;
@ -1433,9 +1352,10 @@ public sealed class GameWindow :
},
(platformResult, hostInputCamera, contentEffectsAudio, settingsDevTools, worldRender) =>
{
Action<string>? compositionToast = settingsDevTools.DevTools is { } devTools
? text => devTools.Debug.AddToast(text)
: null;
// The ImGui developer-tools debug toast sink was removed at
// Campaign V slice V11 along with the rest of the ImGui
// frontend; there is no replacement toast surface yet.
Action<string>? compositionToast = null;
return new InteractionRetainedUiCompositionPhase(
new InteractionRetainedUiDependencies(
_options,
@ -1469,7 +1389,7 @@ public sealed class GameWindow :
_window!,
viewPlane),
_uiFrameDiagnostics,
settingsDevTools.DevTools?.Vitals,
ExistingVitals: null,
compositionToast,
ClientTimerNow,
Console.WriteLine,
@ -1490,9 +1410,10 @@ public sealed class GameWindow :
worldRender,
interactionUi) =>
{
Action<string>? compositionToast = settingsDevTools.DevTools is { } devTools
? text => devTools.Debug.AddToast(text)
: null;
// The ImGui developer-tools debug toast sink was removed at
// Campaign V slice V11 along with the rest of the ImGui
// frontend; there is no replacement toast surface yet.
Action<string>? compositionToast = null;
return new LivePresentationCompositionPhase(
new LivePresentationDependencies(
_options,
@ -1527,8 +1448,8 @@ public sealed class GameWindow :
_hookRouter,
_renderDiagnosticLog,
WorldTime,
settingsDevTools.DevTools?.LateBindings.WorldEntities,
settingsDevTools.DevTools?.LateBindings.FrameDiagnostics,
DevWorldEntities: null,
DevFrameDiagnostics: null,
_uiFrameDiagnostics,
Console.WriteLine,
compositionToast),
@ -1761,7 +1682,6 @@ public sealed class GameWindow :
_kbSource,
_retailUiLease,
_uiHost,
_devToolsComposition,
_runtime,
_runtimeSettings,
_movementInput,
@ -1797,7 +1717,6 @@ public sealed class GameWindow :
new RenderShutdownRoots(
_gpuFrameFlights,
_gpuDevice,
_devToolsComposition,
_localPlayerTeleport,
_portalTunnelFallback,
_paperdollViewportRenderer,