<!--
{
  "documentType" : "article",
  "framework" : "GameKit",
  "identifier" : "/documentation/GameKit/finding-players-with-similar-skill-levels",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Finding players with similar skill levels"
}
-->

# Finding players with similar skill levels

Add a rule to find players in a range of skill levels to balance competitive gameplay.

## Discussion

When finding players using matchmaking rules, consider adding a rule that finds players in a range of skill levels to make gameplay more enjoyable and fair for all players. To reduce wait times for players, make the rule widen the skill range as the wait time, or age of the match request, increases.

This article shows one way to find players by skill level that you can combine with your other matchmaking rules. For other types of matchmaking rules, see [Letting players join matches using party codes](/documentation/GameKit/letting-players-join-matches-using-party-codes) and [Assigning players to teams using rules](/documentation/GameKit/assigning-players-to-teams-using-rules).

### Create a skill-level rule set and queue

First create a rule set to contain the skill-level rule. Pass a reference name, the minimum players, and the maximum players properties that are game-specific to the <doc://com.apple.documentation/documentation/AppStoreConnectAPI/POST-v1-gameCenterMatchmakingRuleSets> endpoint.

```json
POST /v1/gameCenterMatchmakingRuleSets
{
    "data": {
        "type": "gameCenterMatchmakingRuleSets",
        "attributes": {
            "referenceName": "com.example.mygame.SkillBasedRules",
            "ruleLanguageVersion": 1,
            "minPlayers": 2,
            "maxPlayers": 4
        },
        "relationships": {}
    }
}
```

Retain the `id` field of the <doc://com.apple.documentation/documentation/AppStoreConnectAPI/GameCenterMatchmakingRuleSet> object that this endpoint returns to use later when you create the skill-level rule.

```json
{
    "data": {
        "type": "gameCenterMatchmakingRuleSets",
        "id": "36c540f2-031a-4e35-8260-d0804e40376b",
        "attributes": {
            "referenceName": "com.example.mygame.SkillBasedRules",
            "ruleLanguageVersion": 1,
            "minPlayers": 2,
            "maxPlayers": 4
        },
...
}
```

Then create and add the rule set to a skill-level queue. Pass a reference name and the rule set that you create to the <doc://com.apple.documentation/documentation/AppStoreConnectAPI/POST-v1-gameCenterMatchmakingQueues> endpoint. Pass the `id` for the rule set in the <doc://com.apple.documentation/documentation/AppStoreConnectAPI/GameCenterMatchmakingQueueCreateRequest/Data-data.dictionary/Relationships-data.dictionary/RuleSet-data.dictionary/Data-data.dictionary> object.

```json
POST /v1/gameCenterMatchmakingQueues
{
    "data": {
        "type": "gameCenterMatchmakingQueues",
        "attributes": {
            "referenceName": "com.example.mygame.SkillBasedRules"
        },
        "relationships": {
            "ruleSet": {
                "data": {
                    "type": "gameCenterMatchmakingRuleSets",
                    "id": "36c540f2-031a-4e35-8260-d0804e40376b"
                }
            }
        }
    }
}
```

### Choose parameters that work best for your game

You can create a matchmaking rule that initially attempts to match players with similar skill values, then after a few seconds, increases the skill range for another period of seconds. The rule repeats the increments at specified intervals until it reaches a maximum difference in skill levels.

For example, if the skill of players ranges from `0` to `100` in your game, create a rule that:

- For the first `10` seconds, tries to find players with an ideal `20` points or less difference in skill level.
- For the next `10` seconds, compromises to find players within `40` points or less difference in skill level.
- After `20` seconds, finds players with no more than the maximum `100` points difference.

You choose the number of increments and the ranges of wait times and skill levels.

### Write an expression that matches players by skill level

Write an expression for a match rule where the expression returns a Boolean value of <doc://com.apple.documentation/documentation/Swift/true> for an acceptable range of skill values that expands at specified time increments. An expression is a JMESPath formatted string with some Game Center matchmaking function additions.

First use the `diff()` function (see <doc://com.apple.documentation/documentation/AppStoreConnectAPI/computing-numeric-differences>) to compute the difference between the maximum and minimum skill values of players, where `skill` is a game-specific property name that you set in your code when you submit a match request.

```json
diff(players[].properties.skill)
```

In a match rule, the requests array contains only compatible matches because Game Center applies compatible and distance rules before match rules.

Then use the `agedValues()` function to return a range of desired skill values depending on the average wait time or age of the requests. Compute the average age of the requests using the `avg()` function.

```json
avg(requests[].secondsInQueue)
```

Pass the average age as the first parameter to the `agedValues()` function and other parameters depending on your game (see <doc://com.apple.documentation/documentation/AppStoreConnectAPI/getting-value-based-on-age-using-an-array>).

For example, if the ideal difference in skill is `20`, pass `20` as the `initialValue` parameter. Then pass an array of age increments as the `ages` parameter (`[ `10`, `20` ]`) and corresponding skill differences as the `values` parameter (`[ `40`, `100` ]`) to the `agedValues()` function.

```json
agedValues(avg(requests[].secondsInQueue), `20`, [ `40`, `100` ], [ `10`, `20` ])
```

Now compose a Boolean expression that compares the maximum difference in skill between compatible requests with the desired difference in skill as a function of wait time.

```json
diff(players[].properties.skill) <= agedValues(avg(requests[].secondsInQueue), `20`, [ `40`, `100` ], [ `10`, `20` ])
```

For more information on the Game Center functions you can use in expressions, see <doc://com.apple.documentation/documentation/AppStoreConnectAPI/expressions> in App Store Connect API.

> Important:
> If you have previous versions of your game that don’t provide player properties used in your rules, you can write expressions that provide default value for those properties. See <doc://com.apple.gamekit/documentation/GameKit/creating-matchmaking-rules-for-backward-compatibility>.

### Create a match rule containing the expression

Create a skill-level rule and add it to the rule set. Pass `MATCH` for the rule `type` field, the skill-level expression, and the rule set, along with other settings, to the <doc://com.apple.documentation/documentation/AppStoreConnectAPI/POST-v1-gameCenterMatchmakingRules> ``endpoint.

```json
POST /v1/gameCenterMatchmakingRules
{
    "data": {
        "type": "gameCenterMatchmakingRules",
        "attributes": {
            "type": "MATCH",
            "description": "Players must have skill in given range",
            "referenceName": "SkillDifference",
            "expression": "diff(players[].properties.skill) <= agedValues(avg(requests[].secondsInQueue), `20`, [ `40`, `100` ], [ `10`, `20` ])"
        },
        "relationships": {
            "ruleSet": {
                "data": {
                    "type": "gameCenterMatchmakingRuleSets",
                    "id": "36c540f2-031a-4e35-8260-d0804e40376b"
                }
            }
        }
    }
}
```

The `description` and `referenceName` fields are specific to your game. In the `relationships` field, pass the `id` for the rule set in the `GameCenterMatchmakingQueueCreateRequest.Data.Relationships.RuleSet.Data` object.

> Note:
> Typically, you add more than one rule to a rule set. For example, add a `COMPATIBLE` rule to check whether the player’s app versions are the same and a `DISTANCE` rule to find players nearby that Game Center applies before `MATCH` rules.

### Submit a skill-level match request

In your code, create a [`GKMatchRequest`](/documentation/GameKit/GKMatchRequest) object that uses the skill-level queue and its set of rules to find players. Set the [`properties`](/documentation/GameKit/GKMatchRequest/properties) and [`queueName`](/documentation/GameKit/GKMatchRequest/queueName) properties of the match request, so that Game Center uses the matchmaking rules to find players.

```swift
// Create a match request.
let request = GKMatchRequest()
```

Set the [`queueName`](/documentation/GameKit/GKMatchRequest/queueName) property to the reference name of the queue that you previously created using the `Create a queue` endpoint.

```swift
// Set the matchmaking rules queue name.
request.queueName = "com.example.mygame.SkillBasedRules"
```

Set [`properties`](/documentation/GameKit/GKMatchRequest/properties) to a dictionary of key-value pairs that provide values you can use in expressions. Add a `skill` key with a value that represents the local player’s skill level.

```swift
// Set properties to the game-specific keys you use in the rules.
let skill = localPlayerData.skill
request.properties = [ "skill": skill]
```

If you set the [`recipients`](/documentation/GameKit/GKMatchRequest/recipients) property, you can also set skill levels for each recipient using the [`recipientProperties`](/documentation/GameKit/GKMatchRequest/recipientProperties) property.

Then submit the match request using the same APIs regardless of whether you configure matchmaking rules. For example, present the [`GKMatchmakerViewController`](/documentation/GameKit/GKMatchmakerViewController) interface or use the [`GKMatchmaker`](/documentation/GameKit/GKMatchmaker) class that finds players using automatch without presenting an interface.

When all the players accept their invitations and GameKit invokes the [`matchmakerViewController(_:didFind:)`](/documentation/GameKit/GKMatchmakerViewControllerDelegate/matchmakerViewController(_:didFind:)) delegate method in the app instances for all players in the game, you can access the skill levels of all the players using the `GKMatch.playerProperties` property.

For more information, see [Finding multiple players for a game](/documentation/GameKit/finding-multiple-players-for-a-game).

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)