An Introduction to Mobile Games

If you are an avid mobile gamer like I am, you may already be aware of several ways that mobile game developers take to maximize revenue. For instance, simple arcade games tend to periodically run ads in order to generate users. Another way, more common to complex and robust games, is to create an in-game currency (that is purchasable by real money) that helps the player gain special benefits to improve their gaming experience. For gacha games, they can be used to buy special powerful characters. In other games, it allows players to purchase cosmetics that prettify their gaming experience.

Clean Dataframe
Example of purchasing in-game currency for a mobile game

An Introduction to My Mobile Game

The mobile game that I’m analyzing in particular is a story driven game, where the in-game currency was gems. And the gems were used by players to unlock new story lines that they previously haven’t experienced. A basic storyline is playable by the players for free, but if the player wanted to make more wild and new choices, they had to use gems in order to access those associated storylines. The gems were given to the players for free periodically, but in order to have a meaningful amount of gems, players have to purchase gems with their own money.

Clean Dataframe
Phoenix Wright, an example of a popular story-telling game

The data I had access to were the following csv’s

  • users.csv: User data of the mobile game, including user ID and install date
  • sessions.csv: Session history of each user, including date and session number
  • iaps.csv: Purchase history of users of the mobile game
  • spendevents.csv: Spending and purchase history of users of the mobile game. Includes in-game currency spending and purchase history

As each of the csv’s had different information, the key to this analysis was joining the correct tables in order to receive the most important information.

Maximizing Revenue for Mobile Games

My goal this time around, was to figure out when would be the best time to run an in-app promotion where players could purchase gems at a discounted rate. On a high-level, the timing of when the promotion would run should be specialized for each player (besides common seasonal promotions). The reason being is that for most games, there is usually a buffer time, where players that were already going to spend money would spend money (we’ll label them as payers). So the key is to find the amount of time that payers typically wait before making their first purchase. That way if we run the promotion after this time, then the promotion will be better targeted to normal non-payers, instead of payers, therefore increasing the incremental revenue.

Clean Dataframe
An example of an in-game promotion targeted to players

Merging Tables to Find Promotion Time

After taking a deeper dive into the data with Pandas, I found several interesting findings within the data. In the spendevents.csv, for the amount spend category, they only calculated the spend in gems, not actual currency. So I filtered into two of the spendtypes where players spend money, IAP and valuepack, and joined that table with the sessions.csv so that I could calculate the time duration it took for a player to make their first purchase in the app.

Clean Dataframe

After finding the first session time of each user, I found the average time it takes for a payer to make their first purchase was around 4.5 days.

Clean Dataframe

Since the data was skewed very right, running the promotion after 4.5 days should help increase incremental revenue by targeting non-payers. If the company wants to be safe and add to the time by one standard deviation, they could consider running the promotion after 14.5 days.

Clean Dataframe


So Run the Promotion after 4.5 days… Is that it?

At the very base level, we now know that the timing of when to run the promotion. But if we were to dive even deeper, we should find what are the most important features that influence a player to purchase gems. So after I feature engineered a column that determined if a user was a purchaser or not, I trained and tested a Random Forest Model that found the top features that influenced whether a user purchased gems or not.

Clean Dataframe

As seen in the image above, the most relevant feature is what part of the game they were at when they purchased the gems. This is very important, especially for this particular story driven game, where users can spend gems at key moments during the story to unlock new stories. Therefore, if we were to pinpoint those key moments during the game (i.e., chapter), we can maybe run a different time-based promotion at the time. Or if we found which story caused the most purchases, maybe we do a story specific promotion.

I also had data of users that purchased a value-pack or promotion. Since the data was only for 3-months, there were only 34 unique users who purchased a value-pack and only 1 unique user who only purchased a value-pack (and not gems through the conventional means). If I had access to more data, it might be possible to create a target profile for these value-pack only purchasers in order to create even more targeted campaigns.

There are other interesting features such as hardware version and os version. These probably aren’t as useful as they could be seen as more reflective of the players real world wealth. Language could be another interesting feature to look into, as popular wisdom goes, is that users in some cultures tend to spend more on mobile gaming. I plan to explore deeper into these features in the future.


Link to GitHub repo can be found here