RomanZhu / Entitas-Sync-Framework

Networking framework for Entitas ECS. Targeted at turnbased games or other slow-paced genres.
MIT License
162 stars 20 forks source link
autosync c-sharp client-server codegenerator csharp ecs enet entitas entitas-csharp entity-component-system game game-development gamedev generator multiplayer networking sync unity

Entitas-Sync-Framework

Features

Overview

The framework is targeted at slow-paced genres. Gameplay should be delay-tolerant, as clients use state buffering to smoothly display ECS world changes. All packets are sent reliably using a single channel. It means you should not set tickrate too high. Otherwise single dropped packet will block all other already received packets from being executed and in extreme cases state queue will fail to smooth those pauses, producing visible stutter.

Overview Creating networking command Creating networking component

Server

On the server each client has entity with a Connection, ConnectionPeer and ClientDataBuffer components. When you tell the server to enqueue command for a particular client - it is written into BitBuffer inside ClientDataBuffer component.

Each tick server will execute all received Commands, then it will execute all gameplay systems. After that, all changes to the ECS world are captured by reactive systems and written to the 4 bitbuffers which are common for all clients. Only entities with Sync component attached are handled by automatic synchronization

The last system for each client combines 1 personal and 4 common BitBuffers into a single byte array, copies data to native memory and publishes a request for a network thread to send data from that native memory to peer from ConnectionPeer component. After that, all BitBuffers are cleared.

All gameplay logic should be located inside ServerFeature.

Client

The client uses state queue to smooth out ping jitter. The only way for the client to send something to the server is using Commands. When you tell the client to enqueue command - it is written into BitBuffer inside ClientNetworkSystem.

Each tick client will execute all received Commands, then it will execute all gameplay systems. After that, it will send all Commands which were enqueued.

The client knows the whole world all the time. In the first packet he receives all entities with Sync component and all their networking components. After that, he will only receive changes which happened in the world.

To react to changes in ECS world you can add systems into ClientFeature. You should not modify networking components in those systems or destroy/create entities with Sync attribute.

Commands

Both client and server can enqueue commands. You create a struct, set data into fields and call _server.Enqueue*(command) or _client.Enqueue*(command). Then that command will be received on connected peer/peers.

To create a new command:

Supported attributes

Entity Synchronization

All entities marked with Sync component will be sent to clients. Only networking components on those entities will be sent to the clients. Everything is handled automatically. You should not add/remove WasSync component from entities, as it will break logic and desync will happen.

Make sure to use only supported field types.

To create new networking component:

Special components

Field types supported

Dependencies