Mark
Pricing Sign Up
← All posts

How to find which levels players get stuck on

Mike Dalton By Mike Dalton ·

A row of level tiles where one is marked with a warning sign, beside the Game Stats AI logo, with an arrow pointing to a dashboard card showing a bar chart with one short bar.

A level's completion rate is the share of attempts at that level that players finish. A level with a much lower completion rate than the levels around it is where players get stuck, and often where they stop playing.

To show what that looks like, we set up an example puzzle game with eight levels and 120 players across two versions, 1.0.0 and 1.1.0. In version 1.0.0, Level 5 is much harder than the levels around it. Version 1.1.0 makes it easier.

Step 1: Choose a token

Progression events can come from your game client or from a game 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 an event when a level starts

Every time a player starts a level, send a started event to the progression events endpoint. Each start is one attempt, so a player who restarts a level sends another started event:

curl -i -X POST "https://gamestats.ai/api/v1/accounts/$ACCOUNT_ID/progression_events" \
  -H "Authorization: Bearer $GAMESTATS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "player_username": "player_3e8",
    "version_name": "1.0.0",
    "progression_type_name": "level",
    "progression_name": "Level 5",
    "progression_milestone_type_name": "started",
    "progression_milestone_name": "started",
    "started_at": "2026-10-02T14:03:10Z",
    "occurred_at": "2026-10-02T14:03:10Z",
    "time_elapsed": 0
  }'

progression_type_name groups the progressions you want to compare, here every level. progression_name is the level itself, and it is the name the report displays. The report compares milestone types, so use the same two, started and finished, for every level; progression_milestone_name can repeat the type name. started_at marks the start of a new attempt.

A 201 response means the event was accepted. Players, versions, levels, and milestone types are created on first use, so there is nothing to register in advance.

Step 3: Send an event when a level is finished

When the player clears the level, send a finished event for the same player and level, without started_at:

curl -i -X POST "https://gamestats.ai/api/v1/accounts/$ACCOUNT_ID/progression_events" \
  -H "Authorization: Bearer $GAMESTATS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "player_username": "player_3e8",
    "version_name": "1.0.0",
    "progression_type_name": "level",
    "progression_name": "Level 5",
    "progression_milestone_type_name": "finished",
    "progression_milestone_name": "finished",
    "occurred_at": "2026-10-02T14:05:31Z",
    "time_elapsed": 141
  }'

Game Stats AI attaches the event to that player's most recent attempt at the level. time_elapsed is the time since the attempt started, here 141 seconds. Use any unit you like, as long as every event uses the same one.

Send nothing when a player fails or quits a level. An attempt without a finished event counts as not completed.

Step 4: Build a progression report

In Reports > New report, choose Progression report, give it a label, and set Type to level, From to started, and To to finished:

The progression report form with the label Level completion, the type level, From set to started, and To set to finished.

The report shows one row per level, sorted by name so that Level 2 comes before Level 10, with three values:

Value Meaning
Completion Rate The share of attempts that reached finished
Average Time Elapsed The average time between started and finished for finished attempts
# of Instances The number of attempts, including retries

Step 5: Find the level where players get stuck

Pick version 1.0.0 in the report's filters. The chart plots completion rate for each level:

A progression report for version 1.0.0. Level 5 has a 17% completion rate, while the other levels are between 55% and 94%.

In the example game, Level 5 stands out three ways:

  • Its completion rate is 17%, while every other level is between 55% and 94%.
  • It has 99 attempts, more than any other level, because players retried it.
  • Only 19 attempts were made at Level 6. Most players who reached Level 5 never got past it.

The finished attempts also took 141 seconds on average, the longest of any level.

Step 6: Check the fix in the next version

Version 1.1.0 made Level 5 easier. Pick 1.1.0 in the filters to see only attempts made in that version:

The same report for version 1.1.0. Level 5 has a 54% completion rate, and 44 attempts were made at Level 6.

Level 5's completion rate rose from 17% to 54%, and attempts at Level 6 rose from 19 to 44, so more players now reach the rest of the game.

Each attempt belongs to the version in its started event. Select more than one version in the filters to see them combined.

Keep reading

© 2026 Rowhome Labs, LLC