Skip to content

feat(gdk): expose the XNetworking API surface as GDK.networking - #157

Merged
James Lenell (jameslen-atg) merged 4 commits into
mainfrom
feat/xnetworking
Aug 21, 2026
Merged

feat(gdk): expose the XNetworking API surface as GDK.networking#157
James Lenell (jameslen-atg) merged 4 commits into
mainfrom
feat/xnetworking

Conversation

@jameslen-atg

Copy link
Copy Markdown
Member

Adds a new GDK.networking service (XboxNetworking) that exposes the full Microsoft GDK XNetworking.h surface, following the established one-service-namespace-under-the-GDK-singleton pattern.

What's exposed

Method Native API
query_preferred_local_udp_multiplayer_port() XNetworkingQueryPreferredLocalUdpMultiplayerPort
query_preferred_local_udp_multiplayer_port_async() XNetworkingQueryPreferredLocalUdpMultiplayerPortAsync (+ Result)
get_connectivity_hint() XNetworkingGetConnectivityHint
query_security_information_for_url_async(url) XNetworkingQuerySecurityInformationForUrlAsync (+ ResultSize / Result)
query_configuration_setting(setting) XNetworkingQueryConfigurationSetting
set_configuration_setting(setting, value) XNetworkingSetConfigurationSetting
query_statistics(statistics_type) XNetworkingQueryStatistics
preferred_local_udp_multiplayer_port_changed signal XNetworkingRegister/UnregisterPreferredLocalUdpMultiplayerPortChanged
connectivity_hint_changed signal XNetworkingRegister/UnregisterConnectivityHintChanged

Plus a new XboxNetworkingSecurityInformation RefCounted wrapper for NSAL results.

Usage

var init: XboxResult = GDK.initialize()
if not init.is_ok():
    push_error(init.message)
    return

# Gate networking on network_initialized — it is the only authoritative field
# in the hint. Everything else is a best-effort device-wide signal.
GDK.networking.connectivity_hint_changed.connect(func(hint: Dictionary) -> void:
    if hint["network_initialized"]:
        start_matchmaking()
    else:
        show_offline_banner(hint["connectivity_level_name"])
)

var hint_result: XboxResult = GDK.networking.get_connectivity_hint()
if hint_result.is_ok():
    print(hint_result.data["connectivity_level_name"], " / ", hint_result.data["connectivity_cost_name"])

# Rebind when the system changes the preferred multiplayer port.
GDK.networking.preferred_local_udp_multiplayer_port_changed.connect(
    func(port: int) -> void: rebind_udp_socket(port)
)

# Prefer the async query on the main thread; the GDK documents the sync overload
# as unsafe on time-sensitive threads.
var port_result: XboxResult = await GDK.networking.query_preferred_local_udp_multiplayer_port_async()
if port_result.is_ok():
    rebind_udp_socket(port_result.data["port"])

# The sync overload is still available for worker threads.
var sync_port: XboxResult = GDK.networking.query_preferred_local_udp_multiplayer_port()

# NSAL certificate thumbprints for a title endpoint registered in Partner Center.
var security: XboxResult = await GDK.networking.query_security_information_for_url_async("https://api.example.com")
if security.is_ok():
    var info: XboxNetworkingSecurityInformation = security.data
    print(info.get_enabled_http_security_protocol_flags())
    for thumbprint in info.get_thumbprints():
        print("%s: %s" % [thumbprint["type_name"], thumbprint["hex"]])

# TCP queued-receive-buffer configuration and statistics (no-ops on Windows).
var setting := XboxNetworking.CONFIGURATION_SETTING_MAX_TITLE_TCP_QUEUED_RECEIVE_BUFFER_SIZE
var cfg: XboxResult = GDK.networking.query_configuration_setting(setting)
if cfg.is_ok():
    print(cfg.data["value"], " unlimited=", cfg.data["unlimited"])

var applied: XboxResult = GDK.networking.set_configuration_setting(setting, 1024 * 1024)
if not applied.is_ok() and applied.code == "not_supported_on_platform":
    print("configuration settings are a documented no-op on Windows")

var stats: XboxResult = GDK.networking.query_statistics(
    XboxNetworking.STATISTICS_TYPE_TITLE_TCP_QUEUED_RECEIVED_BUFFER_USAGE)
if stats.is_ok():
    print(stats.data["peak_num_bytes_ever_queued"])

C# facade parity (Xbox.Networking) ships in the same change:

var hint = Xbox.Networking.GetConnectivityHint();
if (hint.Ok && (bool)hint.Data["network_initialized"])
{
    StartMatchmaking();
}

Deliberate exclusions

Both are documented in spec/gdext-gdk.md and docs/gdk/api-reference.md rather than silently dropped:

  • XNetworkingVerifyServerCertificate — its requestHandle is a WinHTTP HINTERNET produced by WinHttpOpenRequest, and it is meant to be called from inside a WINHTTP_CALLBACK_STATUS_SENDING_REQUEST callback. Godot's HTTPClient / HTTPRequest expose no such handle, so it cannot be called correctly from GDScript. XboxNetworkingSecurityInformation intentionally retains the native result buffer so a native-interop entry point can be added later without a breaking change.
  • XNetworkingQuerySecurityInformationForUrlUtf16Async — differs from the UTF-8 entry point only in input encoding, which is not observable through Godot's single String type.

Behavior notes

  • Both change registrations are established during GDK.initialize() on the shared task queue and torn down on shutdown. The GDK fires an initial callback on registration, so the first emission of each signal reports current state rather than a change. Registration failure degrades with a warning (signals disabled, queries still work) instead of failing GDK.initialize() — same graceful-degradation posture as GDK.activation.
  • query_configuration_setting, set_configuration_setting, and query_statistics are documented Windows no-ops (setter returns E_NOTIMPL, surfaced as the not_supported_on_platform code; queries return zeros). Wrapped anyway so the surface is identical on console-capable Godot forks.
  • Native uint64 configuration values do not round-trip through GDScript's signed int, so query_configuration_setting reports a companion unlimited: bool for the UINT64_MAX case.
  • This service builds no transport. It is a diagnostics/configuration surface only, matching the GDK.game_chat rule that titles own their own networking.

Docs and spec

  • spec/gdext-gdk.md — new scope-table row, a GDK.networking service section with a native API mapping table, and reconciliation of the two stale "do not wrap XNetworking" lists that predate this change.
  • spec/gdext-csharp.md, docs/gdk/api-reference.md, docs/gdk/plugin.md, docs/gdk/async-system.md, docs/gdk/native-runtime.md, docs/README.md — service enumerations and the full reference section.

No sample content was added: the connectivity/NSAL surfaces have no meaningful offline demo, and the tutorial tracks are being reworked separately.

Validation

  • Parse gate: tools\check_gd_scripts_headless.ps1 — pass.
  • Orchestrator: tools\run_all_tests.ps1pass (offline tier). GDK host went 330 → 336 tests, 3094 → 3209 asserts, 0 failed; PlayFab and GameInput hosts unchanged and green; C++ doctest and all bootstrap mini-runners green.
  • C# parity: tools\run_csharp_tests.ps1 — 109 passed, 0 failed (was 107; +2 for the two new doc_classes).
  • New GUT suite tests/godot/gdk/tests/test_networking.gd — 6/6 passing, 115 asserts, no pendings on a machine with the GDK runtime available.
  • Live coverage: live tests were skipped (no -Live, no -AllowLiveWrites). Nothing in this change writes online state.

Adds a new `GDK.networking` service (`XboxNetworking`) wrapping the Microsoft
GDK `XNetworking.h` family: the preferred local UDP multiplayer port (sync,
async, and change signal), device connectivity hints (query + change signal),
NSAL certificate information for title endpoints, and the TCP queued-receive
buffer configuration/statistics surfaces.

`XboxNetworkingSecurityInformation` is a new RefCounted wrapper that owns the
native result buffer for its lifetime, because the native record's thumbprint
pointers point into it.

Two entry points are deliberately not wrapped, and the spec/docs say why:
`XNetworkingVerifyServerCertificate` requires a WinHTTP HINTERNET handle Godot
does not expose, and the Utf16 security-information variant differs only in
input encoding, which Godot's single String type cannot express.

The configuration/statistics methods are documented no-ops on Windows. They are
wrapped anyway so the surface is identical on console-capable Godot forks.

Also updates spec/gdext-gdk.md (scope table, service section with native API
mapping, and the two stale "do not wrap XNetworking" lists), spec/gdext-csharp.md,
docs/gdk/api-reference.md, docs/gdk/plugin.md, docs/gdk/async-system.md,
docs/gdk/native-runtime.md, docs/README.md, the C# facade, and adds GUT coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f04a7dcf-127c-4e73-adea-f19c823ab5fa

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

Adds a new GDK.networking service (XboxNetworking) to the godot_gdk addon to expose the script-facing Microsoft GDK XNetworking.h diagnostics/configuration surface (ports, connectivity hints, NSAL security info, TCP queued-receive-buffer settings/stats), plus C# facade parity and supporting docs/tests.

Changes:

  • Introduces XboxNetworking + XboxNetworkingSecurityInformation (C++ bindings, registration, singleton wiring, doc_classes).
  • Adds GUT coverage for the new service and updates specs/docs to document the new surface and deliberate exclusions.
  • Adds C# service/type wrappers (Xbox.Networking) and updates C# mapping spec.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/godot/gdk/tests/test_networking.gd New GUT suite covering GDK.networking surface, validation, and payload shapes.
spec/gdext-gdk.md Adds GDK.networking to scope table and spec section with API mapping/notes.
spec/gdext-csharp.md Documents C# parity mapping for Xbox.Networking.
docs/README.md Adds GDK.networking to top-level docs service list.
docs/gdk/plugin.md Mentions networking service in plugin overview and service enumeration.
docs/gdk/native-runtime.md Updates runtime structure/service lists to include GDK.networking.
docs/gdk/async-system.md Updates async system docs to include GDK.networking and new implementation files.
docs/gdk/api-reference.md Adds full API reference section for GDK.networking including payload details.
addons/godot_gdk/src/xbox.h Adds XboxNetworking forward decl, member, and getter.
addons/godot_gdk/src/xbox.cpp Instantiates the service, binds it, exposes property, and wires init/shutdown steps.
addons/godot_gdk/src/xbox_networking.h New C++ service + NSAL wrapper type declarations and Godot bindings.
addons/godot_gdk/src/xbox_networking.cpp New implementation of XNetworking wrappers, signal registration, and payload shaping.
addons/godot_gdk/src/register_types.cpp Registers the new classes with Godot.
addons/godot_gdk/doc_classes/XboxNetworkingSecurityInformation.xml New class reference docs for NSAL result wrapper.
addons/godot_gdk/doc_classes/XboxNetworking.xml New class reference docs for XboxNetworking service.
addons/godot_gdk/doc_classes/Xbox.xml Documents the new get_networking() and networking member on the root singleton.
addons/godot_gdk/CMakeLists.txt Adds xbox_networking.cpp to the addon build.
addons/godot_gdk_csharp/Xbox.cs Adds Xbox.Networking static service accessor + reset wiring.
addons/godot_gdk_csharp/Types/XboxNetworkingSecurityInformation.cs New C# wrapper type for the NSAL security info object.
addons/godot_gdk_csharp/Services/XboxNetworking.cs New C# service wrapper with events and methods matching the GDScript surface.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/gdk/native-runtime.md Outdated
Comment thread addons/godot_gdk/src/xbox_networking.cpp
Comment thread addons/godot_gdk/src/xbox_networking.cpp
- Include <cstring> and <limits> in xbox_networking.cpp. memcpy() was relying on
  a transitive include; every other addon source that calls it includes <cstring>
  explicitly.
- Replace unchecked static_cast<int64_t>(uint64_t) with the to_variant_u64()
  clamping helper already used by xbox_package.cpp. The raw cast is only
  well-defined from C++20 on, and any out-of-range value silently wrapped
  negative, contradicting the documented payload. Applied to both
  query_configuration_setting() and the query_statistics() byte counters, which
  had the same unchecked conversion.
- Correct the stale "21 public service namespaces" count in native-runtime.md
  now that the enumerated list has 22.
- Sync the clamping contract into XboxNetworking.xml, docs/gdk/api-reference.md,
  and spec/gdext-gdk.md, and state that `unlimited` (not a -1 test) is the
  authoritative flag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f04a7dcf-127c-4e73-adea-f19c823ab5fa
Copilot AI review requested due to automatic review settings August 21, 2026 16:49

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 20 out of 20 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

addons/godot_gdk/src/xbox_networking.cpp:219

  • QuerySecurityInformationAsyncContext::finalize() passes buffer_size into XboxNetworkingSecurityInformation::set_native_internal(...), but the GDK also returns bytes_used (the actual bytes written). Storing the requested size instead of the used size can make m_buffer_size inaccurate for future native-interop use and makes it harder to validate the buffer contents.
        Ref<XboxNetworkingSecurityInformation> info;
        info.instantiate();
        info->set_native_internal(std::move(buffer), buffer_size, native);
        get_pending_signal()->complete(XboxResult::ok_result(info));

Comment on lines +14 to +18
The current native implementation has one root singleton and 22 public service namespaces:

- root singleton: `GDK`
- service namespaces: `GDK.users`, `GDK.game_ui`, `GDK.accessibility`, `GDK.achievements`, `GDK.package`, `GDK.stats`, `GDK.leaderboards`, `GDK.privacy`, `GDK.presence`, `GDK.social`, `GDK.store`, `GDK.profile`, `GDK.string_verify`, `GDK.title_storage`, `GDK.error_reporting`, `GDK.launcher`, `GDK.multiplayer_activity`, `GDK.capture`, `GDK.system`, `GDK.display`, and `GDK.activation`
- wrapper types: `XboxResult`, `XboxUsers`, `XboxUser`, `XboxGameUI`, `XboxAccessibility`, `XboxClosedCaptionProperties`, `XboxAchievements`, `XboxAchievement`, `XboxPackage`, `XboxPackageMount`, `XboxPackageResourcePack`, `XboxStats`, `XboxLeaderboards`, `XboxLeaderboard`, `XboxLeaderboardColumn`, `XboxLeaderboardRow`, `XboxPrivacy`, `XboxPresence`, `XboxPresenceRecord`, `XboxSocial`, `XboxSocialFilter`, `XboxSocialGroup`, `XboxSocialUser`, `XboxStore`, `XboxStoreLicenseStatus`, `XboxProfile`, `XboxUserProfile`, `XboxStringVerify`, `XboxTitleStorage`, `XboxTitleStorageBlobMetadata`, `XboxTitleStorageBlobMetadataResult`, `XboxErrorReporting`, `XboxLauncher`, `XboxMultiplayerActivity`, `XboxMultiplayerActivityInfo`, `XboxCapture`, `XboxCaptureMetaData`, `XboxSystem`, `XboxDisplay`, `XboxDisplayTimeoutDeferral`, and `XboxActivation`
- service namespaces: `GDK.users`, `GDK.game_ui`, `GDK.accessibility`, `GDK.achievements`, `GDK.package`, `GDK.stats`, `GDK.leaderboards`, `GDK.privacy`, `GDK.presence`, `GDK.social`, `GDK.store`, `GDK.profile`, `GDK.string_verify`, `GDK.title_storage`, `GDK.error_reporting`, `GDK.launcher`, `GDK.multiplayer_activity`, `GDK.capture`, `GDK.system`, `GDK.display`, `GDK.activation`, and `GDK.networking`
- wrapper types: `XboxResult`, `XboxUsers`, `XboxUser`, `XboxGameUI`, `XboxAccessibility`, `XboxClosedCaptionProperties`, `XboxAchievements`, `XboxAchievement`, `XboxPackage`, `XboxPackageMount`, `XboxPackageResourcePack`, `XboxStats`, `XboxLeaderboards`, `XboxLeaderboard`, `XboxLeaderboardColumn`, `XboxLeaderboardRow`, `XboxPrivacy`, `XboxPresence`, `XboxPresenceRecord`, `XboxSocial`, `XboxSocialFilter`, `XboxSocialGroup`, `XboxSocialUser`, `XboxStore`, `XboxStoreLicenseStatus`, `XboxProfile`, `XboxUserProfile`, `XboxStringVerify`, `XboxTitleStorage`, `XboxTitleStorageBlobMetadata`, `XboxTitleStorageBlobMetadataResult`, `XboxErrorReporting`, `XboxLauncher`, `XboxMultiplayerActivity`, `XboxMultiplayerActivityInfo`, `XboxCapture`, `XboxCaptureMetaData`, `XboxSystem`, `XboxDisplay`, `XboxDisplayTimeoutDeferral`, `XboxActivation`, `XboxNetworking`, and `XboxNetworkingSecurityInformation`

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.

Fixed in d96a9a0 — updated the remaining reference to 22 public namespaces.

Co-authored-by: jameslen-atg <24258495+jameslen-atg@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

Copilot reviewed 20 out of 20 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 21, 2026 17: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 20 out of 20 changed files in this pull request and generated no new comments.

@jameslen-atg
James Lenell (jameslen-atg) merged commit 0f3184a into main Aug 21, 2026
10 checks passed
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.

4 participants