# Onboarding funnel for a Roblox game (/docs/guides/onboarding-funnel)

Most players decide in their first few minutes whether to stay. This guide tracks those minutes as a funnel, finds the biggest drop, and checks whether the players who finish onboarding are the ones with good D1 retention. The example is a simulator with a short tutorial.

<Steps>

### Track the steps [#track-the-steps]

Pick the handful of moments every new player should reach, and send one event per step from the server, where the game logic already knows they happened:

| Step | Event | Properties |
| --- | --- | --- |
| Joined | `$session_start` (automatic) | join source, platform |
| Tutorial started | `tutorial_step` | `step = 1` |
| First tool equipped | `tutorial_step` | `step = 2`, `tool` |
| First sale | `tutorial_step` | `step = 3`, `coins` |
| Tutorial done | `tutorial_completed` | `seconds` (time it took) |
| First upgrade bought | `upgrade_bought` | `upgrade`, `cost` |

```luau title="ServerScriptService/Tutorial.server.luau"
local RoChart = require(game.ServerScriptService.RoChart)

local function onStepReached(player, step, props)
  props = props or {}
  props.step = step
  RoChart.track(player, "tutorial_step", props)
end

local function onTutorialDone(player, startedAt)
  RoChart.track(player, "tutorial_completed", { seconds = os.clock() - startedAt })
end
```

One `tutorial_step` event with a `step` property keeps the schema small. Filter on `step` to use each one as a funnel step.

### Build the funnel [#build-the-funnel]

Create a [funnel](/docs/product-analytics/insights#funnels) over the last 14 days, converting within **1 day**:

1. `$session_start`
2. `tutorial_step` where `step = 1`
3. `tutorial_step` where `step = 2`
4. `tutorial_step` where `step = 3`
5. `tutorial_completed`
6. `upgrade_bought`

If the tutorial only runs for new players, the steps after the first are already about new players. To make the first step new players only too, filter the funnel by the **New players** cohort from the step below.

```text title="summary"
$session_start 18,240 → tutorial_step 1 15,902 (87.2%) → tutorial_step 2 13,110 (82.4%) → tutorial_step 3 7,288 (55.6%) → tutorial_completed 6,940 (95.2%) → upgrade_bought 3,105 (44.7%)
Overall conversion 17.0%. Biggest drop-off: tutorial_step 2 → tutorial_step 3 (44.4% lost).
```

Here, nearly half the players who equip their first tool never make a sale. That's the step to fix.

### Break it down [#break-it-down]

Break the funnel down by `$device_type` (platform). If phones drop much more at one step, the problem is often the UI on a small screen, not the game. Break it down by `$join_source` to see whether players who followed a friend get through better than players from discovery.

Segments with fewer than 30 players are stippled: treat them as anecdotes.

### Make a cohort of new players [#make-a-cohort-of-new-players]

"First played in the last 14 days" is easiest in SQL. Save this in the [SQL Editor](/docs/product-analytics/sql) and create a cohort **New players** from it:

```sql
SELECT person_id
FROM events
WHERE event = '$session_start'
GROUP BY person_id
HAVING min(timestamp) >= now() - INTERVAL 14 DAY
```

A rule-based cohort works for the rest, such as **Completed tutorial**: performed `tutorial_completed` at least once. Cohorts work as filters, breakdowns and experiment segments.

### Does onboarding predict retention? [#does-onboarding-predict-retention]

Create a [retention](/docs/product-analytics/insights#retention) insight by **day**: start with `tutorial_completed`, return with `$session_start`. Compare it with the D1 on [Game analytics → Retention](/docs/game-analytics), which counts every new player. If players who finish the tutorial come back much more often, getting more players through it is worth the work.

### Fix it and check [#fix-it-and-check]

Ship the fix, and leave an annotation on the day so everyone knows what changed. Next morning, the funnel and **today so far** on Game analytics already show the first day of new players. If you're not sure the fix is better, [A/B test it](/docs/guides/ab-test) instead.

</Steps>

## A dashboard to start with [#a-dashboard-to-start-with]

Put these on one [dashboard](/docs/product-analytics/dashboards): new players per day, the onboarding funnel, the funnel broken down by platform, D1 retention of players who completed the tutorial, and median `seconds` on `tutorial_completed`. Or ask your agent: *"Build an onboarding dashboard: new players per day, the tutorial funnel by platform, and next-day retention of players who finished the tutorial."*
