Skip to content

feat: hybrid NetcodeConfig defaults - #4144

Open
NoelStephensUnity wants to merge 3 commits into
develop-3.x.xfrom
feat/hybrid-netcodeconfig-defaults
Open

feat: hybrid NetcodeConfig defaults#4144
NoelStephensUnity wants to merge 3 commits into
develop-3.x.xfrom
feat/hybrid-netcodeconfig-defaults

Conversation

@NoelStephensUnity

Copy link
Copy Markdown
Member

Purpose of this PR

This PR introduces an automated NetcodeConfig default settings feature where NGO will, at a minimum, configure NGO user's NetcodeConfig settings to the recommended settings.

The UI

When there are no hybrid prefabs within a network prefab list used by a NetworkManager, the Multiplayer Netcode for GameObjects UI will display that there are no hybrid prefabs (network prefab with GhostObject) and the default settings do not apply until there is at least one.
image

Once a hybrid prefab has been detected it will apply the default settings once, log a notification (to the console currently, but we can make this a one time dialog box), and then the UI adjusts to provide users with the ability to re-apply the default settings in the event they tinker with things and want to get back to the recommended default settings:
image

Jira ticket

MTT-15571

Changelog

  • Added: The package whose Changelog should be added to should be in the header. Delete the changelog section entirely if it's not needed.
  • Fixed: If you update multiple packages, create a new section with a new header for the other package.
  • Removed/Deprecated/Changed: Each bullet should be prefixed with Added, Fixed, Removed, Deprecated, or Changed to indicate where the entry should go.

Documentation

  • Includes documentation (wip)

Testing & QA (How your changes can be verified during release Playtest)

Functional Testing

Manual testing :

  • Manual testing done
    • To fully test this you need to:
      • Create a project using an earlier version of 6000.x.x than 6000.7.0a5
        • Add a NetworkManager to the SampleScene.
        • Create a network prefab and add a NetworkObject to it.
        • Add these two defines to your project's players defines:
          • NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL
          • NETCODE_EXPERIMENTAL_SINGLE_WORLD_HOST
          • These are being removed, but currently you still need to add them.
      • If you plan on iterating, make this a local repo to roll back to the default pre-upgrade settings.
    • Open the project using 6000.7.0a5+.
      • Select your network prefab and check the "Network" box.
      • Navigate to the project settings --> Multiplayer --> Netcode for GameObjects.
      • You should see something like the blow picture:
image

You can also look at the NetcodeConfig.asset file and spot check (if the snapshot size has been increased to 15000 then the NGO settings were automatically applied).

Automated tests:

  • Covered by existing automated tests
  • Covered by new automated tests

Does the change require QA team to:

  • Review automated tests?
  • Execute manual tests?
  • Provide feedback about the PR?

If any boxes above are checked the QA team will be automatically added as a PR reviewer.

Up-port

None

Backports

None

When Netcode for Entities is installed and a registered network prefab
carries a GhostObject, the project's NetCodeConfig is now aligned with
what NGO needs rather than leaving it to the user to discover.

The two settings hybrid mode cannot run without (single world hosting,
and automatic bootstrapping disabled since NetworkManager owns world
creation) are corrected whenever they drift. The Netcode for Entities
tick rates are driven from NetworkConfig.TickRate so that ghost
transform updates land on the same interval as everything else. The
snapshot, interpolation and transport values tuned against the 2000
instance stress test are applied once and then left alone, so a user's
own edits survive; Project Settings > Multiplayer > Netcode for
GameObjects can restore them.

The config is never created here. Netcode for Entities already creates
one unconditionally from its own InitializeOnLoadMethod, and creating a
second lands the project in its multiple-config error path.

Also:
- UnifiedIsConfiguredCorrectly now validates EnableClientServerBootstrap
  and warns when the two tick rates diverge. Its two log messages were
  missing their string interpolation prefixes.
- m_TempStreamSize returns to the Netcode for Entities default of 8192.
  GhostSendSystem takes max(TempStreamInitialSize, dataStream.Capacity),
  and capacity is DefaultSnapshotPacketSize, so 4192 had no effect.
- Unity.Netcode.Editor.Tests gains the UNIFIED_NETCODE version define.
  Without it any hybrid editor test compiles away and reports zero cases
  rather than failing.
- Adds a measurement fixture for sizing DefaultSnapshotPacketSize. It is
  marked Explicit so its 24 cases stay out of the suites.
Some comment clean up.
@NoelStephensUnity
NoelStephensUnity requested review from a team and EmandM as code owners August 25, 2026 15:08

@u-pr u-pr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Harness Review

Needs changes

The new hybrid configuration flow establishes the intended defaults and exposes them in settings, but several reachable editor states prevent it from preserving or aligning those defaults correctly.

Reviewed commit 49e605e

🤖 Helpful? 👍/👎

changed |= HybridNetcodeDefaults.ApplyTickRate(config, ResolveTickRate(config));
}

if (!changed)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1

When this is the first pass but the config already happens to equal the recommended values, changed is false and this early return leaves HybridDefaultsVersion at zero. For example, a user can configure these values manually before registering their first ghost prefab, then later change one setting; the next domain reload treats it as a first application and overwrites that edit. Persist the version marker on a successful first/recommended pass even when there was no config mutation (while only dirtying/saving the config when it actually changed).

🤖 Helpful? 👍/👎

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@u-pr you can disregard this mechanism because a user applying their own settings before having added a hybrid prefab very likely doesn't realize there are recommended settings in order to yield the best results. Users editing the NetcodeConfig before they have created their 1st hybrid prefab for the 1st time most likely are not aware of this default setting.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Understood, that makes sense. If the intended design is to prioritize ensuring the NGO hybrid defaults are applied once hybrid mode is first actively used regardless of prior pre-hybrid configuration, leaving the current flow as-is makes total sense.

🤖 Helpful? 👍/👎

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@u-pr can you review all of the areas you pointed out potential issues?
They should all be resolved now.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Reviewed the updated changes, and everything looks solid and properly resolved:

  1. Version Marker Persistence (HybridNetcodeConfigApplier.cs): Persisting HybridDefaultsVersion and saving settings inside the applyRecommended || isFirstApply block ensures domain reloads won't treat an already-matching config as a first apply or overwrite subsequent user modifications.
  2. String Interpolation & Bootstrap Validation (NetworkManager.cs): The un-interpolated string format issue in UnifiedIsConfiguredCorrectly is resolved, and validation now properly leverages HybridNetcodeDefaults.IsMissingRequired to check both single-world hosting and disabled automatic bootstrapping.
  3. Tick Rate & Scene Loading (HybridNetcodeConfigApplier.cs): Subscribing to EditorSceneManager.sceneOpened handles unopened scenes gracefully to pick up NGO NetworkManager tick rates post-initialization.
  4. Test Coverage (HybridNetcodeDefaultsTests.cs): The added unit tests thoroughly cover the one-shot application behavior, required settings enforcement, tick rate locking, and hybrid project detection.

🤖 Helpful? 👍/👎

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@u-pr Since all of the issues you found are resolved, can you update the status of your review?
(still says "needs changes")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I cannot directly update or clear the GitHub review status (e.g., changing "Changes requested" to "Approved").

  • Why: I do not have the permissions or tooling to submit formal PR review state changes or dismiss existing reviews.
  • Alternatives: A repository maintainer or reviewer can manually dismiss the previous review or submit an approving review now that the issues have been addressed.

🤖 Helpful? 👍/👎

}

diverged |= found != 0 && found != tickRate;
found = tickRate;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1

This selects the tick rate from every loaded NetworkManager, rather than from the manager(s) that registered a ghost prefab. With a hybrid manager at 30 Hz and an unrelated conventional manager at 60 Hz that is enumerated later, the global config is set to 60 Hz; starting the hybrid manager then hits the new mismatch warning and its ghost timeline is not aligned with its NGO tick rate. Restrict this selection to managers that actually reference a ghost prefab (and handle conflicting hybrid-manager rates explicitly) instead of taking the last manager encountered.

🤖 Helpful? 👍/👎

/// </summary>
internal static bool IsHybridProject()
{
foreach (var networkManager in Resources.FindObjectsOfTypeAll<NetworkManager>())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1

FindObjectsOfTypeAll only sees loaded objects; it does not enumerate NetworkManagers in unopened scene or prefab assets. Thus, if a project has its manager-with-ghost-registration in a closed scene at domain reload, this returns false and no defaults are applied. Opening that scene later does not invoke this initialization hook, and the postprocessor only reacts to imports of ghost GameObjects, so entering Play Mode can still fail the required hybrid configuration validation. Discover persisted manager assets (or trigger a rescan when their registration changes/when scenes open) rather than relying solely on currently loaded managers.

🤖 Helpful? 👍/👎

Fixing some things u-pr caught and adding a test to validate the update.
@danni-lu

Copy link
Copy Markdown

Is it possible to add a call to action to the console log that the user can click on the directly open the relevant page?
networkConfigParamter foldout content is a bit too much to the right, can shift 1 level to the left
If I press the apply recommended hybrid defaults button, are settings above it be changed?

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.

2 participants