Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Game Data Persistence Across Devices

I'm still in the very early stages of a game, and I am saving information using a KeyChain wrapper class someone made. I wanted to ask for some advice early on, since I have time to change my approach.

My game has the potential to persist a fair amount of data about the player and what they've done, such as:

  • how much gold the player has
  • what items they've acquired (you can get about 50 items)
  • what skills, spells, and abilities they've chosen for their character
  • what experience level they are, max health, stats, etc

The reason I decided to store this in KeyChain was that I was told it's encrypted and much more difficult to tamper with. I felt there were other solutions such as the ones below, but I wrote some potential reasons why that might not be good:

  1. Make everything web-based, and stored in a database somewhere on my server - I want my game to be playable offline

  2. Use a local database (FMDB, let's say) - I could use a tool to edit the values directly, and give myself more health, etc.

  3. Use Core Data - Never used this before, not sure if this is the same ease of tampering as #3?
  4. GameCenter - Never used this before, so not sure what the lift is
  5. NSPreferences - Preferences are more easily tampered with (i've used a tool to change the values pretty quickly)

So I am not sure if i'm completely wrong above, but let's say there is some degree of truth there and KeyChain is a good approach. The problem is now what if I want to then somehow allow the player to pick up a new device and pick up where they left off? How on earth would I serialize all that data I'm saving in keychain? I don't mind creating a giant JSON document of the values, and sending it along somewhere (where? to GameCenter?)

Any advice / pointers in the right direction would be good, especially now since i'm in the early stages and can make changes to step back.

Thanks so much everyone appreciate your time!

like image 972
NullHypothesis Avatar asked Dec 17 '16 03:12

NullHypothesis


People also ask

How do I sync game progress between Apple devices?

You can use iCloud and Game Center to keep your progress, high scores, and game saves up-to-date across your devices. If you're signed in to the same iCloud and Game Center accounts and download Apple Arcade games from the App Store on all of your devices, you can access your game saves and progress on all of them.

How do I transfer game progress from Android to iPhone?

Set up your iPhone until reaching the “Apps & Data” screen. Choose “Move Data from Android”. On your Android phone, go to “Google Play Store”, download and install the Move to iOS app. Tap on “Continue” on both your Android and iPhone.

What is data persistence in iOS?

Data persistence is the mechanism of storing any type of data to disk so that the same data can be retrieved without being altered when the user opens the app next time. While you could save the same data on a server, in this tutorial we are going to describe all the ways to store data locally in iOS apps.

How do I restore game data on my iPhone?

To do that, go to Settings > Game Center > Apple ID. 2. After you log into Game Center using the right Apple ID and open the game, you'll be prompted to load the existing progress. If you can't recover the lost account with the email you are using now, you might be using the wrong email.


1 Answers

A few thoughts based on lessons learned (usually, "the hard way") that may (or may not) be helpful. :)

I see three requirements in your post: offline play (requiring local storage), data security (which is a massive topic in and of itself) and synchronization.

  • Playable offline:

Thus you need some sort of local storage. Keychain, Core Data, SQL, NSPreferences are all options. I don't know the limitations of the Keychain, so not really sure how suitable it is for continuous read/write of large chunks of data.

  • Data security:

They keychain protects your secrets when you're not logged in, and partitions them between apps. https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html and http://evgenii.com/blog/sharing-keychain-in-ios/ give more details. That should prevent other tools from modifying other app's content on non-jailbroken devices.

Core Data, SQL, et al will be inside your app's container, which makes it harder for other tools to access on non-jailbroken devices. There's a good description here: https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html

NSPreferences doesn't offer any security that I'm aware of. Plus, if they jailbreak the device, they basically have root access on a linux machine and can probably do anything they want.

In today's security world, the mantra is generally, "assume breach." As in, assume if they want in bad enough, they're going to find a way in. Thus you need to think about other layers of defense: partitioning your secrets so compromised secrets have limited value, encryption at rest and encryption in transit. Obfuscating the data before you write it/transmit is therefore another layer of defense (although they may still edit it and you'll have to handle potential garbage values).

You can chase security pretty far down the rabbit hole; you'll have to decide where the cost outweighs the benefit, and/or what risks you intend to defend against.

  • Synchronization across devices:

Thus you need a syncing solution. the iCloud Keychain syncs between devices, so if the keychain meets your storage needs, this probably will meet your sync needs, too. Again, I'm not sure if there are size or frequency-of-update constraints. I haven't used this, but this SO answer gives more info: https://stackoverflow.com/a/32606371/1641444. Based on Apple's docs (https://support.apple.com/en-us/HT204085) it looks like the user does have to enable syncing for this to work.

Otherwise, Apple provides GameCenter and CloudKit. Or you could explore 3rd party options. I've used GameCenter and CloudKit to sync data across devices. CloudKit wins over GameCenter, IMO, no contest.

With GameCenter, you gain multiplayer matchmaking and channels to share data between users. But, you have to adhere specifically to its structure which is IMO both extremely frustrating to work with and limited in functionality. Check the GameCenter and GKTurnBasedMatch tags here on SO for a taste of the problems.

CloudKit is a lower-level solution. It allows you to store a wide variety of data objects in iCloud and "subscribe" to change notifications. All data is contained within a container for the app, and has a "private" (user-specific) section and a public (shared by all users of the app) section. After watching the introductory WWDC videos on CloudKit, I was successfully sync'ing user settings between devices AND different users on different devices in no time. However, if you want some of the multiplayer features of GameCenter, you'll have to build the data model/subscriptions yourself. Since you support offline play, you'd need to save your data to a local storage solution and periodically upload it to iCloud for sync.

Conclusion (aka TL;DR)

So, my opinion is: none of the tools individually meet all three of your requirements, and you'll end up rolling your own solution for at least 1 req, regardless of which option you go for. In my multiplayer game, I'm trusting in Apple's filesystem (containers) to provide sufficient data security, I'm using a local storage option within the app's container, and I'm periodically writing NSData objects to cloudKit for synchronization across devices. I hit my frustration limit with GameCenter and pulled it from my app.

like image 154
Thunk Avatar answered Oct 17 '22 20:10

Thunk