Netcode for Entities 1.9.0 released

:package: Netcode for Entities 1.9.0 is now live! :package:

Hey everyone! We’re back with another batch of updates for Netcode for Entities. We are still experimenting on how to structure those messages because because their goal is:

  • Shortly explain what is the most interesting in this package update and on what you should pay attention to
  • Gather feedback and your opinions on the changes and current package state. Even though we may not be always able to quickly address those it’s still super valuable to us and helps directing package development

NetcodeSamples update

We updated NetcodeSamples (REPO LINK) to the latest version (which for example includes a Host Migration sample) and we are planning to update them consistently with each Netcode package release.
We know it wasn’t updated for some time and those samples are not perfect so we want to use this opportunity to ask you for your pain points when using them for learning purposes, namely

  1. Is there any functionality/sample that you would like us to implement in the samples?
  2. Are there sample issues that you would like us to prioritize?

Key Updates in This Release

The most important updates happened around Despawning

  • Ghost Despawn Handling (Breaking Change): We changed the way how despawn messages are sent which improves throughput and reduces bandwidth. The minimum snapshot packet size is now 100 bytes.
  • Snapshot Performance: Delta-compression for despawns is improved, and bandwidth use for ghost data is further optimized.
  • API Changes:
    • The PrefabDebugName.Name field is now fully deprecated, increasing per-chunk entity capacity.
    • New setting: GhostSendSystemData.PercentReservedForDespawnMessages controls how much of the snapshot is reserved for despawns (defaults to 33%).
  • Reliability Fixes: Resolved memory leaks, improved host migration data reliability, and fixed rare ghost despawn and snapshot errors.
  • Developer Experience: We added clickable link that help to resolve disable Batched Tick related warnings and new buttons for thin client management in PlayMode Tools.

We hope these changes make your multiplayer projects more efficient and reliable. Let us know if you have feedback or questions!

Happy Netcoding! :rocket:


Fixed
  • The analyzer to warn about using the Simulate component while ignoring enabled state has been fixed to correctly warn when using SystemAPI.Query().WithAll()` and similar calls.
  • Issue where the ghost data writes could fail while gathering the host migration data (now it will always grow correctly).
  • Allocator.Persistent memory leaks caused by ImportanceDrawerSystem.cs.
  • ClampPartialTicksThreshold now displays correctly in the NetCodeConfig.
  • Behaviour Breaking Change: Ghost despawn messages are now added to the snapshot in a round-robin priority order, where up to 2 despawn messages can be “in-flight” for a single ghost at once. Old behaviour was to send up to 100 ghostIds per snapshot, where each despawn was sent up to 5 times in a row before the next 100 could be added. Delta-compression has also been significantly improved. This new approach significantly improves despawn throughput, while also significantly reducing despawn bandwidth consumption.
  • Behaviour Breaking Change: The minimum DefaultSnapshotPacketSize is now 100 bytes, up from 1 byte.
  • Incorrectness in ghost despawn message handling, leading to missed despawns, and rare snapshot errors.
  • Hardened snapshot receive logic to expect exact dataStream.GetBitsRead() correctness, and used it to fix a (harmless) incorrectness when a chunk attempts to write its first ghost into the snapshot, but fails due to exceeding the stream capacity.
  • Potential dependency error with importance visualization.
  • Broken table on PlayMode Tool documentation page.
Changed
  • Marginally reduced the bandwidth consumption of the GID and SpawnTick values of ghosts within snapshots, on average.
  • API Breaking Change: The PrefabDebugName.Name has now been fully deprecated, reducing archetype chunk sizes, increasing per-chunk entity capacity for ghost instances.
  • Best practice on GhostOwnerIsLocal usage. Server-only world behaviour is now undefined and might be changed in future versions. GhostOwnerIsLocal should only be used in client logic. To find owned ghosts in prediction logic, please make sure to strip your input components so they only appear on predicted ghosts.
  • Best practice on NetcodeServerRateManage.WillUpdate. Should now use NetworkTime.NumPredictedTicksExpected server side.
  • Significant internal refactoring for upcoming Single World Host feature.
  • The importance visualizer setting name for “Per Entity Spatial Chunk Structure” has been changed to “Per Chunk”. This does not change the behavior, the name is only changed to more accurately reflect the underlying data that is being visualized.
  • Made NetworkDriverStore methods readonly, where possible.
Added
  • GenerateTestsForBurstCompatibility test coverage - and ToString overloads - of ToFixedString methods.
  • Behaviour Breaking Change: GhostSendSystemData.PercentReservedForDespawnMessages denoting the percentage of the snapshot capacity reserved for ghost despawn messages, with a default value of 33% (i.e. one third of the snapshot). This replaces the internal const of 100 ghosts.
  • A clickable link directing users where to disable Batched Tick Warnings.
  • New + and - buttons for automatic thin client creation in the PlayMode Tools window.
  • Bounds checks to NetworkDriverStore and NetworkDriverStore.Concurrent driver accessors.
6 Likes

With regards to additional Netcode Samples, could you provide an example on how to best go about parenting a Ghost entity to another Ghost entity?

Here is my use case:

  1. Ghost entity Item is on the ground and uses Unity Physics so it can be moved around naturally.
  2. Ghost entity Player picks up Item. Item should now be parented to Player and all state should be perfectly preserved.
  3. Item should be able to be dropped and picked up, ItemState should be replicated to the client via GhostComponent so the Item’s abilities can do things like trigger visual effects and change UI on the Client.

Currently there is only limited information via difficult to find staff and ex-staff forum responses on workarounds to get ghost parenting working as intended even though it is a critical system in many games, a detailed sample would be very helpful please!

1 Like

Hey, thanks a lot for the feedback :grin:, I will raise this with the team and let’s see what we can do

1 Like

Does netcode for entity support nat punch through so that players can run their own games as servers?
Of course I have a matchmaking server so that both players know each other’s IP before connecting, and they will try to send UDP packets to each other.

We don’t have NAT punchthrough support when using Unity Transport unfortunately. I would recommend using Unity Relay instead, as that solves the same problem in a different way. If you really don’t want to use relay, others have had success with using Steam’s transport instead with their NAT punchthrough, but that is significantly more work and now you’re bound to the Steam APIs as well.

1 Like

The problem is that it seems that netcode for entity requires Unity Transport, unlike netcode for gameobject. Is there a reason for that?

Not a compelling reason, no; it was a timing quirk with the MLAPI acquisition, as well as a need for Unity Transport to support DOTS Job Scheduling. Though, as Jonathan mentions, both abstractions allow concrete implementations of other transports to be plugged in.

1 Like