Making a Master-Server / Matchmaking system

Greetings !

A few friends from college and I are currently working on a game that involves matchmaking, meaning you enter the game, then you connect to some kind of “Master server” who takes care of pairing you with another player and starting a match of the game you against him. At least that is what we are going for, a very simple version without any kind of player rating or anything. And I am the one that has to work on that. I decided I’d go with the low level API, for learning reasons (I dislike using High level stuff) and also for practical reasons : our game will not use GameObjects or even Transforms for most of the entities in the game which means most of the HLAPI is useless anyway.

I need help and advice on the approach I took which, I guess, is a common approach : I have a Master-Server monobehaviour holding a list of “ClientInfo” objects (ID of the Connection, name of the client, and weither than client is currently in a match or not).

The Master Server “gains” new Client Info upon a client connecting to it and loses client info upon the said client disconnecting.

On every frame it tries to pair off clients that are not currently in a match. For optimisation purpose it only looks at clients that just joined the server, it doesn’t update the list every frame with all the client infos that claim they are not in a match.

Upon successfully finding two clients to pair off, it creates an instance of the “Match” class, which is where all in-game stuff happens (entity management, communication with the client on gameplay…) and gives it the client info objects corresponding to each player, that way it knows about the name of each player and what connection ID to use for message transportation.

Matches are updated by the Master Server on its Update() call and are passed the delta-time. Matches also have their own “Speed” attribute that multiplies the deltaTime passed to them, but that’s purely gameplay stuff (figured I could use it for end-game slow-motion or whatever).

When a match ends, the clients are sent a message telling them the match’s outcome, and a few seconds after receiving it, they disconnect from the Master-Server and go back to the main menu.

For message transportation, I have 3 classes : NetworkMessage, NetworkMessageSender and NetworkListener. NetworkMessage is a simple data structure that contains a message name (string), message content (object), and the ConnectionID from which it was sent (useful to determine who / what a reaction to a message should affect, for example, if the Match receives a “Player wants to move forward” message, it can check if it is meant for him by checking the source Connection ID and the Connection IDs of each player participating in the match.

NetworkListener is a static class where all message receiving is handled for servers and clients alike : when a message is received it is put inside a list of “ReceivedMessages”. Then anyone can use the “NetworkListener.CheckMessage(“MessageName”, out NetworkMessage something)”. It works just like the Raycast : if a message of said name is inside the “ReceivedMessages” list, then the method returns true and puts the message in the something variable, then it removes itself from the ReceivedMessages list.

This is where my doubts are the greatest : If a message gets “Checked”, it gets removed from the list, meaning whoever reads a message first and tries to make sense of it will be the only one that ever gets to read it, which might prove problematic. I’ve also thought about cleaning the entire list of messages on each frame but then isn’t this going to cause problems too ? I’m not sure frankly.

As for NetworkMessageSender, it is a class used to “wrap” messages into something that is then sent into the message’s connection ID. So basically in order to send a message to Connection ID X :

  • You create a NetworkMessage object, give it a name and a content, as well as X for Connection ID
  • You create a NetworkMessageSender object, give it your HostID and ChannelID, aswell as the NetworkMessage
  • On construction the NetworkMessageSender sends itself through the network on Connection ID X.

Not sure it is the best system, but so far it works, kinda :smile:

I think that’s it. I know there are no specific questions but if you guys are interested in helping me make a better system using the LLAPI then I’d appreciate some criticism :wink:

Thanks !

UP ! I finally have a kind of straight forward problem. Basically my client socket connects to something (At least I think so because the NetworkTransport.Connect() call does not put any error in the out variable) but I can’t find out what, as neither the client nor the server report a Connection event during their NetworkTransport.Receive calls. Of course this blocks everything else from working because it seems the connection cannot be made for some reason. For testing purposes I’m using the 127.0.01 IP (the client and the server both are on the same machine), so that might be the culprit but I can’t be sure because previous tests in these conditions did not create any problem.

you should take a look on Master Server example. https://forum.unity3d.com/threads/master-server-sample-project.331979/

Thanks a lot, but this example is made with HLAPI, not LLAPI, so it doesn’t really help solve my problem. But I could use it down the road so thanks again.

EDIT : Strangely enough, the problem just stopped occuring and I have no idea why. At least it works now - partly, for I have yet another problem. It seems you cannot properly send a message right after you connected to another socket, at least not on the same frame and not on the next few frames. I’m kind of new to networking so there may be a few concepts I don’t completly grasp yet - do I need to keep sending a message until it actually goes through ? I thought sending it once would do the trick.

At least it have a NetworkMessage system, so it could help you to understand how to properly send a NetworkMessage.