I’m trying to add server-authoritative multiplayer to a small game I made with DOTS, and I have some questions…
I’m using:
- Entities 1.0.0-exp.12
- Netcode for Entities 1.0.0-exp.13
- Unity Transport 2.0.0-exp.6
- Unity 2022.2.1
(I want to keep updating to the latest versions for the foreseeable future.)
The game has a large number of Agents that follow the closest Player.
Since ECS-based Navigation is far away in the roadmap, and the game’s level is a simple square, I divided it into a grid and implemented a basic A* algorithm.
Each Agent has a WaypointData
buffer:
[InternalBufferCapacity(20)]
public struct WaypointData : IBufferElementData
{
public int2 Position;
}
The AStarSystem
populates these buffers with the correct path toward each Agent’s target, and the AgentMovementSystem
moves the agents along their paths.
For the multiplayer version, I want:
-
The
AStarSystem
to run only in the Server. -
So I will add
[WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)]
. -
The
AgentMovementSystem
runs in both the client and the server, because movement is client-predicted.
Q1: Is the attribute [UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
the correct one to add to AgentMovementSystem
?
Q2: Should I add .WithAll<Simulate>()
to AgentMovementSystem
’s entity query? What does this Simulate
tag mean exactly?
Q3: Given the following requirements, how do I set up the ghost/serialization for the Agents (and specifically for the WaypointData
buffer)?
- The Agents are NPCs, so they are NOT owned by any Player.
- The
WaypointData
buffer will be written by the server and read by the clients. - The clients should not try to predict or interpolate the
WaypointData
buffer. - I only want to sync the
WaypointData
buffer when there are changes, which will NOT happen many times per second. - The
WaypointData
buffer will have changes when the Agent’s target moves from one cell to another. If there are many Agents following that same target, they will all try to sync at the same time.
[GhostComponent]
[InternalBufferCapacity(20)]
public struct WaypointData : IBufferElementData
{
[GhostField] public int2 Position;
}
So I found this: Synchronize IBufferElementData or any other array of data
Q4: Do you recommend to not have the WaypointData
buffer be a GhostComponent
, and simply send a message from the server to all clients containing all the changed buffers to all clients?
Q5: Am I right to assume that, for this purpose, I can identify each Agent by their Ghost ID?
Q6: Can you give me an example of how to send a message from the server to all clients through TCP communication from within an ECS system?
Q7: If I don’t add GhostComponent
to an IBufferElementData
component, it is NOT synchronized by default, right?
Thank you for your time!