Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Net: Replication #30

Open
jacopograndi opened this issue May 4, 2024 · 0 comments
Open

Net: Replication #30

jacopograndi opened this issue May 4, 2024 · 0 comments

Comments

@jacopograndi
Copy link
Owner

Tracking issue for net refactor/replication.

Flows

The idea is to not match on NetworkMode but to have the three flows distinct.

Here is what each flow should do:

Client

Opens a connection to the server.
Sends input buffer.
Receives the replica of
[x] Universe's chunks
[x] Player
[x] position and rotation
[x] state (for now only hand, later also armor, effects, invetory, ...)
[ ] mobs
[ ] items
The player state, mobs and items are replicated by src.
The replica is a client representation of what exists on the server.

Server

Receives clients' inputs.
Sends replicas of chunks, players, mobs and items.

Client with a Server

Is a server with a player.
We can choose between:

  • Opening a client that connects to the server and use all the same infrastructure keeping the 1 connection = 1 player entity invariant
  • Changing Lobby to accept also a local player and changing server and client flows to account for that

Replication

How the server send the world to the clients and how the client interpret the server's world.
The idea is that the game is played on the server, the client are just "viewports" into the server's world.
Therefore, the client has to keep a cache the server world.
It is known that caching is impossible.

Lobby

Map from client connectionid to player's entity.
Split screen not supported in the short term, it would entail having multiple player entities for the same client connectionid.
Both the client and the server have this map.
On client connection the server generates the player and notifies the other clients that someone has connected.
The server also notifies disconnections.
The client constructs a local representation of that new player and keeps it in sync with the one in the server.

Universe's Chunks

The player positions have to be known.
When a player is spawned, the nearby chunks are requested. The server generates or loads the requested chunks and sends them to the player.
When a chunk is changed it is sent to all players. When a player moves it causes new chunks to be generated/loaded, which are marked as dirty by default and sent to all players.
This is clearly not optimized.

[ ] The client only cares about the visible chunks, so every chunk out of view distance has to be unloaded. We could unload them based on stale time or by unloading the last one when a fixed size buffer is full. The assumption is that the client asks for chunks, the server does not track the client buffer.
[ ] Send only the diff if the client already has a previous version of the chunk. To create the diff the server has to know both versions of the chunk (the updated one and the client one)

Player's components

The position and rotation of the player is replicated by default by net. Every other component has to be replicated by src. We could add an abstraction like #[derive(ReplicatePlayer)] to generate the replication code.

Mobs and items

Other entities are not replicated by now.
We could do it all in src or consider adding an abstraction like [derive(Replicate)] to generate the replication code for generic entities and components. This is something that other networking crates do. I chose renet because it allows to write the custom replication that is needed for Universe's chunks.

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

No branches or pull requests

1 participant