Skip to content

chore: netcode for entities 7.0.0 as a dependency - #4158

Merged
michalChrobot merged 13 commits into
develop-3.x.xfrom
chore/n4e-hard-dependency
Sep 14, 2026
Merged

michalChrobot merged 13 commits into
develop-3.x.xfrom
chore/n4e-hard-dependency

Conversation

@NoelStephensUnity

@NoelStephensUnity NoelStephensUnity commented Sep 8, 2026 •

Copy link
Copy Markdown
Member

Parts of this are taken from #4156.

Purpose of this PR

N4E becomes a hard dependency at 7.0.0, and com.unity.transport moves to 6.7.0 to match it. We update our CI to match the actual minimal supported editor.
We had to disable the serialization tests that would otherwise fail under CoreCLR in the editor later (as we don't have CI for it yet here)

  • N4E 7.0.0 ships its unified API - GhostObject, GhostBehaviour, GhostField behind NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL.
  • testproject and minimalproject were updated to 6000.7.0b1

Jira ticket

MTT-14623

Changelog

  • Added: Netcode for Entities (com.unity.netcode 7.0.0) is now a hard dependency, so installing Netcode for GameObjects also brings it, and its own dependencies (Entities, Burst, Collections), into the project.

Documentation

  • No documentation changes or additions were necessary.

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

Green Ci should validate this properly

Up-port

No up-port is required.

Backports

No back-port is required.

… a define

N4E becomes a hard dependency at 7.0.0, and com.unity.transport moves to 6.5.0 to match it.

N4E 7.0.0 ships its unified API - GhostObject, GhostBehaviour, GhostField - behind
NETCODE_GAMEOBJECT_BRIDGE_EXPERIMENTAL, which leaves those types internal in the configuration
NGO ships. A public type cannot derive from an internal one, so the unified path can no longer key
off the package being present: the UNIFIED_NETCODE versionDefine is removed from the four assembly
definitions and the symbol is set by the project instead, alongside N4E's own define.
NetworkObjectBridge is internal for the same reason, and UnifiedBootstrap raises an #error when
only one of the two defines is set.

With N4E present the two packages share the Unity.Netcode namespace, which breaks three things
outside the unified gates:

- N4E's Netcode facade type shadows the namespace, so 22 XML doc crefs and one nameof that
  qualified with Netcode. stopped resolving.
- N4E declares an INetworkStreamDriverConstructor in the shared root that the enclosing namespace
  finds ahead of NGO's, so the one implementation in the editor tests is fully qualified.
- N4E's source generator errors on an assembly that does not reference N4E, so the editor test
  assembly now references it.

Multiplayer Services 2.3.1 does not compile against N4E 7.0.0 and no fix is published, so it is
dropped from the test project manifests. Validation moves to trunk, the only editor that has
dropped N4E as a core package and can resolve the 7.0.0 request rather than its bundled 6.7.0.

The unified work is preserved and still compiles with both defines set: the N4E 6.7.0 spellings are
updated, and GhostObject.ApplyPostTransformMatrixScale, which N4E removed in its scale rework, is
reimplemented over the new PostTransformMatrix model. The unified CI job sets the defines itself
and is no longer a PR check.

Also disables the serialization tests that fail under CoreCLR so the package is not ejected from
the editor manifest batch.

Parts of this are taken from #4156.
@NoelStephensUnity
NoelStephensUnity requested review from a team and EmandM as code owners September 8, 2026 16:45

@u-pr u-pr Bot 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.

💡 Harness Review

Ship it

The change updates the package dependency surface and isolates the optional unified bridge behind project-level defines; I examined the runtime namespace/API migration, scale bridge call paths, assembly references, manifests, and CI gating.

Reviewed commit c78f679

🤖 Helpful? 👍/👎

Comment thread testproject/ProjectSettings/ProjectSettings.asset
@NoelStephensUnity
NoelStephensUnity enabled auto-merge (squash) September 8, 2026 17:17
Three things the standards job caught, since it opens the project, runs the formatter with --fix and
then fails on any diff at all:

- The fully qualified INetworkStreamDriverConstructor is simplified by the formatter (IDE0001), so
  write it the way the formatter wants. It still resolves to NGO's, since the lookup walks out to
  Unity.Netcode.Transports before reaching the shared root.
- N4E 7.0.0 renamed the serialized GlobalNetCodeConfig field to GlobalNetcodeConfig, which the editor
  rewrites in the test project's settings asset the first time it loads it.
- validation_editors.minimal is back on a released editor. The standards job opens the project with
  it, and trunk rewrites ProjectVersion.txt out from under the cleanliness check. Nothing there needs
  N4E present: a released editor bundles 6.7.0 as a built-in package, so the 7.0.0 request is dropped
  silently and the project builds with no N4E at all - verified on 6000.7.0a6, which resolves and
  compiles clean with N4E absent from packages-lock, PackageCache and ScriptAssemblies alike.
The formatter and the compiler want opposite things here. With N4E present the bare
INetworkStreamDriverConstructor binds to N4E's copy in the shared Unity.Netcode root, which the
enclosing namespace reaches before the using directive, and the class then fails to implement it.
With N4E absent - which is what the standards job's editor resolves - any qualification is redundant
and IDE0001 strips it back off, so the last two attempts each traded one failure for the other.

A file-scope using alias satisfies both. Its target cannot be shortened, since at file scope there is
no enclosing namespace to shorten it against; the use site is a single identifier with no qualified
form; and IDE0005 cannot drop the alias because removing it stops the name resolving at all.
@codecov-github-com

codecov-github-com Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...cts/Runtime/SceneManagement/NetworkSceneManager.cs 0.00% 1 Missing ⚠️
@@                Coverage Diff                @@
##           develop-3.x.x    #4158      +/-   ##
=================================================
+ Coverage          78.19%   78.26%   +0.06%     
=================================================
  Files                153      154       +1     
  Lines              26272    26543     +271     
=================================================
+ Hits               20544    20774     +230     
- Misses              5728     5769      +41     
Flag Coverage Δ
NGOv2_project_testproject_ubuntu_pinnedTrunk 76.70% <0.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../Runtime/Components/AnticipatedNetworkTransform.cs 80.41% <ø> (ø)
...tcode.gameobjects/Runtime/Core/NetworkBehaviour.cs 87.35% <ø> (+1.12%) ⬆️
...netcode.gameobjects/Runtime/Core/NetworkManager.cs 79.97% <ø> (ø)
....netcode.gameobjects/Runtime/Core/NetworkObject.cs 75.31% <ø> (ø)
...time/NetworkVariable/AnticipatedNetworkVariable.cs 76.64% <ø> (ø)
...meobjects/Runtime/Spawning/NetworkPrefabHandler.cs 66.66% <ø> (ø)
...cts/Runtime/SceneManagement/NetworkSceneManager.cs 79.49% <0.00%> (ø)

... and 4 files with indirect coverage changes

Components Coverage Δ
com.unity.netcode.gameobjects 78.26% <0.00%> (+0.06%) ⬆️

ℹ️ Need help interpreting these results?

…r version

The 7.0.0 dependency could not be satisfied anywhere. Every editor available today - 6000.7.0a6 and
current trunk alike - lists com.unity.netcode 6.7.0 as mustBeBundled in its manifest, so UPM drops a
7.0.0 request silently: no assemblies, no packages-lock entry, no warning. upm-pvp then fails hard
with "depends on com.unity.netcode, which is not in the lock file", which is what took out Validate
on all three platforms and Package Test on both editors.

Dependency versions are minimums, so asking for 6.7.0 resolves the bundled package today and picks up
7.0.0 by itself once an editor manifest carries it. The transport bump goes back to 2.6.0: 6.5.0 was
never published (the 6.x line is editor-bundled only, latest published is 2.7.4), so it fails
PVP-160-1, which the Validate job explicitly requires - and N4E asks for 6.5.0 itself, so resolution
is unaffected either way. With the dependency resolving everywhere, nothing needs a trunk editor and
validation_editors goes back to what develop had.

Since either version can now be what resolves, the unified path compiles against both, gated on a
UNIFIED_NETCODE_7_0_0 versionDefine keyed to the resolved package version. The 6.7.0 spellings are
aliased to the 7.0.0 names so the use sites read the same either way, except N4E's Netcode class:
inside namespace Unity.Netcode that name binds to the enclosing namespace before any file-scope alias
is considered, so it is aliased as EntitiesNetcode in both. GhostObjectScaleExtensions is 7.0.0-only,
since 6.7.0 still has the method it stands in for.

That also makes the dependency real rather than dropped, which has consequences worth knowing: N4E's
assemblies now build in every project, its ClientServerBootstrap becomes the Entities bootstrap with a
non-zero AutoConnectPort, and it writes a NetcodeConfig into the project when its settings asset does
not resolve one - which is why the GlobalNetCodeConfig field goes back to the 6.7.0 spelling here.

Verified on 6000.7.0a6 against both versions: shipping (unified off), unified against bundled 6.7.0,
and unified against 7.0.0 all compile with zero errors, and the standards check is clean.
Comment thread com.unity.netcode.gameobjects/Editor/Unity.Netcode.Editor.asmdef
Comment thread com.unity.netcode.gameobjects/CHANGELOG.md Outdated
Comment thread com.unity.netcode.gameobjects/package.json Outdated
Comment thread testproject/Packages/manifest-unified.json
Comment thread testproject/Packages/manifest-unified.json
@u-pr

u-pr Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

⚠️ Some settings were ignored in '.pr_agent.toml (repository root)' repo settings

Check the configuration's TOML syntax, permitted settings, and size limit. See the error below.


Error message:
Ignored prohibited settings: github_app.handle_pr_actions. Permitted settings were applied.

Configuration content:
# This is the configuration for the u-pr bot
# https://github.cds.internal.unity3d.com/unity/u-pr
# For configuration of this file:
# https://developer.portal.internal.unity.com/catalog/default/component/u-pr/docs/configuration/automatic_runs/

[github_app]
handle_pr_actions = ['opened', 'ready_for_review']  # PR events that auto-run pr_commands
pr_commands       = ["/harness-review"]             # what runs on those events
reviewer_commands = ["/harness-review"]             # what runs when @u-pr is added as reviewer

@michalChrobot
michalChrobot merged commit b7327c9 into develop-3.x.x Sep 14, 2026
26 of 29 checks passed
@michalChrobot
michalChrobot deleted the chore/n4e-hard-dependency branch September 14, 2026 15:07
NoelStephensUnity added a commit that referenced this pull request Sep 21, 2026
N4E 7.0.0 renamed NetCodeConfig to NetcodeConfig and moved its types into
Unity.Netcode. Use the 7.0.0 spelling, aliased for 6.7.0 the way the rest of
the unified code already is.

The editor test assembly still declared UNIFIED_NETCODE as a versionDefine
after #4158 made it project-level, so its unified block compiled while the
runtime's did not. It also referenced Unity.NetCode by name alongside the GUID
for the same assembly. Both removed, UNIFIED_NETCODE_7_0_0 added.

The snapshot packet size drops from 15000 to 4096. A snapshot is sent
unreliably, so losing any one of its fragments loses the whole snapshot: 4096
spans 3 datagrams at the 1400 byte MTU where 15000 spanned 11, and still caps
~840 ghosts at the measured 4.87 bytes each. The defaults version is bumped so
a project that already recorded the marker picks the new value up.

Review feedback:
- The experimental opt-in is gone. N4E ships as a normal 3.0.0 release.
- ResolveGlobalConfig's project scan is gone. N4E assigns NetcodeConfig.Global
  from an InitializeOnLoadMethod and delayCall runs after those complete, so
  there is nothing left for a scan to catch.
- The apply log uses the contextual logger at Developer level.
- UnifiedIsConfiguredCorrectly reports which setting is wrong rather than
  discarding the reason it already computed.
NoelStephensUnity added a commit that referenced this pull request Oct 8, 2026
* feat: auto-configure NetcodeConfig for hybrid mode

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.

* style

Some comment clean up.

* fix and test

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

* refactor

Refactoring when the NetcodeConfig default settings are written.
Assuring that the NetcodeConfig tick rate is always the currently set tick rate when starting a session.

* test

Updating to use a more NGO like testing pattern.
Some comment clean up is included.

* update

resolving concern over the .EndVertical();

* style

removing white space.

* chore: n4e 7.0.0 spellings, review feedback and snapshot size

N4E 7.0.0 renamed NetCodeConfig to NetcodeConfig and moved its types into
Unity.Netcode. Use the 7.0.0 spelling, aliased for 6.7.0 the way the rest of
the unified code already is.

The editor test assembly still declared UNIFIED_NETCODE as a versionDefine
after #4158 made it project-level, so its unified block compiled while the
runtime's did not. It also referenced Unity.NetCode by name alongside the GUID
for the same assembly. Both removed, UNIFIED_NETCODE_7_0_0 added.

The snapshot packet size drops from 15000 to 4096. A snapshot is sent
unreliably, so losing any one of its fragments loses the whole snapshot: 4096
spans 3 datagrams at the 1400 byte MTU where 15000 spanned 11, and still caps
~840 ghosts at the measured 4.87 bytes each. The defaults version is bumped so
a project that already recorded the marker picks the new value up.

Review feedback:
- The experimental opt-in is gone. N4E ships as a normal 3.0.0 release.
- ResolveGlobalConfig's project scan is gone. N4E assigns NetcodeConfig.Global
  from an InitializeOnLoadMethod and delayCall runs after those complete, so
  there is nothing left for a scan to catch.
- The apply log uses the contextual logger at Developer level.
- UnifiedIsConfiguredCorrectly reports which setting is wrong rather than
  discarding the reason it already computed.

* feat: hybrid NetcodeConfig values applied at session start

Netcode for GameObjects no longer writes anything into the NetcodeConfig asset. NetworkManager writes the
in-memory global config immediately before the world is created from it, and Netcode for Entities seeds its
world singletons from that.

Two values are driven, both measured rather than assumed:

- The tick rates. NGO's own send queues are flushed by a system in N4E's SimulationSystemGroup, so a
  simulation rate below NetworkConfig.TickRate starves NGO's outbound traffic. N4E defaults to 60 and NGO
  to 30.
- The snapshot packet size, behind the new NetworkConfig.AutoConfigureSnapshotSize. N4E's default of one
  MTU round-robins above roughly 230 GhostObjects: at 512 instances it holds a 13.51Hz effective update
  rate against a 30Hz tick, where 4096 holds 30.00Hz with no saturated snapshots. Below that count the cap
  is never reached, so it costs nothing.

UnifiedBootstrap no longer delegates to base.Initialize. Entities selects the most derived ICustomBootstrap,
so this type is the only one it instantiates under UNIFIED_NETCODE and N4E's own Initialize is never reached
on its own. Calling it only gave N4E a chance to create worlds this bootstrap would then reject, which is why
EnableClientServerBootstrap had to be configured at all. It no longer does.

Removed with it: the editor applier, the Project Settings section, the applied-defaults version marker, and
the interpolation, despawn reservation and transport queue values. Those were tuned against a 2000 instance
stress test and are either inside N4E's own recommended ranges or inert below the snapshot cap.

The FailValidation and ClientDoesNotRequest hybrid test cases are removed pending a separate fix: the server
schedules its disconnect reason into N4E's outgoing RPC buffer and then tears the connection down in the same
call, before RpcSystem transmits it.

* test: move the connection approval latch fix out of this PR

The polled disconnect reason check belongs with the fix for the defect it found, not with the
NetcodeConfig changes. Only the removal of the FailValidation hybrid fixture stays here.

* chore: verbosity pass

Drops a stray blank line that was the only remaining change in NetcodeForGameObjectsProjectSettings, so
that file leaves the diff. Trims the comments that carried mechanism or measurements the PR description
already covers, keeping the reason each value or omission exists.

* chore: clarify the AutoConfigureSnapshotSize tooltip

---------

Co-authored-by: Unity Netcode CI <74025435+netcode-ci-service@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.

2 participants