Want to backfill instantly but retain minimum number of players relaxation rules when starting match

Hello,

I currently use a FlexMatch rule set that starts a game session when:

  • From 0 to < 1 min, find a 3v3 match
  • From 1 min to < 2 min, relax rules so that a game with a minimum of 2 players per team can be started, then backfill in game
  • From 2 min onwards, relax rules so that a game with a minimum of 1 player per team can be started, then backfill in game

Here is my rule set:

{
  "name": "QuickMatch",
  "ruleLanguageVersion": "1.0",
  "playerAttributes": [
    {
      "name": "skill",
      "type": "number",
      "default": 1000
    }
  ],
  "teams": [
    {
      "name": "team1",
      "maxPlayers": 3,
      "minPlayers": 3
    },
    {
      "name": "team2",
      "maxPlayers": 3,
      "minPlayers": 3
    }
  ],
  "rules": [
  ],
  "expansions": [
    {
      "target": "teams[team1].minPlayers",
      "steps": [
        {
          "waitTimeSeconds": 60,
          "value": 2
        },
        {
          "waitTimeSeconds": 120,
          "value": 1
        }
      ]
    },
    {
      "target": "teams[team2].minPlayers",
      "steps": [
        {
          "waitTimeSeconds": 60,
          "value": 2
        },
        {
          "waitTimeSeconds": 120,
          "value": 1
        }
      ]
    }
  ]
}

I use the same matchmaking config (+ rule set) for backfill. The problem is there is waiting time when there are only a few players. With my rule set with, here are some example scenarios:

  • Four players queue, wait 1 minute, get matched as a 2v2 match. Then, another player queues but waits for 1 minute for him to backfill in the existing match.
  • Two players queue, wait 2 minutes, get matched as a 1v1 match. Then, another player queues but waits for 2 minutes for him to backfill in the existing match.

What I want to achieve also is to be able to backfill players instantly when the game starts with less than 3 players per team (I am using manual backfill). Queue takes a long time when players are few because with my rule set, backfilling will apply the same relaxation rules: attempt to backfill players to complete a 3v3, then at least 2v2 after 1 min, then at least 1v1 after 2 min.

I tried using a separate matchmaking configuration for backfill but it does not seem to work, probably because the matchmaking config used by the user is different from the matchmaking config of the backfilling server. I also do not use automatic backfill because there are certain parts of the game where we disallow backfill.

My question is: is there any way I can use my player count relaxation rule (my rule set above) + instant backfill in one single matchmaking configuration with manual backfill?

Thanks for taking time to read and I appreciate any help.

Having dynamic matchmaking based on your queue depth would be great ie if x condition exists then do this in the ruleset, otherwise do y.

I could see how with a lambda you could periodically swap the rule set via update-matchmaking-configuration (you could have a CloudWatch alarm based on QueueDepth or [CurrentTickets](https://docs.aws.amazon.com/gamelift/latest/developerguide/monitoring-cloudwatch.html#gamelift-metrics-match)

I don’t believe GameLift FlexMatch offers any dynamic features out of the box. Its really written for large volume of tickets and its hard to write a balanced ruleset for low vs high volume.

You can:

  • Expand faster for matches that are harder to make, ie don’t wait a minute for 4x4 modes
  • Have separate configurations that favor a mode (ie this is my team queue, this is my 2 x 2 queue - which you can use for testing modes or having finer control over automated backfill. As you note this harder for the backend server to manage but it should be doable.

I’ll ping the GameLift team to see if they have any advice.

I’m interested in a similar behavior and this raises an interesting question for me: why exactly does changing the backfill matchmaking config not work?

  • Would changing the client’s start-matchmaking match config have the same issue as changing the server backfill config?
  • Do the client and server need to use identical matchmaking configs?
  • Or identical rulesets?
  • Do they have to be the same ARN or could they be different configs/rulesets that are functionally identical (useful in case I need to generate them and don’t explicitly check for duplicates).

PS: @Pao I currently work around this by using a 0 min player limit and then doing work on the game server to delay a game start until we get a larger team. It’s certainly not as nice as having MM handle this but it does work.

@Pip any comment on this ^

@ig_tyler - sorry for the lack of replies. I have had little time to spend on the forums this week.

I pinged the GameLift service team to take a look earlier today. Hopefully they’ll respond as backfill is something I only know anecdotally rather than in too much depth.

Client and server don’t have to have the same configs AFAIK. Your configs could target a shared queue but it may add complexity without having value. But the server config could have faster relaxation times for backfill.

Hey @ig_tyler!

In general, you want to avoid using multiple matchmaking configurations, as FlexMatch uses this essentially as an identifier to understand what matches should get placed together. For example, with the backfill issues in the original post here, the reason you can’t use a separate matchmaking config for your backfill requests is because FlexMatch won’t be able to identify that the backfill requests should be matched with the originally placed match.

I’d recommend checking out some of the matchmaking algorithm customization options for your rule set to see if they fit your use case. You can find more details about them here: https://docs.aws.amazon.com/gamelift/latest/flexmatchguide/match-design-ruleset.html For the original issue with trying to apply rules more quickly for your backfill requests, I’d recommend checking out the following options:

  • backfillPriority - This option tells FlexMatch how to prioritize your backfill requests along with all your other matchmaking requests. I’d recommend setting this to high if you want your backfill requests to get placed faster.
  • expansionAgeSelection - This option is the one that I really think will help out. It allows you to change how FlexMatch applies rules expansions in your rules set. Normally, for a potential match, FlexMatch applies rules expansions using the timestamp of the newest ticket being matched. So, if you have an original match that was made and a backfill matchmaking ticket queued up, it will normally use that backfill ticket’s creation time to apply the rules in the rule set, and the backfilled player will have to wait through any configured wait times for your expansions. If you select oldest for this property, FlexMatch will instead use the creation time of the original match’s ticket to apply it’s rules expansion, which means your backfill tickets can basically skip all the wait times for expansions that were already applied when the original match was placed.

Let us know if that helps!

Thanks @JoshC-AWS, this is great info. I don’t know how I missed these configurations before in the ruleset docs.

With regards to expansionAgeSelection, I’m hoping this would not actually skip the earlier rules, since that would open a can of worms for edge cases. Can you confirm that it still check all of the earlier expansion rules, just without waiting?

Hey @ig_tyler, unfortunately expansionAgeSelection will end up skipping the earlier expansion rules. FlexMatch will only apply each expansion once, and this algorithm configuration just changes the timestamp FlexMatch uses to pick the step of the expansion that will be applied for the request. I believe this is because, in many cases, this will result in unnecessary checks. Like for the original issue on this post regarding relaxing the rules of team sizes - if FlexMatch is going to eventually check that a potential match is valid with only 1 player on each team with the later expansions, it’s not really necessary for FlexMatch to check the earlier expansion rules with stricter team sizes.

Is there a specific edge case or rule expansion that you’re worried won’t work with the expansion age selector configuration? If you’re able, you can post a snippet here for us to check out - there may be another configuration or workaround available to prevent those edge cases.

Generally I would just be concerned about having to design all rulesets such that any of the expansions may be ignored.

Specifically, I currently use a ruleset that only requires teams of equal size (size distance max 1). I have expansions to increase the distance in order to allow a group of players to get a match (eg let a team of 2 match in to a 1v1 game). If earlier expansions get ignored then we might create an unnecessarily unbalanced team match.

Like say if there’s a game that’s currently 2v1, and then the backfill ticket skips the first rule of max difference 1 and puts the backfilling player on to the 2-player team, giving us a 3v1 game.

Sounds like you may just add a rule to restrict the number of player difference cannot exceed one, or am I missing something makes that not applicable?

Are you missing this part?

I mean, with one more rule, that will never be a problem.

{
“name”: “SimilarTeamSizes”,
“description”: “Number of player difference cannot exceed one”,
“type”: “distance”,
“measurements”: [ “count(teams[team1].players)” ],
“referenceValue”: “count(teams[team2].players)”,
“maxDistance”: “1”
}

Yes that’s what I’m using and I’m saying it won’t work with expansions if expansionAgeSelection skips the rules.

 {
    "name": "TwoTeamsBySizeRelax",
	"algorithm": {
		"backfillPriority": "high",
		"expansionAgeSelection": "newest",
		"strategy": "exhaustiveSearch"
	},
    "ruleLanguageVersion": "1.0",
	"teams": [{
		"name": "0",
		"maxPlayers": 6,
		"minPlayers": 0
	},
	{
		"name": "1",
		"maxPlayers": 6,
		"minPlayers": 0
	}],
	"rules": [{
        "name": "EqualTeamSizes",
        "description": "Ensure the team sizes are balanced- max 1 more player on each team",
        "type": "distance",
        "measurements": [ "count(teams[0].players)" ],
        "referenceValue": "count(teams[1].players)",
        "maxDistance": 1
    }],
	"expansions": [{
		"target": "rules[EqualTeamSizes].maxDistance",
		"steps": [{
			"waitTimeSeconds": 30,
			"value": 2
		}, {
			"waitTimeSeconds": 45,
			"value": 3
		}]
	}]
}