Networking Multiplayer Game
Description
A Networked Multiplayer project for Networks subject of the Bachelor's Degree in Game Development at CITM, UPC.
BattleShip Royale is an amazing multiplayer game where you pilot a spaceship and have to defeat all the foes you will encounter in order to keep alive as long as possible.
The networked game is featured with a World State Replication so that clients receive the state of the world, Redundant sending of input packets to improve on packet loss ratios, Delivery manager that notifies about successful deliveries, and about delivery failures on timeout.
Besides that, the Network System is implemented with a Client side prediction with server reconciliation, to avoid laggy user input and Entity interpolation, to make network objects update smoothly on screen and many other interesting stuff.
Gameplay Captures
Technical Features
Game accepts client connections
The game accepts clients and assignes them an ID that is handled by the server then assignes them the corresponding data.
Game handles join/leave events
Clients can disconnect and connect at freewill. At the beginning we had an issue related with replication manager since the clients don't replicate properly in the create action when they were disconnected and reconnected again. It was solved declaring the manager at OnStart() function of the client Network module.
World state replication system
the world state replication system uses a map which stores a network id with his proper action (Create, Update, Input , Destroy).
The system works well and replicates the current state of the server to its connected clients but i realized there is an issue when some values are modified like the life or kills in Behaviour code and they have to be replicated to the clients. Sometimes it happens that replication of that changed variables is updated correctly to all the clients but often is only well replicated within the client application.
This issue is fixed sending new packet type with that changed value from server to appropriate client. It works perfectly but i think is not a good practise because of packet dropping.
Redundant sending of input packets
As we deal with techniques to compensate for lag, and bandwidth usage is a real concern, we send input notification data from server with every replication packet. That means a slower response to have all the clients updated but we optimize it in terms of bandwidth streaming.
My first approach was sending the next expected input sequence after each replication packet so each client had to read all the previous replication data to reach the redudancy input so i improved the replication system creating a new action called input as a notification that stores that next sequence input number. This decrease a litle bit tha latency generated by the process of read unnecessary data and update the inputdatafront in order to have space for more input controllers.
Delivery Manager
Delivery manager takes care of all packet received from server to all connected clients. It just send a sequence number that is compared by client delivery manager sequence number so if the values are not the same the client doesn't process the read of that packet.
That happens in every replication interval within a replication packet with a heap allocated delegate that has a replication server reference to resend the current state of the server according to the missed actions if any packet was not received to the clients. With packet drop checkbox activated, it's perceived a loss of data but delegate works well in order to resend the proper state when there is a failure.
Client-side prediction with server reconciliation
The client-side prediction is performed after the client recieves the replication packet with his last processed input updated from the server state. After received it, we iterate the input array in case of inputdataback was incremented, so there are inputs which need to be re-applied since they are not yet processed by the server in order to eliminate visible desynchronization issue.
Entity Interpolation
The interpolation works well and there is no kind of flickering or teleportation of positions and angle. I don't know if I'm crazy but it gives me the feeling that it is not as immediate as it looks on the server, maybe it is because all the input is processed on the server and there is a small latency since we first send the inputs from the client, the server runs them and then send the replication to update the client. Also it can be by the ratio/percentage that is calculated in the local interpolation.
Contributions
- Game accepts client connections
- Game handles join/leave events
- World state replication system
- Redundant sending of input packets
- Delivery Manager
- Client-side prediction with server reconciliation
- Entity Interpolation