Mark
Pricing Sign Up
← All posts

How to compare win rates across maps

Mike Dalton By Mike Dalton ·

A top-down game map with a blue flag and an orange flag beside the Game Stats AI logo, with an arrow pointing to a dashboard card where one bar is taller than the others.

In a game where two sides play different roles, such as attack and defense, a map is balanced when each side wins about half of the matches played on it. A map where one side wins far more often is a map to change.

To show what that looks like, we set up an example team shooter with five maps and 1,600 matches across two versions, 1.0.0 and 1.1.0. In version 1.0.0, a map named Foundry favors the attacking side. Version 1.1.0 changes Foundry to fix that.

Step 1: Choose a token

Match results can come from your game client or from a match server you run. Use a server token if a server sends them, or a client token if the game client does. Create the token in Settings > API tokens, where you also find your account id.

The examples below use curl with both values in environment variables:

export GAMESTATS_TOKEN=your_api_token
export ACCOUNT_ID=your_account_id

Step 2: Send each match with its map and result

When a match ends, send it to the matches endpoint with two match attributes: map, the name of the map, and attack_win, which is 1 if the attacking side won and 0 if the defending side won:

curl -i -X POST "https://gamestats.ai/api/v1/accounts/$ACCOUNT_ID/matches" \
  -H "Authorization: Bearer $GAMESTATS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "match_100_0007",
    "version_name": "1.0.0",
    "match_at": "2026-09-20T21:33:56Z",
    "match_attributes": {"map": "Foundry", "attack_win": 1},
    "match_players": [
      {"username": "player_99d"},
      {"username": "player_ef6"},
      {"username": "player_cd3"},
      {"username": "player_bc2"},
      {"username": "player_55b"},
      {"username": "player_559"}
    ]
  }'

A 201 response means the match was accepted. Players and versions are created on first use. The external_id identifies the match, so sending the same match again updates it instead of counting it twice.

Send map and attack_win in the match's match_attributes, not on the players, because they describe the whole match. A report grouped by a match attribute can only use match attributes in its metrics. A win value on each player would not help here anyway: with teams of equal size, one team wins every match, so the average across all players is 50% on every map.

The average of attack_win across a map's matches is the share of those matches the attacking side won.

Step 3: Build an attribute report

In Reports > New report, choose Attribute report. Set Type to Map Attribute, set Attribute source to Match, and give the report a label:

The attribute report form with the Type set to Map Attribute, the Attribute source set to Match, and the label Map balance.

Then add three match metrics:

Metric type Attribute Label Number format
Average attack_win Attack Win Rate Percentage
Percent of Total None Play Share Percentage
Count None Matches Unformatted

Add Attack Win Rate first: the report's chart plots the first metric. Set its number precision to 1 and check Use for sorting, so the map where attackers win most often is listed first:

The match metric form with Average, the attack_win attribute, the Attack Win Rate label, the Percentage number format, a precision of 1, and Use for sorting checked.

Percent of Total and Count need no attribute. In a report with Match as the attribute source, Play Share is each map's share of all matches, and Matches is the number of matches played on each map.

Step 4: Find the unbalanced map

Pick version 1.0.0 in the report's filters:

An attribute report for version 1.0.0. Foundry has a 68.1% attack win rate, while the other maps are between 50.5% and 53.3%.

In the example game, attackers win 68.1% of the matches on Foundry, while every other map is between 50.5% and 53.3%. Every match in the example has a winner, so defenders on Foundry win the other 31.9%.

Play Share shows that this is not a map players rarely see: Foundry is 20.4% of all matches in 1.0.0, about one match in five.

Step 5: Check the fix in the next version

The report opens filtered to your latest version, and every value shows how much it changed from the version before it:

The same report for version 1.1.0. Foundry has a 50.9% attack win rate, down 17.2 from version 1.0.0, and every map is between 47.6% and 52.5%.

Foundry's attack win rate dropped 17.2 points to 50.9%, and every map is now between 47.6% and 52.5%.

Keep the sample size in mind. Each map has between 122 and 218 matches per version, so a change of a few points, such as Canyon's drop of 4.0 points, can be noise. A large change like Foundry's is a clearer signal. How to balance a game with data shows how many matches you need before a change stands out.

The same approach works for any result you can record as 1 or 0. How to track character win rates in a fighting game uses it to compare characters.

Keep reading

© 2026 Rowhome Labs, LLC