<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Open Match – Tutorials</title>
    <link>/site/docs/tutorials/</link>
    <description>Recent content in Tutorials on Open Match</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/site/docs/tutorials/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Docs: How to build a basic Matchmaker</title>
      <link>/site/docs/tutorials/matchmaker101/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/site/docs/tutorials/matchmaker101/</guid>
      <description>
        
        
        &lt;h2 id=&#34;objectives&#34;&gt;Objectives&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Understand how to use Open Match for Matchmaking.&lt;/li&gt;
&lt;li&gt;Author a simple Match Function, Game Frontend and Director in Golang.&lt;/li&gt;
&lt;li&gt;Build and run an E2E Matchmaker by connecting these components to an Open Match deployment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;h3 id=&#34;set-up-a-kubernetes-cluster&#34;&gt;Set up a Kubernetes Cluster&lt;/h3&gt;
&lt;p&gt;Some basic understanding of Kubernetes, kubectl is required to efficiently completely this tutorial. Follow the instructions to &lt;a href=&#34;/site/site/docs/installation/#setup-kubernetes-cluster&#34;&gt;set up a Kubernetes cluster&lt;/a&gt;, install and configure kubectl to connect to this cluster.&lt;/p&gt;
&lt;h3 id=&#34;install-open-match&#34;&gt;Install Open Match&lt;/h3&gt;
&lt;p&gt;Lets setup Open Match next by running the steps in &lt;a href=&#34;/site/site/docs/installation/yaml/#install-core-open-match&#34;&gt;Install Open Match Core&lt;/a&gt;. Please be sure to also &lt;a href=&#34;/site/site/docs/installation/yaml/#install-the-default-evaluator&#34;&gt;install the default Evaluator&lt;/a&gt;.&lt;/p&gt;


&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;

    If you already installed Open Match for the &lt;a href=&#34;/site/site/docs/getting-started/&#34;&gt;Getting Started Demo&lt;/a&gt;, you can skip this step. Simply &lt;a href=&#34;/site/site/docs/getting-started/#delete-the-demo&#34;&gt;delete the demo namespace&lt;/a&gt; and proceed.

&lt;/div&gt;

&lt;h3 id=&#34;set-up-image-registry&#34;&gt;Set up Image Registry&lt;/h3&gt;
&lt;p&gt;Please setup an Image registry(such as &lt;a href=&#34;https://hub.docker.com/&#34;&gt;Docker Hub&lt;/a&gt; or &lt;a href=&#34;https://cloud.google.com/container-registry/&#34;&gt;GC Container Registry&lt;/a&gt;) to store the Docker Images used in this tutorial. Once you have set this up, here are the instructions to set up a shell variable that points to your registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=[YOUR_REGISTRY_URL]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If using GKE, the below command can be used to populate the image registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=gcr.io/$(gcloud config list --format &amp;#39;value(core.project)&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;get-the-tutorial-template&#34;&gt;Get the Tutorial template&lt;/h3&gt;
&lt;p&gt;Make a local copy of the &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/matchmaker101&#34;&gt;Tutorials Folder&lt;/a&gt;. Checkout &lt;code&gt;release-x.y&lt;/code&gt; branch（e.g. release-1.3, release-1.4） of the Open Match Git repository. Use &lt;code&gt;tutorials/matchmaker101&lt;/code&gt; of &lt;code&gt;release-x.y&lt;/code&gt; branch as a working copy for all the instructions in this tutorial.&lt;/p&gt;
&lt;p&gt;For convenience, set the following variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;TUTORIALROOT=[SRCROOT]/tutorials/matchmaker101
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;create-the-tutorial-namespace&#34;&gt;Create the Tutorial namespace&lt;/h3&gt;
&lt;p&gt;Run this command to create a namespace mm101-tutorial in which all the components for this Tutorial will be deployed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl create namespace mm101-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;p&gt;Please read through the &lt;a href=&#34;/site/site/docs/guides/matchmaker/&#34;&gt;Matchmaking Guide&lt;/a&gt; as the Matchmaker in this tutorial is modeled around the components introduced in the Guide. Also, keep the &lt;a href=&#34;/site/site/docs/reference/api/&#34;&gt;API Reference&lt;/a&gt; handy to look up Open Match specific terminology used in this document.&lt;/p&gt;
&lt;p&gt;A complete &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/matchmaker101/solution&#34;&gt;solution&lt;/a&gt; for this tutorial can be found at &lt;code&gt;tutorials/matchmaker101/solution&lt;/code&gt; To use the solution directly, just run the &amp;ldquo;Build and Push&amp;rdquo; step in each of the component sections and then go to &lt;a href=&#34;/site/site/docs/tutorials/matchmaker101/deploy/&#34;&gt;Deploy and Run&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;The goal is to build a basic game mode based Matchmaker where there are a fixed set of game modes and each Player intends to find a match for a specific game mode.&lt;/p&gt;
&lt;p&gt;The tutorial walks through building the Game Frontend, Director, Match Function and then deploys them together. Here is a high-level flow once all these components are set up:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Game Frontend creates Tickets that specified a game mode.&lt;/li&gt;
&lt;li&gt;The Director requests for matches for a specific game mode.&lt;/li&gt;
&lt;li&gt;The Match Function queries for Tickets from the current pool that match this constraint and groups available Tickets into match proposals.&lt;/li&gt;
&lt;li&gt;The Director receives the matches and sets fake Assignments for Tickets in these.&lt;/li&gt;
&lt;li&gt;The Game Frontend receives these Assignments and then deletes the Tickets.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;for-the-curious-mind&#34;&gt;For the curious mind&lt;/h2&gt;
&lt;p&gt;Open Match enables the user to plug in a custom component called the Evaluator. The Evaluator is responsible for deduplicating any concurrently generated proposals, discarding or promoting the proposals as result Matches. Open Match provides a default Evaluator that this tutorial uses. This tutorial is designed not to generate concurrent conflicting proposals so Evaluation is a no-op. The deployment step deploys the default Evaluator in the tutorial namespace and configures this in Open Match. See the &lt;a href=&#34;/site/site/docs/guides/evaluator/&#34;&gt;Evaluator Guide&lt;/a&gt; for details on proposal evaluation.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Add new matchmaking criteria</title>
      <link>/site/docs/tutorials/matchmaker102/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/site/docs/tutorials/matchmaker102/</guid>
      <description>
        
        
        &lt;h2 id=&#34;objectives&#34;&gt;Objectives&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Adds new search criteria to Open Match&lt;/li&gt;
&lt;li&gt;Write a MatchFunction to get Tickets from multiple Pools and generate Team-based Matches.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;h3 id=&#34;basic-matchmaker-tutorial&#34;&gt;Basic Matchmaker Tutorial&lt;/h3&gt;
&lt;p&gt;It is highly recommended that you run the &lt;a href=&#34;/site/site/docs/tutorials/matchmaker101/&#34;&gt;Basic Matchmaker tutorial&lt;/a&gt; as it introduces the core concepts that this tutorial builds upon. After completion, please remember to &lt;a href=&#34;/site/site/docs/tutorials/matchmaker101/deploy/#cleanup&#34;&gt;cleanup the basic tutorial&lt;/a&gt; before proceeding.&lt;/p&gt;
&lt;h3 id=&#34;set-up-image-registry&#34;&gt;Set up Image Registry&lt;/h3&gt;
&lt;p&gt;Please setup an Image registry(such as &lt;a href=&#34;https://hub.docker.com/&#34;&gt;Docker Hub&lt;/a&gt; or &lt;a href=&#34;https://cloud.google.com/container-registry/&#34;&gt;Google Cloud Container Registry&lt;/a&gt;) to store the Docker Images used in this tutorial. Once you have set this up, here are the instructions to set up a shell variable that points to your registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=[YOUR_REGISTRY_URL]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If using GKE, you can populate the image registry using the command below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=gcr.io/$(gcloud config list --format &amp;#39;value(core.project)&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;get-the-tutorial-template&#34;&gt;Get the Tutorial template&lt;/h3&gt;
&lt;p&gt;Make a local copy of the &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/matchmaker102&#34;&gt;Tutorials Folder&lt;/a&gt;. Checkout &lt;code&gt;release-x.y&lt;/code&gt; branch（e.g. release-1.3, release-1.4） of the Open Match Git repository. Use &lt;code&gt;tutorials/matchmaker102&lt;/code&gt; of &lt;code&gt;release-x.y&lt;/code&gt; branch as a working copy for all the instructions in this tutorial.&lt;/p&gt;
&lt;p&gt;For convenience, set the following variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;TUTORIALROOT=[SRCROOT]/tutorials/matchmaker102
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;create-the-tutorial-namespace&#34;&gt;Create the Tutorial namespace&lt;/h3&gt;
&lt;p&gt;Run this command to create a namespace mm102-tutorial in which all the components for this Tutorial will be deployed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl create namespace mm102-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;p&gt;Please read through the &lt;a href=&#34;/site/site/docs/guides/matchmaker/&#34;&gt;Matchmaking Guide&lt;/a&gt; as the Matchmaker in this tutorial is modeled around the components introduced in the Guide. Also, keep the &lt;a href=&#34;/site/site/docs/reference/api/&#34;&gt;API Reference&lt;/a&gt; handy to look up Open Match specific terminology used in this document.&lt;/p&gt;
&lt;p&gt;A complete &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/matchmaker102/solution&#34;&gt;solution&lt;/a&gt; for this tutorial is in the folder &lt;code&gt;tutorials/matchmaker102/solution&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;changes-to-components&#34;&gt;Changes to Components&lt;/h2&gt;
&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;
&lt;p&gt;For this tutorial, let&amp;rsquo;s consider a game where each Player will choose to play the Match with a specific role (one of DPS, support or tank). Assume that a Match (for each game-mode) will comprise of one Player of each role. Here are the high-level changes to the Game Frontend, the Director and the MatchFunction to achieve this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Game Frontend will specify the role on a new SearchField on each Ticket.&lt;/li&gt;
&lt;li&gt;The Director will specify multiple Pools in each MatchProfile, one per role.&lt;/li&gt;
&lt;li&gt;The MatchFunction will query for Tickets for each Pool and generate Matches with a Ticket of each role.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The below sections cover the changes to be made to the key components to achieving this.&lt;/p&gt;
&lt;h3 id=&#34;game-frontend&#34;&gt;Game Frontend&lt;/h3&gt;
&lt;p&gt;This tutorial provides a Game Frontend scaffold (&lt;code&gt;$TUTORIALROOT/frontend&lt;/code&gt;) that generates a Ticket with the game mode specified (as implemented for the basic Matchmaker). The mock Ticket generation is implemented in &lt;code&gt;makeTicket()&lt;/code&gt; in &lt;code&gt;$TUTORIALROOT/frontend/ticket.go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We need to add a new SearchField to the Ticket to represent the role property for this Player. The below code snippet picks a random role and sets it as a StringArg SearchField for the fake Ticket.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;makeTicket&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Ticket&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ticket&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Ticket&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;SearchFields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SearchFields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Tags&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;gameMode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;StringArgs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;attributes.role&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ticket&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;roles&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;role.dps&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;role.support&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;role.tank&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;roles&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;rand&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Intn&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87&#34;&gt;len&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;roles&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))]&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Please update the Ticket creation logic in &lt;code&gt;$TUTORIALROOT/frontend/ticket.go&lt;/code&gt; with the above snippet and make your own tweaks.&lt;/p&gt;
&lt;h3 id=&#34;director&#34;&gt;Director&lt;/h3&gt;
&lt;p&gt;This tutorial provides a Director scaffold (&lt;code&gt;$TUTORIALROOT/director&lt;/code&gt;) that generates a MatchProfile per game-mode and then calls FetchMatches for each MatchProfile. The MatchProfile generation is implemented in &lt;code&gt;generateProfiles()&lt;/code&gt; in &lt;code&gt;$TUTORIALROOT/director/profile.go&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In the basic Matchmaker, each MatchProfile had a single Pool specifying the game-mode filter. For this tutorial, we will have a Pool per role that filters the role along with the filter for the mode. Thus, the &lt;code&gt;generateProfiles()&lt;/code&gt; will generate a MatchProfile for each game-mode, each of which will have a Pool per role. Below is a sample snippet to achieve this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;generateProfiles&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchProfile&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;profiles&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchProfile&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;modes&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.demo&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.ctf&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.battleroyale&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;roles&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;role.dps&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;role.support&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;role.tank&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mode&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;modes&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;pools&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Pool&lt;/span&gt;
    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;_&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;role&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;roles&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;pools&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;append&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pools&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Pool&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;fmt&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Sprintf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;pool_%s_%s&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;TagPresentFilters&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;TagPresentFilter&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{{&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Tag&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}},&lt;/span&gt;
        &lt;span style=&#34;color:#000&#34;&gt;StringEqualsFilters&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;StringEqualsFilter&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
          &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;StringArg&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;attributes.role&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
            &lt;span style=&#34;color:#000&#34;&gt;Value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;     &lt;span style=&#34;color:#000&#34;&gt;role&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
          &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

    &lt;span style=&#34;color:#000&#34;&gt;profiles&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;append&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;profiles&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt;  &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;profile_&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;mode&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Pools&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;pools&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;profiles&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Please update the MatchProfile creation logic in &lt;code&gt;$TUTORIALROOT/director/profiles.go&lt;/code&gt; with the above snippet and make your own tweaks.&lt;/p&gt;
&lt;h3 id=&#34;matchfunction&#34;&gt;MatchFunction&lt;/h3&gt;
&lt;p&gt;This tutorial provides a MatchFunction scaffold (&lt;code&gt;$TUTORIALROOT/matchfunction&lt;/code&gt;) that generates Match proposals for the MatchProfile that gets passed in. The core matchmaking logic is implemented in &lt;code&gt;makeMatches()&lt;/code&gt; in &lt;code&gt;$TUTORIALROOT/matchfunction/mmf/matchfunction.go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;QueryPools&lt;/code&gt; helper from the &lt;code&gt;matchfunction&lt;/code&gt; library already provides the ability to query Tickets for all the Pools in the MatchProfile. Also, the basic Matchmaker implementation already picks players from each Pool into the Match - hence just by the MatchProfile having one Pool per role, the existing MatchFunction will generate Match proposals with Tickets of each role.&lt;/p&gt;
&lt;p&gt;Although no changes are needed to the core matchmaking logic, you may add some logging or tweak the number of players from each role in a team, etc., to observe the change in matchmaking behavior.&lt;/p&gt;
&lt;h2 id=&#34;build-deploy-run&#34;&gt;Build, Deploy, Run&lt;/h2&gt;
&lt;h3 id=&#34;build-and-push-container-images&#34;&gt;Build and Push Container images&lt;/h3&gt;
&lt;p&gt;Now that you have customized these components, please run the below commands from &lt;code&gt;$TUTORIALROOT&lt;/code&gt; to build new images and push them to your configured image registry.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;docker build -t $REGISTRY/mm102-tutorial-frontend frontend/
docker push $REGISTRY/mm102-tutorial-frontend
docker build -t $REGISTRY/mm102-tutorial-director director/
docker push $REGISTRY/mm102-tutorial-director
docker build -t $REGISTRY/mm102-tutorial-matchfunction matchfunction/
docker push $REGISTRY/mm102-tutorial-matchfunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;deploy-and-run&#34;&gt;Deploy and Run&lt;/h3&gt;
&lt;p&gt;Run the below command in the &lt;code&gt;$TUTORIALROOT&lt;/code&gt; path to deploy the MatchFunction, Game Frontend and the Director to the &lt;code&gt;mm102-tutorial&lt;/code&gt; namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;sed &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;s|REGISTRY_PLACEHOLDER|$REGISTRY|g&amp;#34;&lt;/span&gt; matchmaker.yaml &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;output&#34;&gt;Output&lt;/h3&gt;
&lt;p&gt;All the components in this tutorial simply log their progress to stdout. Thus to see the progress, run the below commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl logs -n mm102-tutorial pod/mm102-tutorial-frontend
kubectl logs -n mm102-tutorial pod/mm102-tutorial-director
kubectl logs -n mm102-tutorial pod/mm102-tutorial-matchfunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cleanup&#34;&gt;Cleanup&lt;/h2&gt;
&lt;p&gt;Run the command below to remove all the components of this tutorial:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl delete namespace mm102-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will delete all the components deployed in this tutorial. Open Match core in open-match namespace can then be reused for other exercises but you will need to re-customize it.&lt;/p&gt;
&lt;h2 id=&#34;whats-next&#34;&gt;What&amp;rsquo;s Next&lt;/h2&gt;
&lt;p&gt;Given that a Ticket can only pick one game-mode, the Matchmaker implemented so far generate Matches from completely partitioned Tickets, where a Ticket is only considered for a game-mode. Next, we can learn how to &lt;a href=&#34;/site/site/docs/tutorials/defaultevaluator/&#34;&gt;use the default evaluator&lt;/a&gt; to handle scenarios where a Ticket may specify multiple game mode preferences and hence may be picked by more than one MatchFunction.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Use the Default Evaluator</title>
      <link>/site/docs/tutorials/defaultevaluator/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/site/docs/tutorials/defaultevaluator/</guid>
      <description>
        
        
        &lt;h2 id=&#34;objectives&#34;&gt;Objectives&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Understands how and why we need the Default Evaluator to resolve proposal conflicts.&lt;/li&gt;
&lt;li&gt;Instructs your MatchFunction to use the default Evaluator.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;h3 id=&#34;basic-matchmaker-tutorial&#34;&gt;Basic Matchmaker tutorial&lt;/h3&gt;
&lt;p&gt;It is highly recommended that you run the &lt;a href=&#34;/site/site/docs/tutorials/matchmaker101/&#34;&gt;Basic Matchmaker tutorial&lt;/a&gt; as it introduces the core concepts that this tutorial builds upon. After completion, please remember to &lt;a href=&#34;/site/site/docs/tutorials/matchmaker101/deploy/#cleanup&#34;&gt;cleanup the basic tutorial&lt;/a&gt; before proceeding.&lt;/p&gt;
&lt;h3 id=&#34;set-up-image-registry&#34;&gt;Set up Image Registry&lt;/h3&gt;
&lt;p&gt;Please setup an Image registry(such as &lt;a href=&#34;https://hub.docker.com/&#34;&gt;Docker Hub&lt;/a&gt; or &lt;a href=&#34;https://cloud.google.com/container-registry/&#34;&gt;GC Container Registry&lt;/a&gt;) to store the Docker Images that will be generated in this tutorial. Once you have set this up, here are the instructions to set up a shell variable that points to your registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=[YOUR_REGISTRY_URL]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If using GKE, you can populate the image registry using the command below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=gcr.io/$(gcloud config list --format &amp;#39;value(core.project)&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;get-the-tutorial-template&#34;&gt;Get the tutorial template&lt;/h3&gt;
&lt;p&gt;Make a local copy of the &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/default_evaluator&#34;&gt;tutorials Folder&lt;/a&gt;. Checkout &lt;code&gt;release-x.y&lt;/code&gt; branch（e.g. release-1.3, release-1.4） of the Open Match Git repository. Use &lt;code&gt;tutorials/default_evaluator&lt;/code&gt; of &lt;code&gt;release-x.y&lt;/code&gt; branch as a working copy for all the instructions in this tutorial.&lt;/p&gt;
&lt;p&gt;For convenience, set the following variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;TUTORIALROOT=[SRCROOT]/tutorials/default_evaluator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;create-the-tutorial-namespace&#34;&gt;Create the tutorial namespace&lt;/h3&gt;
&lt;p&gt;Run this command to create a namespace default-eval-tutorial in which all the components for this tutorial will be deployed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl create namespace default-eval-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;p&gt;It is highly recommended that you read the &lt;a href=&#34;/site/site/docs/guides/evaluator/&#34;&gt;Evaluator Guide&lt;/a&gt; to familiarize yourself with the lifecycle of a Match proposal through the synchronization and evaluation phases. Also, keep the &lt;a href=&#34;/site/site/docs/reference/api/&#34;&gt;API Reference&lt;/a&gt; handy to look up Open Match specific terminology used in this document.&lt;/p&gt;
&lt;p&gt;A complete &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/default_evaluator/solution&#34;&gt;solution&lt;/a&gt; for this tutorial is in the folder &lt;code&gt;tutorials/default_evaluator/solution&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;evaluation&#34;&gt;Evaluation&lt;/h2&gt;
&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;
&lt;p&gt;In the &lt;a href=&#34;/site/site/docs/tutorials/matchmaker101/&#34;&gt;basic Matchmaker&lt;/a&gt;, each Ticket had only one game-mode and the Director generated a MatchProfile per game-mode. Thus concurrently executing MatchFunction (for each MatchProfile) worked with completely partitioned (by game-mode) Ticket Pools. However, this may not always be the case. There are scenarios in which, the Pools specified in concurrent MatchProfiles may have an overlap and thus concurrently executing MatchFunctions could use overlapping Ticket in its Proposals.&lt;/p&gt;
&lt;p&gt;In a lot of real matchmaking scenarios, this overlap is desired. To generate high-quality Matches, you may want your Ticket to be considered concurrently for multiple possible MatchProfiles and then be able to compare the quality of these overlapping Matches, picking the highest quality Match and discarding the rest. The ability to provide this model of executing concurrent MatchFunctions on overlapping Ticket Pool is a core value proposition of Open Match.&lt;/p&gt;
&lt;p&gt;To allow generation of proposals using overlapping Tickets but still provide unique Matches to the Director, Open Match synchronizes all the proposals generated by concurrently executing MatchFunctions and passes these to an Evaluator to perform de-collision.&lt;/p&gt;
&lt;p&gt;Since basic cases may either not need an evaluation or may need very simple evaluation, Open Match provides a default Evaluator as an optional component that may work in most scenarios. At a high level, there are three evaluation scenarios for you to consider when using Open Match:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Your MatchProfiles completely partition the Ticket Pool and so you will never have collisions(the basic Matchmaker falls under this usage). The default Evaluator handles this scenario and you do not have to make any changes.&lt;/li&gt;
&lt;li&gt;Your MatchProfiles may use overlapping Ticket Pools - but each MatchFunction can simply generate a quality score for that Match based on certain game-specific criteria (latency, MMR, etc.). The default Evaluator can be used for this scenario by following instructions in this tutorial to add specific information needed for evaluation to the Match in your MatchFunction.&lt;/li&gt;
&lt;li&gt;You have complex evaluation logic that cannot be simplified to a score for a Match but rather involves comparing some details of the overlapping Matches. Open Match provides you with the ability to plug in your custom Evaluator to handle this case. See the &lt;a href=&#34;/site/site/docs/tutorials/customevaluator/&#34;&gt;tutorial for using a Custom Evaluator&lt;/a&gt; for details.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;default-evaluator&#34;&gt;Default Evaluator&lt;/h3&gt;
&lt;p&gt;The Evaluator for Open Match at a high level accepts Match proposals (that may be overlapping) and returns non-overlapping result Matches. Open Match provides an optional default score based Evaluator that you can deploy with core Open Match installation.&lt;/p&gt;
&lt;p&gt;The default Evaluator expects that the MatchFunction populate a &amp;lsquo;score&amp;rsquo; for the generated Matches. When it is invoked with a list of proposals, it simply sorts the Matches by score and in case of collision, picks the Match with the highest score as a result and discards the other colliding matches.&lt;/p&gt;
&lt;p&gt;The MatchFunction may use a game-specific information (MMR, latency, etc.) to compute the score for this Match. It populates the score in a DefaultEvaluationCriteria proto that is shown below.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-proto&#34; data-lang=&#34;proto&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;DefaultEvaluationCriteria&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;double&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;score&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;
&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a40000&#34;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The MatchFunction embeds the populated DefaultEvaluationCriteria in the Match&amp;rsquo;s Extensions field (Extensions are a mechanism Open Match uses to pass blobs of specific information across components that extend Open Match). The default Evaluator accesses the score for the Match from this field and uses it as a proxy for the Match quality. This tutorial provides step-by-step instructions and samples to generate the score and populate the DefaultEvaluationCriteria for a Match.&lt;/p&gt;
&lt;h2 id=&#34;using-the-default-evaluator&#34;&gt;Using the Default Evaluator&lt;/h2&gt;
&lt;h3 id=&#34;scenario-overview&#34;&gt;Scenario Overview&lt;/h3&gt;
&lt;p&gt;For this tutorial, we will tweak the basic matchmaking scenario to enable a Player to select more than one game-mode to be considered for finding a Match. Given that the Director for our Matchmaker generates a MatchProfile per game-mode, concurrent MatchFunction executions handling different MatchProfiles will both consider the same Ticket(Player) for their respective Match proposals. We will use the default Evaluator provided by Open Match to resolve conflicts in this scenario.&lt;/p&gt;
&lt;p&gt;To generate a score (for evaluation) indicating the Match quality, we will introduce a new property on each Ticket indicating the time at which the Ticket entered matchmaking queue. The MatchFunction can then aggregate the wait times for all the Tickets in a Match to generate a score for that Match. Higher the score, longer the total wait times and higher the likelihood that the default Evaluator will pick the Match in case of a conflict.&lt;/p&gt;
&lt;p&gt;Here are the changes we need to make at a high level to our components to achieve this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Game Frontend will generate Tickets with two game-mode preferences.&lt;/li&gt;
&lt;li&gt;The Game Frontend will add a new SearchField indicating the time of entry in matchmaking queue.&lt;/li&gt;
&lt;li&gt;The MatchFunction will generate the score for each Match to be used as evaluation criteria.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The below sections provide details of these changes:&lt;/p&gt;
&lt;h3 id=&#34;game-frontend&#34;&gt;Game Frontend&lt;/h3&gt;
&lt;p&gt;This tutorial provides a Game Frontend scaffold (&lt;code&gt;$TUTORIALROOT/frontend&lt;/code&gt;) that generates a Ticket with the game-mode specified (as implemented for the basic Matchmaker). The mock Ticket generation is implemented in &lt;code&gt;makeTicket()&lt;/code&gt; in &lt;code&gt;$TUTORIALROOT/frontend/ticket.go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The below snippet adds a new SearchField representing the time of entry in matchmaking queue:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;makeTicket&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Ticket&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;ticket&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Ticket&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;SearchFields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SearchFields&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Tags&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;gameModes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;DoubleArgs&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;float64&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
        &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;time.enterqueue&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;enterQueueTime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(),&lt;/span&gt;
      &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;},&lt;/span&gt;
  &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ticket&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;enterQueueTime&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;float64&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Implement your logic to return a random time interval.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;gameModes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;()&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;modes&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.demo&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.ctf&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.battleroyale&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;mode.2v2&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Implement your logic to return any two of the above game-modes randomly
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Please update the Ticket creation logic in &lt;code&gt;$TUTORIALROOT/frontend/ticket.go&lt;/code&gt; with the above snippet adding your logic to pick the random time and game-modes.&lt;/p&gt;
&lt;h3 id=&#34;matchfunction&#34;&gt;MatchFunction&lt;/h3&gt;
&lt;p&gt;This tutorial provides a MatchFunction scaffold (&lt;code&gt;$TUTORIALROOT/matchfunction&lt;/code&gt;) that generates Match proposals for the MatchProfile that gets passed in. The core matchmaking logic is implemented in &lt;code&gt;makeMatches()&lt;/code&gt; in &lt;code&gt;$TUTORIALROOT/matchfunction/mmf/matchfunction.go&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Just because a Ticket has multiple game-modes, the MatchFunction will now consider Tickets for Match generation that other concurrent proposals use. Thus without any change to the core matchmaking logic here, we will generate overlapping results across MatchFunction executions.&lt;/p&gt;
&lt;p&gt;To use default Evaluator, the MatchFunction needs to calculate a score for each Match and populate that in the DefaultEvaluationCriteria field. The code below demonstrates how to populate this field in the MatchFunction:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;
&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;makeMatches&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;p&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MatchProfile&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;poolTickets&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;map&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;][]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Ticket&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;([]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Match&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Add score calculation logic here.
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#000&#34;&gt;matchScore&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;scoreCalculator&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;matchTickets&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#000&#34;&gt;evaluationInput&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ptypes&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;MarshalAny&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;DefaultEvaluationCriteria&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;Score&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;matchScore&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;})&lt;/span&gt;

    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
      &lt;span style=&#34;color:#000&#34;&gt;log&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Printf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Failed to marshal DefaultEvaluationCriteria, got %w.&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
      &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;fmt&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Errorf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;Failed to marshal DefaultEvaluationCriteria, got %w&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;err&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt;
    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

  &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;...&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;

&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;scoreCalculator&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;tickets&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Ticket&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;float64&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#000&#34;&gt;matchScore&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0.0&lt;/span&gt;
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Add your logic to compute the score for this Match here
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;matchScore&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add the above snippet to the MatchFunction and populate the logic for score calculation. One strategy you may use is to aggregate the wait time for each Ticket and use that value as the score.&lt;/p&gt;
&lt;h2 id=&#34;build-deploy-run&#34;&gt;Build, Deploy, Run&lt;/h2&gt;
&lt;h3 id=&#34;build-and-push-container-images&#34;&gt;Build and Push Container images&lt;/h3&gt;
&lt;p&gt;Now that you have customized these components, please run the below commands from &lt;code&gt;$TUTORIALROOT&lt;/code&gt; to build new images and push them to your configured image registry.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;docker build -t $REGISTRY/default-eval-tutorial-frontend frontend/
docker push $REGISTRY/default-eval-tutorial-frontend
docker build -t $REGISTRY/default-eval-tutorial-director director/
docker push $REGISTRY/default-eval-tutorial-director
docker build -t $REGISTRY/default-eval-tutorial-matchfunction matchfunction/
docker push $REGISTRY/default-eval-tutorial-matchfunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;deploy-and-run&#34;&gt;Deploy and Run&lt;/h3&gt;
&lt;p&gt;Run the below command in the &lt;code&gt;$TUTORIALROOT&lt;/code&gt; path to deploy the MatchFunction, Game Frontend and the Director to the &lt;code&gt;default-eval-tutorial&lt;/code&gt; namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;sed &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;s|REGISTRY_PLACEHOLDER|$REGISTRY|g&amp;#34;&lt;/span&gt; matchmaker.yaml &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;output&#34;&gt;Output&lt;/h3&gt;
&lt;p&gt;All the components in this tutorial simply log their progress to stdout. Thus to see the progress, run the below commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl logs -n default-eval-tutorial pod/default-eval-tutorial-frontend
kubectl logs -n default-eval-tutorial pod/default-eval-tutorial-director
kubectl logs -n default-eval-tutorial pod/default-eval-tutorial-matchfunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To check the logs from the default Evaluator, run the following commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;# Locate the Evaluator pod(s) using the following command
kubectl get pods -n open-match

# Check the logs from the Evaluator pod
kubectl logs -n open-match &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;&amp;lt;&lt;/span&gt;Evaluator Pod&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cleanup&#34;&gt;Cleanup&lt;/h2&gt;
&lt;p&gt;Run the below command to remove all the components of this tutorial:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl delete namespace default-eval-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will delete all the components deployed in this tutorial. Open Match core in open-match namespace can then be reused for other exercises but you will need to re-customize it.&lt;/p&gt;
&lt;h2 id=&#34;whats-next&#34;&gt;What&amp;rsquo;s Next&lt;/h2&gt;
&lt;p&gt;There are scenarios where evaluating overlapping Matches may need context from both Matches and thus the logic may not be represented by a single score computed in isolation for a Match. In such cases, you can &lt;a href=&#34;/site/site/docs/tutorials/customevaluator/&#34;&gt;build your custom Evaluator&lt;/a&gt; and connect that to Open Match.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Docs: Build a Custom Evaluator</title>
      <link>/site/docs/tutorials/customevaluator/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/site/docs/tutorials/customevaluator/</guid>
      <description>
        
        
        &lt;h2 id=&#34;objectives&#34;&gt;Objectives&lt;/h2&gt;
&lt;p&gt;The tutorial aims to explain how to :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build your Custom Evaluator&lt;/li&gt;
&lt;li&gt;Deploy, Run your custom Evaluator and configure Open Match core to use it&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;prerequisites&#34;&gt;Prerequisites&lt;/h2&gt;
&lt;h3 id=&#34;default-evaluator-tutorial&#34;&gt;Default Evaluator tutorial&lt;/h3&gt;
&lt;p&gt;It is highly recommended that you run the &lt;a href=&#34;/site/site/docs/tutorials/defaultevaluator/&#34;&gt;default Evaluator tutorial&lt;/a&gt; as it introduces the core concepts that this tutorial builds upon. After completion, please remember to &lt;a href=&#34;/site/site/docs/tutorials/defaultevaluator/#cleanup&#34;&gt;cleanup the default Evaluator tutorial&lt;/a&gt; before proceeding.&lt;/p&gt;


&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;

    &lt;p&gt;Given that all the other tutorials so far use the default Evaluator, the chances are, you already have the default Evaluator deployed in the open-match namespace. That is OK as at a later point, you will simply configure Open Match to point to your custom Evaluator in this tutorial&amp;rsquo;s namespace.&lt;/p&gt;
&lt;p&gt;However, given that the default Evaluator in the open-match namespace will not be used for this tutorial, you may choose to delete it. Alternatively, you may delete the open-match namespace and &lt;a href=&#34;/site/site/docs/installation/yaml/#install-core-open-match&#34;&gt;Install Open Match Core&lt;/a&gt; &lt;strong&gt;without&lt;/strong&gt; installing the default Evaluator.&lt;/p&gt;


&lt;/div&gt;

&lt;h3 id=&#34;set-up-image-registry&#34;&gt;Set up Image Registry&lt;/h3&gt;
&lt;p&gt;Please setup an Image registry(such as &lt;a href=&#34;https://hub.docker.com/&#34;&gt;Docker Hub&lt;/a&gt; or &lt;a href=&#34;https://cloud.google.com/container-registry/&#34;&gt;GC Container Registry&lt;/a&gt;) to store the Docker Images used in this tutorial. Once you have set this up, here are the instructions to set up a shell variable that points to your registry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=[YOUR_REGISTRY_URL]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If using GKE, you can populate the image registry using the command below:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;REGISTRY=gcr.io/$(gcloud config list --format &amp;#39;value(core.project)&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;get-the-tutorial-template&#34;&gt;Get the tutorial template&lt;/h3&gt;
&lt;p&gt;Make a local copy of the &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/custom_evaluator&#34;&gt;tutorials Folder&lt;/a&gt;. Checkout &lt;code&gt;release-x.y&lt;/code&gt; branch（e.g. release-1.3, release-1.4） of the Open Match Git repository. Use &lt;code&gt;tutorials/custom_evaluator&lt;/code&gt; of &lt;code&gt;release-x.y&lt;/code&gt; branch as a working copy for all the instructions in this tutorial.&lt;/p&gt;
&lt;p&gt;For convenience, set the following variable:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;TUTORIALROOT=[SRCROOT]/tutorials/custom_evaluator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;

    This tutorial only focuses on building the custom Evaluator and so the working copy of Matchmaker components already has the changes to Frontend, Director that were made to work with the default Evaluator.

&lt;/div&gt;

&lt;h3 id=&#34;create-the-tutorial-namespace&#34;&gt;Create the tutorial namespace&lt;/h3&gt;
&lt;p&gt;Run this command to create a namespace custom-eval-tutorial in which all the components for this tutorial will be deployed.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl create namespace custom-eval-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;p&gt;It is highly recommended that you read the &lt;a href=&#34;/site/site/docs/guides/evaluator/&#34;&gt;Evaluator Guide&lt;/a&gt; to familiarize yourself with the lifecycle of a Match proposal through the synchronization and evaluation phases. Also, keep the &lt;a href=&#34;/site/site/docs/reference/api/&#34;&gt;API Reference&lt;/a&gt; handy to look up Open Match specific terminology used in this document. The tutorial also customizes the Open Match installation with the configuration of the custom Evaluator. The &lt;a href=&#34;/site/site/docs/guides/custom/&#34;&gt;Customization Guide&lt;/a&gt; is a good reference for those changes.&lt;/p&gt;
&lt;p&gt;A complete &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/custom_evaluator/solution&#34;&gt;solution&lt;/a&gt; for this tutorial is in the folder &lt;code&gt;tutorials/custom_evaluator/solution&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;custom-evaluator&#34;&gt;Custom Evaluator&lt;/h2&gt;
&lt;h3 id=&#34;scenario-overview&#34;&gt;Scenario Overview&lt;/h3&gt;
&lt;p&gt;For this tutorial, we will use the matchmaking scenario where a Player selects more than one game-mode to be considered for finding a Match. This will result in concurrent MatchFunction executions to generate overlapping results and hence require evaluation. We will build a custom Evaluator and configure Open Match to resolve conflicts using this Evaluator. We will also add the property on the Ticket indicating the time at which the Ticket entered matchmaking queue.


&lt;div class=&#34;alert alert-info&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;alert-heading&#34;&gt;Note&lt;/h4&gt;

    Comparing to the default Evaluator, the Matchmaking function &lt;strong&gt;need&lt;/strong&gt; not precompute any score to hint on Match quality. You will have full control over what Tickets decide a better Match with a custom evaluator.

&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;Thus, the only change to the Matchmaker components from the default Evaluator tutorial is that we will not compute the score or the DefaultEvaluationCriteria in the Match Function. The core of the tutorial thus will focus on authoring the Evaluator and customizing Open Match with it.&lt;/p&gt;
&lt;h3 id=&#34;building-the-evaluator&#34;&gt;Building the Evaluator&lt;/h3&gt;
&lt;p&gt;Please revisit the Evaluator overview section in the &lt;a href=&#34;/site/site/docs/tutorials/defaultevaluator/#evaluation&#34;&gt;default Evaluator tutorial&lt;/a&gt; as it specifically calls out the scenario in which a custom Evaluator is needed.&lt;/p&gt;
&lt;p&gt;This tutorial provides an Evaluator scaffold (&lt;code&gt;$TUTORIALROOT/evaluator&lt;/code&gt;) as a starting point. The basis &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/custom_evaluator/evaluator/evaluate/server.go&#34;&gt;Evaluator server&lt;/a&gt; implementation in &lt;code&gt;$TUTORIALROOT/evaluator/evaluate/server.go&lt;/code&gt; provides the following functionality:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creates a gRPC service that listens on the configured port&lt;/li&gt;
&lt;li&gt;Implements the &lt;code&gt;Evaluate()&lt;/code&gt; interface that Open Match prescribes&lt;/li&gt;
&lt;li&gt;Accepts a stream of proposals in its implementation for this interface and then calls into a simplified helper method.&lt;/li&gt;
&lt;li&gt;Streams back results from the helper method to Open Match.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below is the &lt;code&gt;evaluate()&lt;/code&gt; helper method in &lt;code&gt;$TUTORIALROOT/evaluator/evaluate/evaluator.go&lt;/code&gt; where the core evaluation logic should be implemented. At runtime, Open Match calls the &lt;code&gt;Evaluate()&lt;/code&gt; method and streams the proposals for evaluation. This triggers the &lt;code&gt;evaluate()&lt;/code&gt; method with a list of proposals. The &lt;code&gt;evaluate()&lt;/code&gt; method should de-collide the proposals and return a list of results that Open Match will then return back to the Director.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-golang&#34; data-lang=&#34;golang&#34;&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;evaluate&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;proposals&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;pb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Match&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;([]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Core evaluation logic
&lt;/span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;&lt;/span&gt;  &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{},&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;nil&lt;/span&gt;
&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Please add your evaluation logic to this method. Here are some strategies for evaluation you may use when you detect Matches with overlapping Tickets:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Aggregate the wait time of the Tickets on the Match. The Match with higher aggregate wait time is selected and the rest are discarded.&lt;/li&gt;
&lt;li&gt;Match with the Ticket with the longest wait time gets selected and others discarded.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are just suggestions. You can also experiment with your own evaluation criteria for this scenario.&lt;/p&gt;
&lt;p&gt;As a reference, you may check the implementation of the &lt;a href=&#34;https://github.com/googleforgames/open-match/blob/main/tutorials/custom_evaluator/solution/evaluator/evaluate/evaluator.go&#34;&gt;tutorial solution Evaluator&lt;/a&gt; that uses strategy 2.&lt;/p&gt;
&lt;h3 id=&#34;build-and-push&#34;&gt;Build and Push&lt;/h3&gt;
&lt;p&gt;Now that we have a custom Evaluator, please run the below commands in the &lt;code&gt;$TUTORIALROOT&lt;/code&gt; to build and push the Evaluator to your configured image registry.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;docker build -t $REGISTRY/custom-eval-tutorial-evaluator evaluator/
docker push $REGISTRY/custom-eval-tutorial-evaluator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;deploy-and-customize&#34;&gt;Deploy and Customize&lt;/h3&gt;
&lt;p&gt;Run the below command in the &lt;code&gt;$TUTORIALROOT&lt;/code&gt; path to deploy the custom Evaluator to the &lt;code&gt;custom-eval-tutorial&lt;/code&gt; namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;sed &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;s|REGISTRY_PLACEHOLDER|$REGISTRY|g&amp;#34;&lt;/span&gt; evaluator/evaluator.yaml &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We need to update the Open Match ConfigMap with details of the custom Evaluator. The &lt;a href=&#34;/site/site/docs/guides/custom/&#34;&gt;Customization Guide&lt;/a&gt; provides some details on customizing your Open Match installation. The updated ConfigMap for the custom Evaluator is present in the &lt;code&gt;customization.yaml&lt;/code&gt;. Run the below command in the &lt;code&gt;$TUTORIALROOT&lt;/code&gt; path to customize Open Match installation:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl apply -f customization.yaml --namespace open-match
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;build-deploy-run-matchmaker&#34;&gt;Build, Deploy, Run Matchmaker&lt;/h2&gt;
&lt;h3 id=&#34;build-and-push-container-images&#34;&gt;Build and Push Container images&lt;/h3&gt;
&lt;p&gt;Now that you have customized these components, please run the below commands from &lt;code&gt;$TUTORIALROOT&lt;/code&gt; to build new images and push them to your configured image registry.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;docker build -t $REGISTRY/custom-eval-tutorial-frontend frontend/
docker push $REGISTRY/custom-eval-tutorial-frontend
docker build -t $REGISTRY/custom-eval-tutorial-director director/
docker push $REGISTRY/custom-eval-tutorial-director
docker build -t $REGISTRY/custom-eval-tutorial-matchfunction matchfunction/
docker push $REGISTRY/custom-eval-tutorial-matchfunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;deploy-and-run&#34;&gt;Deploy and Run&lt;/h3&gt;
&lt;p&gt;Run the below command in the &lt;code&gt;$TUTORIALROOT&lt;/code&gt; path to deploy the MatchFunction, Game Frontend. the Director to the &lt;code&gt;custom-eval-tutorial&lt;/code&gt; namespace:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-cmd&#34; data-lang=&#34;cmd&#34;&gt;sed &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;s|REGISTRY_PLACEHOLDER|$REGISTRY|g&amp;#34;&lt;/span&gt; matchmaker.yaml &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;|&lt;/span&gt; kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;output&#34;&gt;Output&lt;/h3&gt;
&lt;p&gt;All the components in this tutorial simply log their progress to stdout. To see the progress, run the below commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl logs -n custom-eval-tutorial pod/custom-eval-tutorial-frontend
kubectl logs -n custom-eval-tutorial pod/custom-eval-tutorial-director
kubectl logs -n custom-eval-tutorial pod/custom-eval-tutorial-matchfunction
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To check the logs from the custom Evaluator, run the following commands:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl logs -n custom-eval-tutorial pod/custom-eval-tutorial-evaluator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cleanup&#34;&gt;Cleanup&lt;/h2&gt;
&lt;p&gt;Run the below command to remove all the components of this tutorial:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;kubectl delete namespace custom-eval-tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will delete all the components deployed in this tutorial. Open Match core in open-match namespace can then be reused for other exercises but you will need to re-customize it.&lt;/p&gt;

      </description>
    </item>
    
  </channel>
</rss>
