The hacking tools introduced in the last blog are very good for modding purposes. In my case, I want to extract pieces of information – in particular, the score – while the game is running. Since I developed the roll-a-ball game in question I have a clue what to look into at this point: PlayerPrefs.
In this blog, I introduce the PlayerPrefs concept.
Key-Value Maps
A key value map (KVM) is a data structure that is ideal for storing data that is used during runtime. A KVM is a collection of key/value pairs: While lists assign indices to their values, KVMs assign keys (which are typically words = strings). KVMs work similar like lists, but look a lot more readable, as shown in Figure 1. (cf. [https://docs.apigee.com])
PlayerPrefs inside Unity
The PlayerPrefs structure works like a key value map. It has one limitation, however: while most key value maps allow any data type to be stored, PlayerPrefs is limited to string, integer and float values. In a script, these values can be loaded and saved at any point, using the included set and get functions (e.g. SetString(„key“, „value“) will save a string value along with its correspondent key). (cf. [https://medium.com])
PlayerPrefs is a great, simple tool for storing non-sensitive user information.
In the Roll-a-ball game, PlayerPrefs were used to store three pieces of data:
- The current score, which is updated whenever points are gained or lost.
- The current highscore, which is only updated when the current score surpasses the current highscore.
- A game over indicator, which resets the game when the goal is reached or the ball felld down.
PlayerPrefs outside Unity
On macOS, PlayerPrefs are stored in ~/Library/Preferences folder, in a file named unity.[company name].[product name].plist (company and product names are like those set in the Project Settings). The same .plist file is used for both Projects run in the Editor and standalone players.
On Windows, PlayerPrefs are stored in the registry under HKCU\Software\[company name]\[product name] key (company and product names are like those set up in Project Settings).
On Linux, PlayerPrefs can be found in ~/.config/unity3d/[CompanyName]/[ProductName] (again, using company and product names as specified as in the settings).
On Windows Store Apps, PlayerPrefs are located in %userprofile%\AppData\Local\Packages\[ProductPackageId]>\LocalState\playerprefs.dat.
On Windows Phone 8, PlayerPrefs can be found in application’s local folder (more information: Directory.localFolder).
On Android, the data is on the device, saved in SharedPreferences. C#/JavaScript, Android Java and Native code are able to access the PlayerPrefs data. Physically, PlayerPrefs data is stored in /data/data/pkg-name/shared_prefs/pkg-name.xml.
On WebGL, PlayerPrefs are stored using the browser’s IndexedDB API.
On iOS, PlayerPrefs are stored in /Library/Preferences/[bundle identifier].plist.
(cf. [https://docs.unity3d.com])
Put into practice: Project Settings can be found in Unity – in this case, the company name is „DefaultCompany“ and the product name is „Reinforcement Learning“, as shown in Figure 2.
Next, executing „regedit“ in the run window that opens after pressing ‚windows key + r‘ opens the registry editor, as shown in Figure 3.
We can conclude that HKCU stands for HKEY_CURRENT_USER, therefore the full path we need to follow is… HKEY_CURRENT_USER\Software\DefaultCompany\Reinforcement Learning. Here, all PlayerPrefs along with some additional data can be found, as shown in Figure 4.
Now that the relevant data was found, it must be somehow extracted. That will be subject of next week’s blog.
Sources
[https://docs.apigee.com]
Working with key value maps: https://docs.apigee.com/api-platform/cache/key-value-maps (28/10/2019)
[https://docs.unity3d.com]
PlayerPrefs: https://docs.unity3d.com/ScriptReference/PlayerPrefs.html (28/10/2019)
[https://medium.com]
Persistent Data Between Scenes: How To Use PlayerPrefs in Unity: https://medium.com/@zachcaceres/persistent-data-between-scenes-how-to-use-playerprefs-in-unity-b6fd409363c3 (28/10/2019)