Creating a Game Frontend: Setting up Protos and Services in C#
By: Jon Foust
Tags: C Sharp Programming, Services, Grpc, Gaming

This post is part of a series of posts on Open Match. If you want to follow from the beginning start with the Overview and then read the Deep Dive

Open Match enables you to customize and design a matchmaker, but there is functionality that it does not offer. For example, Open Match is not responsible for player data nor other game components such as inventory, friends lists, or leaderboards. This creates the need for a service to interact with Open Match that can access these components. If you haven’t figured it out from the title of this blog post, I’m talking about a Game Frontend.

A Game Frontend serves two essential purposes when designing your matchmaker. The first is handling what Open Match does not: interactions with other game components. The other is providing a layer between game clients and Open Match. You do not want game clients to interact with Open Match directly, because it would allow users to potentially submit a request with unvalidated information. Imagine a player who has a skill rating of 1000 submitting a request with a skill rating of 3500; not fun. The Game Frontend enables you to submit matchmaking requests with authenticated user data from your game components. To connect with players online, we must first create a ticket to represent a matchmaking request.

Setup

To create this Game Frontend sample, we will use the following resources:

Visual Studio 2017 Community: C# console app

Open Match Messages proto file

gRPC

Create Two C# Console Applications

To simulate the Game Frontend and client, we will create two C# console applications. Name them “Game Client” and “Game Frontend.” They will represent our client and server, respectively. If you’re unfamiliar with creating a C# application in Visual Studio, check out Tutorial: Create a simple C# console app in Visual Studio..

Install Necessary Nuget Packages

Once you have made the two console applications, we should install the gRPC Nuget packages. The packages to install are:

gRPC by The gRPC Authors

gRPC.Tools by The gRPC Authors

Google.Protobuf by Google Inc.

Setup a Project for Generating Protos

The next step is to create a folder in your solution in Visual Studio to hold the proto files. Right-click the solution, add a “solution folder”, and name it protos.

These next steps can be a bit tedious if you’ve never edited a .csproj file. Here is what you need to do:

Right-click the client project and select Unload Project. Right-click the client project and select “edit client.csproj”. Scroll down and find the item group that contains the “Program.cs” within it. Add the following snippet right above the item group. Save and close the client.csproj file Repeat steps 1–5 for the server.csproj file. Right-click each of the projects and select Reload Project. Right-click each of the projects and add a folder to each named models. Right-click both projects and build them (you will get a couple of errors for a missing file, but we will resolve them).

To recap, we have defined for the project both the proto file locations and where the generated .cs will be saved.

Now we are all set up to create a game frontend. If you haven’t cloned Open Match, please do. Locate messages.proto (open-match/api/messages.proto), which we will be using to create a ticket (in a later blog post), and copy it into the protos directory you’ve made. An additional dependency is required, located in third-party/google/rpc/status.proto, so be sure to place that file in the protos directory as well.

Great! Now that you’ve finished the initial setup, let’s implement the proto file we need to define our messages and services for the game frontend.

Implementing the FindMatch RPC service

To kick things off, create gamefrontend.proto in the protos folder, which will be used to implement the gRPC service you’ll need to communicate with Open Match and the game client. Here is a snippet of code to paste in the file:

We import the messages.proto to get some of the essential definitions needed to submit requests to Open Match. The FindMatch service handles a request containing a player id (and any other relevant info required to matchmake) and returns an Assignment, the game server address the client will use to connect for the game.

Save the file and build the client and server to generate the classes (gamefrontendgrpc.cs and gamefrontend.cs) needed to implement our services.

To begin implementation, right-click, and add a class to the server project named gamefrontendservice.cs. Copy the code snippet below:

In the snippet above, we add a reference to our OpenMatch and Gamefrontend namespaces. This allows us to implement our FindMatch service using message definitions. We accomplish the following in this code:

Define our FindMatch Service functionality. Accept the ID of the game client requesting a match (for player info lookup). Generate a dummy IP address that the game client will connect to. Create an Assignment message containing the dummy IP address. Return the Assignment as a response.

Now that we’ve implemented the service let’s finalize our Game Frontend server-side code.

Wrapping up the Game Frontend (Server-side)

Begin by opening Program.cs for the Game Frontend. In this application, we want to create our server and bind our FindMatch service. We also define the ports our server will run on (localhost on port 50051 for now). Here is a snippet that accomplishes these goals:

Now that we’ve completed our server-side code, let’s write our client-side code to connect and submit a match request.

Game Client (client-side)

This client code is used to implement the game clients that will be submitting requests to the Game Frontend service. Open Program.cs for the Game Client application and paste the following snippet:

We accomplish the following in this snippet:

Establish a connection with the Game Frontend. Generate a player id for player data lookup. Submit a FindMatch request to the Game Frontend. Process the response and output the Assignment received.

We need to load player data when submitting our ticket to Open Match, so we’ll handle it on the server side. To perform a lookup for the player data, we provide the game client/player id as part of our request. We sit back and wait for the Game Frontend (and Open Match) to assign the client a game server address.

Wrapping up

Now that we have finished building out the Game Frontend let’s do a quick test. Run and start your Game Frontend application first. It will begin listening for incoming connections/requests. Next, start your Game Client application to connect and await for an assignment (which should happen pretty quickly). When it does, you should see output similar to this:

This is a simulation of what we should expect from the full Game Frontend service, and it’s a great stopping point until the next blog post, in which we’ll connect our Game Frontend with Open Match.

You can find the source code for this sample: GitHub

If you have any questions or comments, feel free to message me on Twitter.