Object Serialization For Saving Games On Android Platform

Hi folks.

Concise version: Is loading and saving games using serialization an effective solution on Android?

Full version:

I have spent the last few years of my hobby time writing an RPG game in Java. I now want to port it to Android, and have been reading up on Android development.

My lazy decision when writing the PC game was to implement save games using object serialization. All of a game’s data is under the object “Game”, and is serializable, so saving and loading games was easy. The risk is that a Java update will change the standard objects to the point that I cannot retrieve a saved game, and the player will have to start over. Given the nature of the game (it’s more rogue-like than anything else), this was not a problem.

Moving over to Android, I hope to preserve this approach rather than (finally) have to write toString and fromString methods, or figure out how to put all the data into SQLite. I may use the DB later, but to get started, I am trying to avoid taking on more work - redoing the UI is enough.

So, my question is, in your collective experience, is loading and saving games using serialization an effective solution on Android?

thanks,
Andrew

Java serialization sucks. See Kryo.

Thanks for responding. Could you elaborate on why Java serialization is bad? Is it a question of performance, space consumption, reliability … ?

Every time you update your code your saved files will become incompatible. That is why you should avoid serialization. (In my point of view)
For Android, check my answer here.

I rambled a bit here:

Serialization is fine, Java’s built-in serialization not so much. With Kryo’s TaggedFieldSerializer you get backword compatibility – you can add new fields without breaking old bytes. Instead of removing fields, you just @Deprecated them (and I also usually rename them to ignored1, ignored2, etc).

There are other ways to keep backward and forward compatibility, but they start to impact performance and I’ve found TaggedFieldSerializer is enough for games. When I make a change that is large enough that I can’t evolve the class (which is rare), I write a serializer that transforms the old class to a new class. This consists of simply doing the old deserialization, then writing a method that populates the a new class instance with data from the old class instance.

Saying the answer is shared preferences on Android is just as good as saying the answer is “write to a file” or “write to a database”. This is only sufficient if you want to hand write all your serialization and handle compatibility yourself (hint: you don’t ;)). If hand writing binary serialization, Kryo provides a lot of utility to reduce the effort, so I would still suggest it.

Thanks for the replies - they are very helpful.

I prefer json to save data.
If you are using libgdx you could use their json-implementation.
Otherwise json-lib: http://json-lib.sourceforge.net/index.html

I also wrote the JSON stuff in libgdx. :slight_smile: JSON is often fine, though not fast (so much string manipulation, especially string<->float) or small (floats again aren’t efficient, eg I wouldn’t use JSON for mesh data). It isn’t the best for object serialization for a few reasons. If you have a JSON array, you can’t embed type info, eg if your array is a LinkedList rather than an ArrayList. You’d have to wrap it in an object so you can annotate the concrete type to use for the array. Perhaps the biggest issue is JSON numbers are all floats, so you can have data loss with doubles or longs. libgdx handles this by treating JSON numbers as doubles and longs. libgdx’s automatic JSON<->object serialization works for relatively basic classes (eg it doesn’t allow using a subclass of the known class for collections because it doesn’t wrap the JSON array with an object to annotate the concrete type, as explained above), while Kryo’s works for all and is faster and much smaller. The downside is you can’t read or hand edit Kryo output, though I have not found this to be necessary for most usage.

Xoppa added binary JSON to libgdx which helps in some ways, though writing field names still bloats the size.

I’ve used this so far for saving small amounts of info (scores and what not) and it seems to be alright.

You could try JavaBeans Persistence, although almost nobody uses it.

The best link I could find was this: http://my.safaribooksonline.com/book/programming/java/9780137144488/javabeans-components/ch08lev1sec9

On that note, I recommend that you check out the Core Java 2 books (Volume I and II) if you don’t already have them. Vol. II describes in detail how the Persistence mechanism works.