The User State

ognd 017

The user state is the unsung hero of game analytics. People spend countless hours looking at dashboards from reporting tables, analysing datasets built from purchases and session events but the user state is only remembered when some vital piece of information about the user wasn’t added to it.

Still the users state is central to a well built analytics system, especially if we are building your own in house.

So what is it? And why does it matter?

What is it?

The user state is table that has one row per each player. It records the last known state of the player variables of interest. A well built user state allows many complex queries to become simple and supports aggregation code, mostly for cohort analysis.

The reason why I want to focus on the user state right after discussing basic events, is because it has a very important support role when building cohort analysis tables.

What does it have?

The simplest set of variables a user state has consist of:

  • User ID: The unique anonymised identifier of a player.
  • Platform: The platform the player uses, for mobile, it stands for the app store, e.g. Apple, Google, Amazon.
  • Country: The player’s country.
  • Acquisition Date: The date of the player’s first session event.
  • Retained Days: The number of days between the player’s last session event and Acquisition Date.
  • Number of Purchases
  • Revenue
  • Number of Sessions
  • Total Session Time

To be totally honest (and as you may know from the Engagement 101 post) I don’t pay a lot of attention to number and time of sessions. However I can’t force myself to remove them and the truth is that both have proven their worth… on analysis, not dashboards.

These are the basics but we can expand from there, step of the Player Lifecycle by step of the Player Lifecycle.

As far as Acquisition goes, if you invest in User Acquisition, then you should find a way to get the player acquisition source into the user state. This will help both the creation of UA dashboards and predictive LTV models.

Retention needs a bit of a different attention. On one hand you might want to track changes in behaviour of the player. Calculating a slope or a correlation of sessions per day and acting on a negative values can be an interesting idea. I never done it but the idea clicked when I heard a podcast and decided to share with you because I’m a nice guy and you’re past 400 words in the post only! Now that’s dedication to game analytics!

Another good use for the user state as far as retention goes is to keep if the player allows notifications to your game. The point to this is to measure the expected impact of push campaigns and make your push notifications systems a tad smarter.

Engagement is (like always!) the most complex part. You’ll want to add information about user behaviour plus some flags you might want to use as predictors in your models. Counts of meaningful interactions with a feature, time spent in a feature, etc.

First time user experience variables are also helpful for both retention and engagement. Flags for tutorial completion and some relevant funnel steps might provide enormous value when segmenting users and modelling their behaviour.

Monetisation is hard for me. Let me give you some possible variables first. Payer segment, last purchase, days since last purchase, counts for purchases per product family and probably there are dozens wondering about. These sound actionable but in truth what I found is that purchases are often skewed towards one particular product or product family which leads for low predictive power. The problem is not the predictive power itself, that can be worked, but rather that each problem needs considerable thought to be solved and often variables are extracted on a case by case basis. So the question ends up being: is it worth it?

Virality is an interesting one. Players that bring their friends to the game are extremely important. Knowing who they are is a must. At the very least a flag that she has invited friends but better than that is to count how many shares were made for instance.

Last but not least, our arch-enemy Churn! This can be a tad tricky. For most setups knowing who churned is not relevant, especially if you won’t be acting on it. But sometimes you run some reengagement campaigns and you will want to know if a given user has returned to the game after churning.

Next week, what can you do with the user state!

5 thoughts on “The User State

  1. Hi, Ricardo

    Awesome post! How would you go about setting a user state table from an events table? Many of us, working in start-ups don’t have the luxury of relying on Dev Ops or Data Engineers. 🙂 So if you had to set it – how would you do it? If you had to use Redshift, lets say.



    • Hi Pavel,

      Sorry for the late reply. We do use Redshift actually! Building a user state from Redshift queries is a matter of creating aggregated data per user. Should be a simple query for Redshift to execute but it will become heavy with a large number of users and sessions.

      How that query would look like depends on how your events are setup. Do you have all events in one table? One table per event?


  2. Hi Ricardo,

    I enjoyed reading your posts on game analytics and find it very practical. I’m currently building our own events library that holds our raw data and would like to hear your thoughts on how we plan to store user state.

    There is one table that holds event data and a separate table to hold user state. I am thinking that it would be valuable to associate event data to the user state at the time of the event.

    So instead of having one row per player for the user state, a player will have a new user state row inserted whenever the user state changes. A event will be associated with one of the historical user state events.

    From your experience, would saving historical user state be helpful?



    • Hi Min,

      Thank you for your kind words. I need to restart writing, it’s been a while.

      In my opinion it is very useful to have the historical user state. However, depending on the size of the game, it can add complexity and cost. To be honest this is the reason why we have not implemented it in Miniclip by the time I’m writing this. We have Omniata though and Omniata supports this in Google BigQuery tables.

      There are three ways of doing this. One is the way you mentioned: one row per user per change. The other is to add the user state information to the actual event which is how Omniata implemented it. The third is an hybrid data model, where you have a “normal” user state with non-changing info (country, acquisition date, date of birth, etc) and then add the changing information either in the events tables or on a log like table you described.

      Best of luck with this, it’s a pretty cool thing to have!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s