Hey folks, we’ll be posting regular tech dev log entries while we’re working on landing a few big Netcode features. We’re hoping every ~4 weeks. We’ve been working on these for a while in a separate branch and it’s time to get your feedback and bring them to our main branch one by one.
So yes! Unity is bringing client prediction (previously available only in Netcode for Entities) to GameObject-based projects!
Note: The GameObject layer discussed in this post is still in development and specifics such as names and API implementations may change before the feature is delivered.
Some context
You might have heard about this in our last Unite 2025 presentation. We’re pretty excited to finally be able to tell you what that means and talk about what we’ve been working on.
A bit of context: currently, if you want client prediction in your Unity game, you need to use DOTS and ECS with Netcode for Entities. If you’re used to working with GameObjects, then this is a non-trivial shift in how you create games. Netcode for Entities has a spread of cool features like prediction, relevancy, importance scaling, delta compression, quantization, server rewind (lag compensation), etc. that require using ECS and have been unavailable for use with GameObjects.
A new GameObject layer
To bring those cool Netcode for Entities features to GameObject users, we are creating a new GameObject layer on top of Netcode for Entities, using entities as the foundation with the GameObject layer as a higher-level abstraction. This is a design existing Netcode for Entities users might find familiar, and we’ve had many users successfully doing this on their own already. For example, Survival Kids (our latest internal Unity production) did this: they wrote their own GameObject layer, abstracting Netcode for Entities features, and had their gameplay programmers write GameObject code.
We chose to extend Netcode for Entities in this way so that we could work from a proven, stable foundation. Netcode for Entities now has a few years under its belt of real world productions using it.
This is also placing us in line with “ECS for all” that was talked about at Unite.
The end goal of this new flow is for you to benefit from all the Netcode for Entities features we already have without having to write ECS code.
For those used to Netcode for GameObjects, you will be able to interact with this new layer through similar (but not the same) MonoBehaviours and have similar primitives like NetworkVariables, NetworkBehaviours, and NetworkObjects. But those new primitives will be backed by entities internally, with Netcode for Entities’ features like prediction also available for use with GameObject-based flows.
Implementation details
For those interested in the implementation detail: you would have a client GameObject, mapped to a client Netcode for Entities ghost entity that will sync with a server entity, which is in turn mapped to a server GameObject.
Client GameObject ←→ Client entity ←network→ Server entity ←→ Server GameObject
The GameObject side APIs are basically passthroughs to ECS components.
When using a GameObject-based flow, the underlying entities won’t be visible to you and you won’t need to configure them, similar to how GameObject Physics (backed by PhysX) has its own PhysX world. The way you interact with those is through the Rigidbody instance attached to your GameObject. As a user, you don’t have to know PhysX’s implementation details, you only need to know about Unity’s Rigidbody type. Netcode will have a similar “GhostObject” class, abstracting an entity attached to your GameObject. That entity would live in its own “Netcode World”, with its own object-oriented abstractions.
Preview
Here’s a preview of what the end experience would look like.
Please keep in mind those are just previews, the names will most likely change, but expect something in the general area of the following:
// User gameplay logic is done in GhostBehaviours, similar to NGO's NetworkBehaviour
public partial class MyCharacter : GhostBehaviour
{
public GhostField<int> MyHealth; // Writes in the background to an ECS component. ECS components are invisible.
public void Awake()
{
if (IsServer)
Netcode.Relevancy.SetRelevantFor(this.Ghost, Netcode.Connections[0]); // static APIs are all accessible from the same Netcode static API for discoverability.
MyHealthUpdatedRPC(); // RPC works similarly to NGO
}
public override void PredictedUpdate(float networkDeltaTime)
{
if (input.Value.Jump.IsSet)
m_GravityVelocity.Value = JumpVelocityConfig;
m_GravityVelocity.Value -= 9.8f * networkDeltaTime;
transform.position += (Vector3.up * m_GravityVelocity.Value + horizontalMovement) * networkDeltaTime; // transforms are automatically rolledback and replicated
MyHealth.Value = 100; // value rolled back automatically for prediction
if (input.Value.Shoot.IsSet && Netcode.NetworkTime.IsFirstTimePredicting)
GameObject.Instantiate(someRocketPrefab); // Predicted spawn.
// GameObject.Instantiate() "just works" for a server side spawn as well
}
[Rpc]
public void MyHealthUpdatedRPC()
{
Debug.Log("health!!");
}
}
We’ve left out a few things on purpose, it’d add too much noise to an already big post, but don’t hesitate to ask about those! Things like input gathering, accessing component values directly, server rewind, prediction switching, and a whole bunch of other implementations we have in store will have their dedicated blog post later.
What’s next
These Netcode features will be delivered in upcoming Netcode for Entities releases over the upcoming quarters. Keep your eyes on our changelog and on upcoming Discussions posts.
Next post, we’ll talk about the first feature that landed already in the Netcode for Entities package (version 1.9.0) to support this: single world host. With this, you’re able to create a World that functions as both client and server.
In another post, we’ll talk about the GameObject to Entity mapping we’ve landed hidden behind a define (version 1.11.0).
We have GhostFields up for review and prediction and input gathering are next.
We want your thoughts! One of the main reasons we’re doing this series of posts is to chat about all of this with you guys. We’re pretty excited about this on the netcode team, this has been brewing for a long time and so if you have any questions, comments or suggestions, please let us know!