For my Software Development 7 course our goal was to build a Network system that can support a game. In addition to supporting a TCP connection between two programs, the Network System supports UDP via Sessions. This includes Unreliable, Reliable, and Reliable In-Order messages.
Unreliable messages are “fire and forget”, whereas Reliable messages are messages that we ensure have arrived via Acknowledgements attached to the header of all packets. Reliable In Order enforces messages tagged as such are processed in the order that they were sent.
Other features of the Network system include a synced Net Clock and a debug system that shows all connections attached to a session, along with their status, RTT, and clock time.
The game created from this system is a simple game called Coin Grabber, where any number of players compete to grab as many coins as possible. To support this, a NetObject system was built, where the host can make an object, which sends a message to all connected clients, who then create their own local copy of the NetObject. Each NetObject is assigned an ID, so when a NetObjectUpdate is received by a client they look for the object associated with the ID and call its relevant functions.
NetObjects each have a NetObjectType, which is a singleton created for each kind of object (Coin, EnemyKnight, etc.). These singletons have functions that are called on Create, HostSend, HostRecieve, ClientSend, and ClientReceive. By utilizing this system, NetObjects can be used for either a host authoritative or client authoritative game, or any mix in between. NetObjects can be owned by either the client or the host since each NetObject has a OwningPlayerIndex and a OwningConnectionIndex.
On top of these features, a basic form of Client Predicition is implemented. Since players are sending their current position to the host, who then notifies all players of this new position, clients receiving a position update on an object perform a lerp, setting the position of non-owned objects to 30% of the new position and 70% of the old position. This allows the object to glide into the correct location, rather than snapping sporadically to the position.