📓

ServerConnection

public class ServerConnection : GameConnection
{
    //CHANGE THIS TO FALSE IF YOU DEDICATED SERVER
    public static bool serverIsAlsoPlayer = false;

    public List<PlayerConnection> playerConnections = new List<PlayerConnection>();
    public int maxConnections;

    int mostRecentSentSnapshotGameTick = 0;

    EventBasedNatPunchListener natPunchListener = new EventBasedNatPunchListener();

    //whether it should be listed on the master server or not
    public bool publicServer = false;
    public float reconnectTimer = 0;
    public float reconnectTimerMax = 10;//try reconnect to master server every 10 seconds

    //so we can relay game data back to the master server
    public MasterServerClientConnection msClient;

    public string gameName;
    //used basically as a token to update the games data on the master server
    public int gameID;
    public int serverGamePassword;

    public int timerBetweenDataUpdates = 0, timerBetweenDataUpdatesMax = 60;

    public bool needToStartNewGame = false;
    public int newGameStartingTimer = 0, newGameStartingTimerMax = 180;
//...

This class helps setup a server for clients to connect to and extends the GameConnection class. Servers can also be players(peer hosted) or if not, then they can just run the instance(dedicated server). There are quite a few attributes so I’ll briefly run down what they are for.

When clients join, their details are stored in a list of PlayerConnections. As this class is in charge of sending and receiving data from clients, then its helpful to know the last game snapshot sent by gametick so if we get a newer one we can send it right away.

The natPunchListener helps clients and servers reach each other without the need for port forwarding, which is a process a Master Server must help aid in.

The next few attributes help us work with the Master Server, publicServer is a bool letting the Master Server (if we’re connected to one) know whether we should list this server as a joinable game for clients to join if they too also join that Master Server. The reconnect timers are for if we lose connection with Master Server and after how much time until we try to reconnect. msClient is a MasterServerClientConnection, so we can be connected to the Master Server and can relay information back and fourth e.g how many players are in a match or more.

gameName is the name of this Server and is useful for identifying it when listed on the Master Server. The Master Server gives the Server a gameID and serverGamePassword to help uniquely identify the game in the list. serverGamePassword is more a token and not one set by the Server and is used to prevent people from guessing how to join your servers in dodgey ways.

timerBetweenDataUpdates is how many game frames to run before having to send out non crucial data to all clients. In the example this data is the score board, player names and skins, so that is being sent every 60 frames. To make it too often will just slow things down as these packets will be competing with the snap shot packets sent which help update your characters and things in the game world.

needToStartNewGame and newGameStartingTimer are used when you want to kick off a new round. In the example these attributes come in when a round end, it shows the winners, does the count down and then moves onto the next map/scene/event.

Methods

public ServerConnection(int port, int maxConnections = 30 )

A constructor that takes what port to start listening on and how many clients are allowed to join. It then proceeds to start listening and sets up how it will respond to various networked events

public override void Update()

A lot of small things, it polls for various incoming network related events, sends snapshots/player info/which scene to migrate to and also maintain the connection to the Master Server.

public void UpdateGamePlayerCountOnMasterServer()

Let Master Server know how many players are in the current game

public void SendPlayerData()

Sends data that is allowed to be a little bit spaced out. Currently sending player names, skins, scores etc. Add other data as you see fit.

public void SendMostRecentSnapShot()

If there has been a new SnapShot saved on the server, then send it to all clients so they can update their game world simulations

public void NatPunchHostGame(IPEndPoint masterserverIP)

Try to initiate NAT Hole Punch procedure to help clients join

public void MigrateAllPlayersToCurrentScene()

Tell all clients which Unity Scene (map/level etc) to change to

public void SendWinnerInformation()

Tell players who the winner was 😀

public void ChangeScene()

Logic to decide which Scene to load up. This will vary from game to game so it is imperative that you update this with your own logic in someway

public void ChangeScene(string scene)

If you don’t like the approach of the above ChangeScene, then this one might be easier to work with. Pass it the name of the Unity Scene you want to jump into and it will

public void UpdateNewGameSituation()

What happens in your game when the next round or level or start of map is about to start? That logic goes here

public override void CleanUpBeforeSceneChange()

Currently just sets mostRecentSentSnapshotGameTick to zero as we’ll start the snap shot game tick count at zero again in the new scene.