Hey chasse!
Yes, you’re right, our implementation is very “opinionated” about how serialization is done.
I.e. Our architecture is fairly rigid in terms of GhostField snapshot replication, where the flow is:
Gather Ghost Chunks > Sort them > Iterate over entities in chunks until snapshot is full > Serialize all GhostFields using the strategy defined in the template.
I’d recommend reading this page: https://docs.unity3d.com/Packages/com.unity.netcode@1.0/manual/ghost-types-templates.html
As well as these three serialization pages: https://docs.unity3d.com/Packages/com.unity.netcode@1.0/manual/synchronization.html
Therefore, changing how an individual ValueType is replicated can be done via defining user templates, but we don’t provide much more snapshot serialization flexibility than that. However, that does not stop you from fetching the drivers and pipeline stages yourself, and building + sending packets manually. At that point, our Netcode for Entities package would be more of a bootstrapping tool for your own netcode implementation.
Sending entities at a lower tickrate via “Importance Scaling” (where our default implementation is Distance-based Importance Downscaling) is supported, but we use the approach of:
- Define how big your packets should be, and at what frequently each packet is sent.
- Netcode will attempt to fill the packet, using a chunk importance heuristic to sort ghost chunks.
Thus, if you’re used to setting a specific tickrate for a specfic ghost under a specific importance scaling, our approach is the inverse. We’ll send as much as we can until the user-defined packet size is full.
You can modify / replace / toggle our custom distance-based downscaling if you want finer control.
This would require fairly significant packet modification, if what you want cannot be achieved via the (aforementioned) custom serialization template.
Similarly, this is something we do automatically for you. You can see our delta-compression approaches in said templates. We have a few ideas to further improve this, but nothing we can talk about today.
We handle this simply by sending pertinent snapshots until the client has received all “relevant” ghosts. I.e. Eventual consistency handles this. You can do things like:
- Define a subset of server ghosts which should be sent to this client (Relevancy). Example: Relevancy radius around the player of 500m.
- Increase the importance of ghost chunks which the client has never received.
- Query the percentage of ghosts that the client has received, of the aforementioned “relevancy set”.
Because we have state synchronization via snapshots, writing bespoke logic for new joiners is unnecessary. We would likely provide the sort of thing you provide for a GGPO architecture, however. Best example that comes to mind is Factorio.
The “multiple servers” architecture is not supported in Netcode for Entities, but it is on our radar in the long-term. Our current focus is optimizing single-server scalability, especially as “Vertical Scaling” can often solve these “persistent MMO” scale player counts (e.g. 500+ players in a single server).
In my personal view (i.e. not speaking as a Unity employee here), “multiple server” architectures:
- Add a huge amount of complexity (and latency considerations), which classes them automatically as “extremely ambitious”. DOTS provides a lot of the necessary flexibility for this kind of architecture, but it’s a huge undertaking.
- Are still poorly suited to handle a large quantity of players converging on a single area, resulting in unplayable levels of network degradation and rubber banding. So, at that point, why not just use tried and true region/realm instancing?
- Are prohibitively expensive to operate, except for large AAA teams.
- Don’t yet have a concrete use-case. I.e. I think the idea of a 1k player server sounds better in our heads than in practice, especially if the goal is meaningful interaction. I.e. The best multiplayer experiences I’ve ever had are when I know and understand the people around me. E.g. A small, intimate concert venue vs an arena. If you want an arena atmosphere in a video game, the “hard problem” isn’t the netcode IMHO, it’s the audio and voice chat.
LMK if this was helpful, cheers.