Thursday, 18 February 2016

Skyship Aurora Store Data Tutorial



Sources of custom PlayerPrefs and example how it to use you can DOWNLOAD here:
https://www.dropbox.com/s/2t1jwiwb1zjbl3d/StoringTutorial.zip?dl=0

Common problem of many games is storing data. Scores, health, screen resolution, huge world of Skyrim everything you need to store somewhere or somehow. Unity have buit-in cross platfrom thing called PlayerPrefs, Everything ok with them except they not working on Xbox and you could not save custom data types with them. Of course you can use System.IO for serializing custom classes into a file or upload them on server, but System.IO is not working on Windows Phone. If you dont want to make your code full of #if define symbols mess you need something universal. So what our needs:

1. Class that will store data
2. Able to save/load at any part of the code
3. Working on PC/Console/Webplayer/Mobile

So the only way is to write custom PlayerPrefs that can be serialized into various data structures like xml, binary etc.  Also we need a singleton witch we can access at any part of the code like StoreData.Instance.SetInt("MyInt", 10 ). We need to attach such singleton to a gameobject at very first scene of the game and mark them as DontDestroyOnLoad cuz loading new scene will destroy any gameobject and data associated with them. So at very first scene at Awake function we need to load data for example from Steam cloud ( but as for me I recommend to save data into a file and mark them synchronized with cloud in steamworks panel) , wait til everything will be loaded from xbox storage container etc, then prompt Press any key to continue. Process input and continue the game. At least everything platform related things  will be in one place, so you can control bugs easily and separate game logic from system things. It is a very good idea to separate everything from game logic like input, save/load, achievements etc.

Huge plus of such custom player prefs that you can fast rebuilt game that was madden on PlayerPrefs into you custom PlayerPrefs. I also not recommend to call your custom PlayerPrefs like GamePrefs or anything else with prefix Game cuz in the future you will use GameObject much more often then GamePrefs so you need to switch in class helper in Monodevelop or Visual Studio which not optimal.

One more thing that you will need to know about PlayerPrefs that on xbox you can't use binnary serializer but instead you will need a XML serialization, but keep in mind that xml is much bigger then binary data and saving can take time, BTW you can't save longer then 1 second at xbox otherwise you will not pass Microsoft certification. Often solution is to pack data into zip and serialize it, or completely redesign your game witch is not funny :D

Also if your game is quite big you need to separate configuration like resolution, music volume ( better into .ini file ) from saved world. But for Skyship we have only one save file and it is not so big.

Webplayer often was much more complicated for saving data cuz weplayer policiy deny saving any files on desktop. So the only 2 ways - saving everything on server or use playerprefs. For a small games player prefs is quite ok but for middle size game like Anoxemia or SkyshipAurora it will be not comfortable to use PlayerPrefs for saving everything. Solution is quite tricky:

1.Serialize custom PlayerPrefs into byte array
2. Convert byte array into base64 string
3. Save base64 data string into original PlayerPrefs like PlayerPrefs.SetString( "GameData", mBase64Str ).

Thats it. Ofcourse for big games like MMORPG you will need to store data on server with authorization and things like this.

Into this custom PlayerPrefs you can add custom types of data that you can serialize.

Sources of custom PlayerPrefs and example how it to use you can DOWNLOAD here:
https://www.dropbox.com/s/2t1jwiwb1zjbl3d/StoringTutorial.zip?dl=0