Unity games' player preferences on macOS
I’m not a game developer, but after more than a year doing shenanigans at Sound Games, some of my colleagues’ knowledge has somehow transcended the limits of the physical world and travelled toward my office in Vancouver, where I’m now brave enough to spend more time in the Unity editor. I’ve had to learn how to reset the state of a game without making changes to said game and it took me way too long to remember how some of this works from my days building iOS or macOS apps.
TL;DR: Even if the documentation states that PlayerPrefs stores player preferences in a plist file on macOS, this is partially true since it uses the defaults system. If you’re trying to make changes to the state of your game, use defaults write com.company.game key value from your terminal.
For context, we’re working on a game where we store state (last time you did a specific action, the preferred volume for the music, inverting the Y axis on your gamepad like some kind of monster…). Right now we don’t have a “reset to defaults” button which means I couldn’t re-test actions that happen the first time you launch the game, for example. It’s in the work, but apparently even in the world of video games people try to assign priorities to different tasks and prefer working on the more pressing ones first. Weird.
As a result, I started peeking into the source code of the game, harassed my colleagues on the other side of the Atlantic to figure out what we were using and learned about PlayerPrefs which, as the name suggests, stores player’s preferences. Further, as the documentation says, the actual preferences live in a flat file in ~/Library/Preferences/ExampleBundleIdentifier.plist where ExampleBundleIdentifier is your bundle identifier (duh) such as com.mycompany.mysupergame. This was enough to get me going. I grabbed my old and weird friend PlistBuddy that allows you to decode and execute command against a property list file: print content, edit a key, delete it… I should probably have moved to the more modern version, plutil, but that is not here nor there. Also, I forgot it existed until I read the wikipedia page linked earlier.
I ran some PlistBuddy -c "Delete :my-state-key" codes.romain.whatever.plist commands, relaunched the game and… nothing changed. Even worse, the changes I’d made to the file had somehow never happened. After some more digging, asking around and trying to search online for an answer, I brought up the issue with my colleagues and someone mentioned iCloud potentially being the culprit. That’s when it clicked, like a movie where the hero (in this case, me) has a flashback and remembers something from their childhood (in this case, the last time I worked on a macOS app) that will save the day: user defaults.
If you’re not familiar, when making apps for the Apple platforms, there is this simple key value database you can use to store informations within your app. I won’t go into details, but you can access this database on macOS using the defaults command line tool. On a hunch, I typed defaults read com.mycompany.mysupergame and saw the informations I was expecting to tweak, and more. I tried to update some value using defaults write ..., relaunched my game and like a Christmas miracle, the changes were showing up in the game.
What’s the moral of the story? I can think of a couple. First, if you have to use fs_events to watch the changes happening to a file because you’re convinced that a goblin living somewhere in the operating system is modifying that file in secret, you probably need to take a break because you’ve gone too deep. Second, always remember to ask your colleagues, because someone will suggest something that will put you on the right tracks. Lastly, because you’ve only been through the first part of a 27 hours long unity tutorial doesn’t mean you can’t make meaningful contributions to the world of video games. Believe in your dreams.