Skip to content

Fix #144: delegate the XBOX on PC .exe and .pck to Godot's Windows ex… - #151

Merged
James Lenell (jameslen-atg) merged 2 commits into
mainfrom
fix/144-texture-features
Aug 13, 2026
Merged

Fix #144: delegate the XBOX on PC .exe and .pck to Godot's Windows ex…#151
James Lenell (jameslen-atg) merged 2 commits into
mainfrom
fix/144-texture-features

Conversation

@jameslen-atg

Copy link
Copy Markdown
Member

…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.

Summary

Public API changes

# Example for a new API:
# var result := await PlayFab.users.sign_in_with_custom_id_async("my-id").completed

Spec / docs / samples updated

  • spec\gdext-<feature>.md updated (Plan / Progress sections if multi-session work)
  • docs\godot-<addon>-*.md updated
  • addons\<addon>\doc_classes\*.xml updated for any public API change
  • Sample content (sample\<host>\) updated when public addon behaviour changed
  • Path-scoped instruction file (.github\instructions\<addon>.instructions.md) updated if conventions changed
  • Not applicable — no public addon behaviour changed

Test coverage delta

  • Contract (offline) tests added/removed: …
  • Live-read tests added/removed: …
  • Live-write tests added/removed: …
  • Live title id used (if any): …

Validation run

# Example:
# pwsh ...\check_gd_scripts_headless.ps1   -> PASS (52 files)
# pwsh ...\run_all_tests.ps1               -> PASS (parse, build, doctest, GUT, bootstrap)
# pwsh ...\run_all_tests.ps1 -Live         -> PASS (live reads only; live writes pending)

Migration notes

None.

…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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 EditorExportPlugin that restores the gdk feature 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.

Comment thread addons/godot_gdk/editor/gdk_export_platform.gd
Copilot AI review requested due to automatic review settings August 13, 2026 20:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@jameslen-atg
James Lenell (jameslen-atg) merged commit f5d855c into main Aug 13, 2026
10 checks passed
@jameslen-atg
James Lenell (jameslen-atg) deleted the fix/144-texture-features branch August 13, 2026 21:17
James Lenell (jameslen-atg) pushed a commit that referenced this pull request Aug 14, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

XBOX on PC export preset does not copy C# .dll to build directory

3 participants