Proper storage of consumables (In-app purchases)?

I’m trying to figure out what the best way to store consumable data for a Unity game being sold on say iTunes or Google Play. I want to ensure that between version updates of the application, the data persists as to not aggravate the user and discourage them from wanting to make future consumable purchases.

From what I understand, upon doing some light reading, these seem to be the common (?) ways to store consumable data:

Standard [File] I/O

Pros - Because the information is likely stored in a Persistant Data path, the data should be retrievable even after updating the application (as long as the new application recognizes the file format, which it should).

Cons - Easily (?) modifiable if someone has the ability to access the file. Would require encoding the data somehow as well as validations checks within the game to reduce the chance of the user being able to directly modify consumable data.

[Player Preferences]

Pros - Although external, I believe these values are loaded with the game, so retrieval of the data is likely faster (correct me if I’m wrong).

Cons - The values are stored in variables that can be modified at runtime by hacking tools. Would require some kind of safer version of Player Preferences. I also have no idea if these values will be valid for an updated version of the application.

Online profile / database

Pros - Like Standard File I/O, this would make it such that the user can retrieve their consumable information from say a database. Also, since the data is stored online, the user can only retrieve the amount of each consumable that is logged into the database.

Cons - May require an additional log in to check their consumable status when the player may not have a WiFi connection (this would be okay if the game is an online game, but that isn’t always the case). Requires additional maintenance of player information through a database, which can open a new can of worms in terms of project maintenance for the developer.

Other methods I haven’t thought of or seen used**

Which method would you recommend? Am I missing anything? I’m thinking its going to be Standard File I/O with some protection/validation involved but I’d like to know of any better options if possible, or any other issues I’ll have if I go the Standard File I/O route.

If anyone has any experience with purchasable consumables whatsoever, please let me know if I’m on the right track and/or what method you have used for your game(s).

Typically the best was is via a player profile not stored on the device, associated with an id like facebook or gamecenter. This provides security for you (the developer) and security/storage for the player. Also you may want to double check with AppStore/Play, I believe there are some guidelines about storing iap/consumable content.

1 Like

I haven’t built a local-only IAP rig as all of the projects we’ve done have had an online account system for gameplay - thus, I can’t advise on local solutions (although if you’re not worried about hacking, they should be fairly straightforward).

In a game with online accounts, the IAP flow runs along the lines of:

  1. Login user (Facebook, email/pass, GC/GP, etc)
  2. Allow player to buy IAP item
  3. Apple processes the purchase, and sends app client a receipt
  4. App client sends receipt to your game server
  5. Game server updates the player’s profile with the IAP item according to receipt info (i.e adds coins to player account)
  6. App client updates display according to server response

This can be daunting to achieve if you haven’t done it before or don’t have experience coding/administrating servers, but is a fairly secure way of doing things as the client has no control over what happens (the server controls coin additions, and you can perform receipt validation on server in case player tries to tamper with receipt).

2 Likes

@zombiegorilla You’re absolutely right. I will double-check with the AppStore and Google Play guidelines. So far, the only one I’ve read is iTunes and I may have misinterpreted one of the lines about consumable content.

@flaminghairball So your method is a process where the user is logged into say, Facebook, logged into their Apple account and then communicates with the Game Server based on the receipt info? Does this mean they will need to log in again on the Game Server or do you make generic profiles on the server based on their Device Information?

Also another set of questions

What are some realistic costs for managing user data such as consumables for each players? I’m going to assume that my app wont be extremely popular, but I’ll likely want to have the potential to store 5000 users at the least. I’m also not expecting a lot of bandwidth.

I’m sorry for the nooby questions, I would really like some help on understanding this process a little better.

If you could recommend some articles for me to read to grasp these concepts a little better, I’d very much appreciate it.

Implementation details are up to you - fundamentally, you need:
1a) if you want syncing across devices, you need an ID that a user can use across devices. This can be GameCenter, Google Play, Facebook, email address, or even a combination of these and others.
1b) If you don’t care about syncing across devices, you just need a unique ID per device - this could be the UDID on Android, and an ID on iOS whose name escapes me (some kind of ad id - it’s been a while).
2) A bit of code on your server that will perform validation on receipts you send to the app store

You basically have 3 options for accomplishing this:
1. Homebrew Server (C#, JS, PHP, whatever)
In this scenario, you rent a server and write your code from scratch. You have almost total control over your code, and also total responsibility when your server crashes and your players form a mob outside your door. :wink:

2. Backend-as-a-Service (GameSparks, PlayFab, etc)
In this scenario, (using GameSparks as an example), you would add your IAP items to their portal, import their Unity SDK, and tie into their account integration and IAP systems.
In GamesSparks, on the client side, this looks like:

  1. GSAPI.AuthenticationRequest() (or DeviceAuthenticationRequest if you want to use the device id option mentioned above)
  2. GSAPI.ListVirtualGoodsRequest (downloads your IAP options from the GameSparks server - you can then list these in your GUI)
  3. When the player clicks buy, GSAPI.BuyVirtualGoodsRequest()
  4. GSAPI.IOSBuyGoodsRequest() in order to perform receipt validation (or Android alternative)
  5. GSAPI.ConsumeVirtualGoodRequest() - This is a required step in order to notify iTunes/GP that the transaction has been processed and the goods have been delivered to user (thus, must take place AFTER delivery). GameSparks should do this automagically on server side if they’re crediting player accounts - however their docs are a bit sparse on the topic so you’d want to be careful of this.

3. CloudSpark
Disclosure: as a partner in CloudSpark, my opinion is likely biased, take everything past this point with a grain of salt.
CloudSpark exists on a layer between Homebrew and BaaS - it gives you the flexibility (as well as the dangers) of running your own server but with the scalability and ease of the BaaS.
As CloudSpark is essentially a platform to write code on top of, there is no in-built IAP support - the IAP system exists in the form of “snippets” that you deploy on your CS app platform. In the case of IAP, the process looks much the same as the GameSparks flow (it’s all reporting back to the same iTunes/GP backend). The crucial difference is that all of the IAP code on CloudSpark is programmer-facing, which both makes it easy to change/add functionality, and also shoot yourself in the foot. In addition, it’s all C#, which means germicide will be the same language across server and game (you ARE using C# with Unity, right? Right?)

Summary
I don’t want to be that guy who throws a bunch of tech at you and leaves you with more questions than you started with, so I’ll make it simple:

  1. If your priority is to learn how things work, build your own - there’s no better way to learn than get hopelessly lost in a sea of scary errors.
  2. If your priority is to ship a game, use GameSparks or PlayFab (PlayFab is an offshoot of the tech used in Planetary Annihilation - they should be quite good)
  3. If your priority is to get easy scalability while maintaining control of your code, use CloudSpark (it’s in private beta at the moment, email me for an invite - lincoln@troggy.com). We’re still in early stages, which both means there’s kinks to be worked out, as well as incentive for us to build it to match what you need.

I hope this makes things a bit clearer.

2 Likes

I may end up with choosing GameSparks or PlayFab for my first few apps to gain more involvement and understanding of using popular services. Plus, if I decide to work with an Indie team in the future they’ll likely want to know if I have experience working with either of the API’s of these services as opposed to taking a few months to roll a custom solution that can provide enough functionality to suit their needs.*

With the funding and experience of completing my first few apps with these services, it will be easier for me to have a solid understanding of the Database and Server problem domains.*

That being said, I’m a bit scared of the terms DAU and MAU with 10x aggregate DAU that PlayFab and GameSparks bring up. If I deploy my app as F2P, I will likely have a 0.5-2% turnaround in terms of usage, but I have no idea of what timespan that turnaround will come about. For example, assuming 1000 users are using the app and 0.5% decide to actually buy a $0.99 consumable package within the app, that’s $5… but… $5 in how long, a day? possibly more days? A few hours? I understand that the values are situational but if I use the BaaS I want to be able to fund for it from the app itself. I guess that’s a different problem domain (being loud, marketing and smart advertising).*

Option 3 does sound interesting, and maybe in a few months after learning more about Databases and Server services I’ll ask you for the beta invite. I just don’t want to waste someone’s time by stumbling over the simplest things while trying to use an advanced service.*

You’ll have to decide what’s important to you. I’m not sure what your situation is, so can’t really give you specific advice.

If time-to-market at zero cost is absolutely highest priority, roll a local-only solution and call it a day. If time-to-market at low cost with a fair amount of transaction security is the priority, use a BaaS or CloudSpark and call it a day.

CloudSpark won’t be any more complex from your end than GameSparks or Playfab - it’s just more accessible if you DO decide to get fancy.

PlayFab gives you the first thousand DAU (daily active users) free. That means that you can have up to 1000 players per day without paying them a dime. 5 players/day buying $0.99 of consumables means you’re making ~$430/month (after Apple’s cut).

CloudSpark gives you 1m requests/day free - if you’re running it as an IAP server, that means a heck of a lot of customers giving you money per day.

GameSparks’ first paid tier is $200 at 20,000 MAU - that’s 20,000 * 0.5% * $0.99 = $99 IF you hit the high end of that MAU alllowance. If your expectations prove accurate, that’s not sustainable without another revenue stream, but if you get past 10,000 MAU in the first place, there’s a good chance you can find other ways to monetize (or move to a cheaper platform).

1 Like

You’re absolutely right. I really just need the app to fund itself. I guess everything else is secondary.

I will admit I am under a bit of stress for reasons I can’t disclose and I apologize for the confusion in my last post. I’ll edit the irrelevant parts out.

Ah okay, I was confused about your first description of CloudSpark. I thought it would be more-or-less like using the 1st method mentioned of rolling my own solution but with a heavier requirement to be a bit experienced before using it. What is the pricing like for CloudSpark after the 1m requests/day, and are these unique requests or just total requests (I’m assuming the latter but I figured I’d ask anyways)? I guess I’ll shoot you an email for more information.

And I was more-or-less confused about GameSpark’s 100000 aggregate DAU that they mention with the 10000 MAU… I am under the assumption that they mean if you reach 3334 DAU per day, even though its under 10000 MAU you’re still over the 100000 DAU limit? (Correct me if I’m way off of the mark on this)

3334 DAU * 0.005 players * $0.99 still has you making $16/day, $500/month.

Do you have reason to believe your game is going to blow through a 1,000 DAU cap in the near future? If not, I would save yourself some stress and money and just get the game shipped. :stuck_out_tongue:

1 Like

I honestly don’t think that will happen with the first few games until I improve my skills and make a name for myself on the market.

Sorry about all the questions, I just wanted some guidance on all of this. This is all new to me and I’m going to do some more research, but I’m leaning towards PlayFab with GameSpark being a close contender. I am very curious about CloudSpark and if you want to give me any further information about it via email then by all means please do, I’ve already sent you a message!

Thanks a lot for your assistance so far =)

Very didactic, thank you, I’m looking forward to Gamesparks approach.