Game data · Post 03

The smallest possible analytics stack for an indie iOS game.

Most indie games are either flying blind or drowning in events nobody reads. Here's the smallest stack that still answers the questions you'll actually ask.

There are two ways indie analytics goes wrong, and they look like opposites. The first is no data: you ship, you watch the App Store dashboard, and a month later you know how many people downloaded it and nothing about what they did. The second is too much data: two hundred events, four naming conventions, three tools, and a set of dashboards nobody opens because none of them answer a question anyone is asking.

Both failures have the same root cause. Nobody wrote down the questions first.

Start with four questions, not four tools

For a premium or ad-supported puzzle game, the questions that actually change what you do next week are roughly these:

  • Do people who install it start playing? Install to first meaningful action.
  • Do people who start playing finish something? First session to first completed puzzle.
  • Do people come back? Return rates at day 1, 7 and 30.
  • Where do people quit? Which level, which screen, which step of onboarding.

Everything in the stack below exists to answer those four. If an event doesn't feed one of them, it doesn't get added — not because more data is bad in principle, but because every extra event is a thing that has to be named consistently, kept working across releases, and reasoned about later by someone who has forgotten why it exists.

The event taxonomy fits on an index card

A workable starting taxonomy for a puzzle game is about a dozen events:

  • app_open — with a flag for whether it's the first ever open.
  • onboarding_step — with a step index, so you get a funnel for free.
  • onboarding_complete / onboarding_skipped.
  • level_start — with level id and difficulty band.
  • level_complete — with level id, duration, hints used, undos used.
  • level_abandon — with level id and how far in.
  • hint_used, undo_used.
  • settings_changed — with the setting name, so you learn which accessibility options people actually reach for.
  • rating_prompt_shown / rating_prompt_result.
  • purchase or ad_impression, if either applies.

Two conventions save you months. First, snake_case verbs in the past or present, consistently, forever — mixing LevelStart and level_started means every query becomes an archaeology exercise. Second, properties over event names: one level_complete event with a difficulty property beats easy_level_complete, medium_level_complete and friends, which multiply forever and can't be grouped.

Include an app version property on everything

This is the one property people forget and regret. Without it, you cannot tell whether a metric moved because of your change or because of a mix shift between versions. Every event should carry app version, OS version, and device model at minimum — most SDKs attach these automatically, but verify rather than assume.

One place to look, not three

The temptation is to run a product analytics tool, a game-specific analytics tool and a crash reporter, and check all three. In practice a small studio should have exactly one surface where behavioural questions get answered, plus a crash reporter, which is a different job entirely.

The realistic options for a very small iOS studio:

  • A general product analytics tool (PostHog, Amplitude, Mixpanel and similar) — strong funnels and retention charts out of the box, generous free tiers, and the query model transfers to any other product you build later.
  • A game-specific tool (GameAnalytics and similar) — built-in progression and level-difficulty reporting that you'd otherwise construct by hand, plus benchmark comparisons.
  • Firebase Analytics — free at the scale most indie games operate at, tightly coupled to Remote Config and Crashlytics, but its default reporting is shallow and the good analysis lives in a BigQuery export.

Any of these is a defensible choice. Running two of them is usually a mistake: the numbers will disagree, you will spend a day finding out why, and the answer will be "different session definitions."

The crash reporter is not optional

Crashes are the one thing where a small studio genuinely needs a dedicated tool, because a symbolicated stack trace with device and OS breakdown turns a mystery review into a fifteen-minute fix. Crashlytics is the common default and costs nothing.

Privacy is part of the stack, not paperwork after it

On iOS this materially constrains your design. Anything used for tracking across apps and websites requires the App Tracking Transparency prompt, most people decline it, and your app's privacy nutrition label has to describe what you and every SDK you embed collect. Apple also requires privacy manifests from apps and from third-party SDKs that declare data use and reasons for accessing certain APIs.

The practical consequence for a small game: prefer first-party, aggregate, non-advertising analytics; avoid collecting anything you can't justify in one sentence; and check the privacy manifest of any SDK before you adopt it, because you inherit its disclosures. A smaller stack is genuinely easier to be compliant with, which is a second reason to keep it small.

Three dashboards, and that's the whole thing

With the taxonomy above, the reporting layer is small:

  • Acquisition and activation. New users, install to first level_start, onboarding funnel by step. This tells you whether the first ninety seconds work.
  • Retention. D1/D7/D30 by install cohort, split by app version. This tells you whether the game is worth returning to, and whether a release broke that.
  • Progression. Completion rate and median duration per level, plus abandon rate per level. This is the one that tells you where to change the game.

That third one is the reason to bother with any of this. Retention numbers tell you that something is wrong; a progression chart tells you which level to go fix.

A weekly ritual beats a real-time dashboard

Small studios don't need live data. They need a habit. Once a week, look at the three dashboards in order, write down one sentence about what changed, and pick at most one thing to act on. Most weeks nothing will have changed, and that's a useful finding — it means the last release didn't break anything.

The failure mode of indie analytics isn't missing tooling. It's a set of dashboards that exist and are never opened. A fifteen-minute weekly review with three charts beats an elaborate stack nobody has looked at since launch week.

When to add more

Outgrow this stack deliberately, not by accident. Reasonable triggers: you start running paid acquisition and need per-channel cohorts; you begin A/B testing and need a proper experiment assignment layer; volume grows enough that raw event export into a warehouse becomes cheaper and more flexible than the tool's own UI. Until one of those is actually true, more instrumentation is just more surface area to maintain.

Want clean game data without building a data team?

Send a paragraph about the game and what you're trying to learn from it.