WinUI 3 Host
The WinUI 3 host embeds the engine inside a Windows App SDK window and drives it from the XAML UI thread. Like the WinForms host, its UI is deliberately minimal: a panel the game renders into and a working Pause/Resume button, ready to be extended with your own controls.
Use It
The host is opt-in and Windows-only - unlike WinForms, it does not even build on other systems, so the generated solution excludes it from plain solution builds:
dnx 2dog add --winui
dotnet new 2dog -n MyGame --winui true # new project
dotnet run --project MyGame.winuiThe repository's own instance is demos/showcase/showcase.winui.
Capabilities
- Embeds Godot in a WinUI 3 window (Windows App SDK, unpackaged, self-contained -
dotnet runworks without MSIX packaging or the Windows App Runtime installer). - Interleaves Godot frames and XAML events on one STA UI thread.
- Lets event handlers safely access the scene tree.
- Tracks per-monitor DPI: XAML lengths are DIPs, so the host scales the embed rectangle by the panel's
RasterizationScale.
How It Works
The embedding mechanism is the same --wid <window_id> argument the WinForms host uses (and the Godot editor's embedded game window): given the WinUI window's HWND, the engine creates its main window as a borderless popup owned by that handle, and the host drives its geometry with SetWindowPos from SizeChanged, AppWindow.Changed, and XamlRoot.Changed handlers.
Two things are WinUI-specific:
- The host is a code-only WinUI 3 app. With no XAML in the project there is no generated metadata provider, so the
Applicationsubclass forwards WinUI's ownXamlControlsXamlMetaDataProvideritself and mergesXamlControlsResourcesinOnLaunched- without those, the first control lookup dies in native code with a stowed exception (0xC000027B). - The frame pump is a self-reposting dispatcher callback. WinUI has no idle event, so the host enqueues one
Iteration()per pass atDispatcherQueuePriority.Low; normal-priority input and layout always interleave, and the UI thread stays the pump thread - event handlers can touch the scene tree (viaengine.Tree) directly.
Teardown happens in AppWindow.Closing/Closed, while the owner HWND still exists - Godot self-closes its window when the owner disappears, and the engine must be gone before the process-exit libgodot unload runs.
Limitations
- Windows only, at build time too: the Windows App SDK tooling has no cross-compilation story, which is why the solution carries the project with
<Build Project="false" />. For a cross-platform GUI host, use the Avalonia host. - The embedded window always draws above the XAML content, so WinUI controls cannot overlap the game rectangle - the Avalonia host composites instead, which lifts this restriction.
--widmarks the instance as embedded (Engine.is_embedded_in_editor()returnstrueto scripts).