Fix #144: delegate the XBOX on PC .exe and .pck to Godot's Windows ex… - #151
Conversation
…porter The custom `XBOX on PC` export platform reimplemented Godot's desktop export pipeline by hand instead of driving the engine's own, so it inherited none of Godot's Windows export behaviour. Issue #144 (C# assemblies missing from the package) and issue #134 were both instances of that gap, and so were two more defects found while investigating it: - VRAM-compressed textures were silently dropped from the .pck. Godot resolves an imported texture through `path.<feature>` keys in its `.import` remap and erases every remap whose feature the exporting platform does not report; this platform reported no texture-format tags at all, so `path.s3tc` never matched. A 864 MB `Windows Desktop` .pck came out of `XBOX on PC` at 147 MB and the game died at load on `Can't load dependency`. - The staged .exe kept the stock Godot icon and carried no VERSIONINFO. - The platform reported invented `xbox`, `d3d12` and `x86_64` feature tags, so `OS.has_feature()`, per-feature ProjectSettings overrides and `.import` remaps resolved differently here than under the `Windows Desktop` preset that `gdkpkg` already drives for the same project. Patching these one at a time kept losing races with the engine. Godot 4.5 removed rcedit and moved PE resource patching into a native TemplateModifier that is not exposed to GDScript, so the icon and version-info path cannot be reimplemented from a GDScript export platform at all any more. So stop reimplementing it. `_export_project()` now instantiates EditorExportPlatformWindows and calls `export_project()` on it with *our own* preset, then layers the GDK packaging steps on top of the result: - The .exe, the console wrapper .exe, the .pck, the embedded PE icon, version info, code signing, .NET assemblies, texture-format feature tags, the D3D12 Agility SDK and PIX runtimes, and declared shared objects are all produced by the engine. Whatever Godot adds to its Windows exporter in a future release is inherited for free, and there is no copy of that logic here to fall out of date. - MicrosoftGame.config generation, the support-runtime DLL copy (libHttpClient, Thunks, XCurl, GameChat2), makepkg layout generation and the loose dev-register flow stay here, because they are genuinely GDK-specific. Two mechanical consequences of delegating: - The export option table is load-bearing. The built-in exporter reads its options back off the preset it is handed, so every name it touches must be declared here or it reads back null (omitting `custom_template/debug`, for instance, fails the export with "Mismatching custom export template executable architecture: found 'invalid'"). All 38 options from EditorExportPlatformWindows and EditorExportPlatformPC are now declared verbatim -- the list is identical in Godot 4.5 and 4.6 -- alongside the 3 GDK-specific ones, and Godot's own visibility rules are mirrored so the inspector still collapses the codesign, SSH and non-resource application groups. A test pins the list so drift is caught. - Export feature tags come from the platform *performing* the export, so a delegated run would otherwise drop `gdk`. A small EditorExportPlugin (gdk_export_features_plugin.gd) re-adds it for the duration of a GDK export and stays out of the way otherwise: # Still works from game code under an XBOX on PC export. if OS.has_feature("gdk"): GDK.initialize() # And in project.godot per-feature overrides: # [display] # window/size/mode.gdk=3 No public GDScript API changed; every affected method is internal to the export platform. The user-visible new surface is export-preset options, configured in the export dialog rather than from script -- the full Windows option set is now present under `Project > Export... > XBOX on PC`, including Application (icon, version strings), Texture Format, Binary Format, Codesign and Dotnet. Behaviour change: a loose dev-register export is no longer exempt from the export-template requirement. The old code substituted the running editor binary when no template was installed; Godot's exporter requires a real template, so that stand-in is gone and the export now fails with a clear message instead of producing a package that cannot run standalone. Validation: - tools/run_all_tests.ps1 (full offline tier): overall pass -- parse gate, cmake debug build, C++ doctest, GUT hosts (gdk 330 tests / 3424 asserts, playfab 81, gameinput 60, 0 failures) and all 13 bootstrap mini-runners. - Live tests: skipped (default; no -Live). - Verified end to end against an installed Microsoft GDK: a probe project exported through `XBOX on PC` and `wdapp register` succeeded. - Control experiment: the same project exported through a real `Windows Desktop` preset produced a byte-identical .exe and console .exe (SHA-256), and a .pck differing only by the `gdk` string in `_custom_features`. Fixes #144. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the XBOX on PC Godot export platform to delegate .exe/.pck production to Godot’s built-in EditorExportPlatformWindows, then layers GDK-specific staging and packaging on top. This aligns the exported output with Godot’s native Windows export behavior (templates, C# assemblies as shared objects, texture-format feature tags, icon/VERSIONINFO, etc.) while retaining the GDK-only steps (MicrosoftGame.config, support DLL staging, makepkg layout, wdapp loose registration).
Changes:
- Reworked the export pipeline to call
EditorExportPlatformWindows.export_project()with the platform’s own preset, then perform GDK staging/packaging steps afterward. - Added an
EditorExportPluginthat restores thegdkfeature tag during delegated exports. - Expanded/pinned export option coverage (mirroring the full Windows/PC option set) and updated tests + docs to reflect the new behavior and failure modes.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/godot/gdk/tests/test_export_platform_errors.gd | Adds/updates tests to pin delegation behavior, option coverage, feature tags, and validation/error reporting for templates/custom templates. |
| docs/gdk/editor-tools.md | Updates documentation to explain delegated export behavior, texture-format feature tags, and the new features plugin. |
| addons/godot_gdk/editor/gdk_export_platform.gd | Implements delegation to EditorExportPlatformWindows, adds option mirroring/visibility logic, restores correct feature tagging, and improves export-dialog diagnostics. |
| addons/godot_gdk/editor/gdk_export_features_plugin.gd | New export plugin that re-adds gdk feature tag only during delegated exports. |
| addons/godot_gdk/editor/gdk_editor_plugin.gd | Registers/unregisters the new export-features plugin alongside the export platform. |
| addons/godot_gdk/CMakeLists.txt | Ensures the new plugin script is synced into the sample. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
addons/godot_gdk/editor/gdk_export_platform.gd:1264
- _get_export_option_visibility() collapses fields based on codesign/enable and ssh_remote_deploy/enabled, but _opt() only sets update_visibility for dev/* and application/modify_resources. Without update_visibility on those toggles, the export dialog may not refresh option visibility immediately when the user enables/disables codesign or SSH deploy.
# Options whose value changes which *other* options are shown must ask
# the dialog to re-query _get_export_option_visibility().
"update_visibility": p_name.begins_with("dev/") or p_name == "application/modify_resources",
addons/godot_gdk/editor/gdk_export_platform.gd:453
- This error is emitted to the Output panel via push_error() and currently lacks the "GDK Export:" prefix, which makes it harder to filter/search alongside other export errors (and is inconsistent with other _report_error() call sites in this file).
clear_messages()
if not _gdk_found:
_report_error("GDK not found. Install via: winget install Microsoft.Gaming.GDK")
return ERR_FILE_NOT_FOUND
Reconciles main's game-save quota threading fix (#145 / #152) and the XBOX-on-PC export delegation fix (#144 / #151) with the GDK* -> Xbox* class rename. Conflict resolutions: - xbox_game_save.{h,cpp}: took main's async XAsyncProvider-backed get_remaining_quota_async(), renamed to XboxGameSave/XboxResult/ XboxRuntime/XboxPendingSignal/XboxSignalXAsyncContext/XboxUser. The resurrected gdk_game_save.h was dropped. - XboxGameSave.cs: took main's Task<XboxResult> GetRemainingQuotaAsync(); the resurrected GdkGameSave.cs was dropped. - gdk_editor_plugin.gd / gdk_export_features_plugin.gd: kept main's new export-features plugin, renamed its preload consts to Xbox*. - README.md: kept both main's badges/tagline and the branch's breaking- change warning. - doc_classes/XboxGameSave.xml, docs/gdk/api-reference.md, spec/gdext-gdk.md, tests/godot/gdk/tests/test_game_save.gd: took main's updated Connected Storage / async-quota prose with Xbox* type names. Validation: check_gd_scripts_headless.ps1 clean; run_all_tests.ps1 overall pass (471 GUT tests, 0 failed; live tier skipped, no -Live/-AllowLiveWrites). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…porter
The custom
XBOX on PCexport platform reimplemented Godot's desktop export pipeline by hand instead of driving the engine's own, so it inherited none of Godot's Windows export behaviour. Issue #144 (C# assemblies missing from the package) and issue #134 were both instances of that gap, and so were two more defects found while investigating it:path.<feature>keys in its.importremap and erases every remap whose feature the exporting platform does not report; this platform reported no texture-format tags at all, sopath.s3tcnever matched. A 864 MBWindows Desktop.pck came out ofXBOX on PCat 147 MB and the game died at load onCan't load dependency.xbox,d3d12andx86_64feature tags, soOS.has_feature(), per-feature ProjectSettings overrides and.importremaps resolved differently here than under theWindows Desktoppreset thatgdkpkgalready drives for the same project.Patching these one at a time kept losing races with the engine. Godot 4.5 removed rcedit and moved PE resource patching into a native TemplateModifier that is not exposed to GDScript, so the icon and version-info path cannot be reimplemented from a GDScript export platform at all any more.
So stop reimplementing it.
_export_project()now instantiates EditorExportPlatformWindows and callsexport_project()on it with our own preset, then layers the GDK packaging steps on top of the result:Two mechanical consequences of delegating:
The export option table is load-bearing. The built-in exporter reads its options back off the preset it is handed, so every name it touches must be declared here or it reads back null (omitting
custom_template/debug, for instance, fails the export with "Mismatching custom export template executable architecture: found 'invalid'"). All 38 options from EditorExportPlatformWindows and EditorExportPlatformPC are now declared verbatim -- the list is identical in Godot 4.5 and 4.6 -- alongside the 3 GDK-specific ones, and Godot's own visibility rules are mirrored so the inspector still collapses the codesign, SSH and non-resource application groups. A test pins the list so drift is caught.Export feature tags come from the platform performing the export, so a delegated run would otherwise drop
gdk. A small EditorExportPlugin (gdk_export_features_plugin.gd) re-adds it for the duration of a GDK export and stays out of the way otherwise:No public GDScript API changed; every affected method is internal to the export platform. The user-visible new surface is export-preset options, configured in the export dialog rather than from script -- the full Windows option set is now present under
Project > Export... > XBOX on PC, including Application (icon, version strings), Texture Format, Binary Format, Codesign and Dotnet.Behaviour change: a loose dev-register export is no longer exempt from the export-template requirement. The old code substituted the running editor binary when no template was installed; Godot's exporter requires a real template, so that stand-in is gone and the export now fails with a clear message instead of producing a package that cannot run standalone.
Validation:
XBOX on PCandwdapp registersucceeded.Windows Desktoppreset produced a byte-identical .exe and console .exe (SHA-256), and a .pck differing only by thegdkstring in_custom_features.Fixes #144.
Summary
Public API changes
Spec / docs / samples updated
spec\gdext-<feature>.mdupdated (Plan / Progress sections if multi-session work)docs\godot-<addon>-*.mdupdatedaddons\<addon>\doc_classes\*.xmlupdated for any public API changesample\<host>\) updated when public addon behaviour changed.github\instructions\<addon>.instructions.md) updated if conventions changedTest coverage delta
Validation run
Migration notes
None.