Unity Web Player, Cookies, and saving player data...
Hello everyone,
I was hoping you fine folks could help me out a bit. I am trying to find a reliable way to store (persistant)user date while using the Unity Web Player. I know a little about Player Prefs but that doesn't seem to be a good solution to storing a lot of data. I basically want to store things like the levels the player has unlocked as well as weapons and other unlockable stuff.
I was thinking about saving files to the local machine(can apparently be done with some javascript wizadry), or maybe using cookies, though I'm not even sure how cookies work.
Has anyone done something similar that could give me some advice or point me to some good articles I can read?
Thanks and happy new year! :D
I was hoping you fine folks could help me out a bit. I am trying to find a reliable way to store (persistant)user date while using the Unity Web Player. I know a little about Player Prefs but that doesn't seem to be a good solution to storing a lot of data. I basically want to store things like the levels the player has unlocked as well as weapons and other unlockable stuff.
I was thinking about saving files to the local machine(can apparently be done with some javascript wizadry), or maybe using cookies, though I'm not even sure how cookies work.
Has anyone done something similar that could give me some advice or point me to some good articles I can read?
Thanks and happy new year! :D
Comments
Are you looking to store session-type data, like progress in a game that players are going to restart often (think of an arcade shmup, for instance) or are you wanting to store longer-term data that players will be annoyed about losing?
I mainly ask because cookies and player prefs (which both let you store similar amounts of data, nothing too huge) tend to be relatively transitory, so I wouldn't rely on those if you had important player progress to store. The most reliable storage is always going to be in your own server-side database, provided you've got a website to keep that on. Unity's built-in web queries are pretty solid, we use those for all DD's data passing between our server and the individual clients.
For DD we store player profiles, savegames and debug info (crash messages, event data) in a couple of databases on our main server. We use player prefs to store the username that a player last logged in with ;) (Always always always use good password security practices if you're asking players to log in, it's not difficult and will save you time later, trust me)
I would imagine that the cookie route would require the Unity plugin talking to some custom Javascript you've got waiting on the webpage that's serving the game. So that's probably going to be a related hassle.
I want to store the weapons/upgrades that the players purchase in game, so it's not really anything complex. Just a lot of bits to set to 1 or 0. I'm also trying to get away with something I don't have to pay for, which excludes the server side DB. :/
Working with player prefs for lots of different choices felt really clunky to me. I don't know if I was just messing up, but it doesn't seem to be designed to store a lot of information. Rather specific things the user last used...like the the last username.
I read up some more about cookies and I'm afraid of using them because it seems that they have a limited time to live. Which is not ideal.
So all in all it seems like I'm pretty screwed :P I either need some clever way to encode my data so I can use the player preferences to better effect, or I need to fork out the cash for some server side functionality. :D
What we do is keep our save-data in a Serializable class (the fields are variables containing Serializable instances of the various different things we save, PlayerSaveData, List<MonsterSaveData>, etc.), we serialise the entire thing to an XML string, and dump it in PlayerPrefs. For about 500 KB - 2 MB there is a split-second stutter on iPhone, and none on PC / web (on my machine).
There are quite a few arguments against XML... all I can say is it worked well for us.
One caveat: it has happened to me three times (on different projects) that an error is reported that make me think that List<T> is (suddenly) not serializable (and every time I only remember it once we found the problem). In each case it was a variable in T that was not serializable (sometimes a variable in a variable...).
Another one: dictionaries are not serializable. I usually convert a dictionary to two coupled Lists for saving.
@hermantulleken, is the XmlSerlializer something built into unity? I read somewhere, that the built in xml parser usually adds about 5MB to the file size. I was wondering if this was your experience as well?
Thanks for the responses guys. I Appreciate it. :)
A web version that uses the serializer with basically nothing else builds to ~300 KB.
Without the serializer, about ~12 KB.
PC with serializer 20.3 MB.
PC without 17.8 MB.
(Cannot test iOS so quickly, but my gut is that the difference will be larger, although percentage-wise less or the same).
For PC it works with the .Net 2.0 Subset; for web the API compatibility is fixed at WebPlayer Subset.
In my experience (though experiences may differ) PlayerPrefs saved by the Webplayer have been as transient as operating systems (as in I lose PlayerPrefs when I reinstall Windows or MacOsX). So about as transient as a game on a harddrive storing data locally (which of course isn't permanent enough for some games, but plenty permanent for many).
If you're concerned about publishing and selling the game (at which point users will be more precious about their saves) then you might end up integrating with the IOS Cloud or the Steam Cloud anyway. So whatever solution you use now might in itself be transient.
It just felt messy to use for lots of little values. I think PlayerPrefs was designed to store "recent" information, things that don't change often and have a limited set of variations. So my first approach at using playerPrefs was really bad. If I plan a bit better how I'm going to use it, I'm sure it'll be fine.
As far as the transience(is that a word?) goes...it shoulnd't really be a problem. I sometimes get stuck on insignificant details. Which is why I want to make more threads like this so people can just tell me that I'm being an idiot and I need to move on :P
@hermantulleken, thank you for doing those test. It's good to see some numbers that show the contrary to what I thought :)
I consistently eschew the least amount of effort to get anything working fast (and to then deal with the fallout later if the game actually turns out well and needs to be improved). So you can take that into account whenever I (perhaps misguidedly) give programming feedback :P
Any feedback is always appreciated, even if it might be misguided. :P It sometimes really good to get another perspective, especially if the other perspective doesn't value the things your own does as much as you do. That way you can get some interesting new avenues to explore(maybe).