2

I'm making a roguelike game in XNA with procedurally generated levels.

It takes about a second to generate a whole new level but takes about 4 seconds to serialize it and about 8 seconds to deserialize one with my current methods. Also the files are massive (about 10 megs depending on how big the level is)

I serialize like this.

private void SerializeLevel()
{
    string name = Globals.CurrentLevel.LvLSaveString;

    using (Stream stream = new FileStream("SAVES\\"+name+".lvl", FileMode.Create, FileAccess.Write, FileShare.None))
    {
        formatter.Serialize(stream, Globals.CurrentLevel);
        stream.Close();
    }
}

My game engine architecture is basically a load of nested Lists which might go..

Level\Room\Interior\Interiorthing\sprite

This hierarchy is important to maintain for the game/performance. For instance usually only things in the current room are considered for updates and draws.

I want to try something like the Raw Binary formatter shown in this post to improve serialization/deserialization performance

I can just save the ints and floats and bools which correspond to all the positions of/configurations of things and reinstantiate everything when I load a level (which only takes a second)

My question is how do I use this Raw Binary serializer while also maintaining which object is which, what type it is and which nested list it is in. In the example cited OP is just serializing a huge list of ints and every 3rd one is taken as the start of a new coordinate.

I could have a new stream for each different type of thing in each room but that would result in loads of different files (I think) Is there a way to segregate the raw binary stream with some kind of hierarchy? Ie. split it up into different sections pertaining to different rooms and different lists of things?


UPDATE

Ok, one thind that was throwing me off was that in question I reference OP is referring to "manual serialization" as "raw binary serialization" which I couldnt find any info on.

Community
  • 1
  • 1
Guye Incognito
  • 2,726
  • 6
  • 38
  • 72
  • Is `Globals` a static class? – Ivaylo Slavov May 15 '13 at 13:50
  • yes. Its not serialized though – Guye Incognito May 15 '13 at 13:51
  • 1
    It's taking *8* seconds to deserialize 10 megabytes? Something is wrong... – aquinas May 15 '13 at 13:54
  • 1
    you ask about the "raw binary stream", but what you actually seem to be asking about is manual serialization (the accepted answer in the other post is entirely manual serialization). When writing the code manually, then yes of *course* you can break it into any amount of hierarchy etc that you choose - but it is **on you** to do that. – Marc Gravell May 15 '13 at 13:56
  • 2
    Your call to `Stream.Close()` is unnecessary, since you are using a `using` block. – John Willemse May 15 '13 at 13:57
  • 2
    Writing complex serialization code takes time, patience, and lots of debugging; I can't visualize your object model just from your description, but have you tried simply running it through something like protobuf-net? It might just do the job nicely... – Marc Gravell May 15 '13 at 13:57
  • @ aquinas. In the post I reference it is taking him 26 seconds for 20 Mb.. Also some of my 8 seconds (1 second say) is for reinstantiating alll the things, sprites, physics stuff etc. – Guye Incognito May 15 '13 at 14:03
  • @john thx. I wasnt sure about that.whether u need to close before disposing, so I left it in – Guye Incognito May 15 '13 at 14:05
  • @Marc Yeah I dont mind that! :) I am already sort of manually serialzing stuff that is to do with various libraries for physics and lighting which I reckoned would be a nightmare to serialize this way. Basically I am reinsantiating new versions of them when you load the level. Also I think I'm ok now that I know is called "manual serialization" I found an article on that.. OP in other post was calling it "raw serialization". ALso I still have no idea – Guye Incognito May 15 '13 at 14:13
  • contd.. how to split stream into discrete parts but I will read that article – Guye Incognito May 15 '13 at 14:20

1 Answers1

1

If you want to serialize each member of Globals independently, and upon deserialization to manually update the member value, you need to know which member you are currently processing upon deserialization. I can suggest you these:

  • Process items in the same order. The code in your example will put binary data in the stream that it is nearly impossible to extract, unless you deserialize members in the order they have been serialized. This is going to be maintenance hell if new items are added and is not a good solution regarding both code clarity, maintainability and backwards compatibility.

  • Use dictionary. As per comments, Globals appears to be a static class, therefore it itself is not serializable. When serializing, put all members of the Globals class in a dictionary, and serialize it. Upon deserialization, you will know that you have a dictionary (not a random mess of objects). Then from the deserialized dictionary restore the Globals object

  • Use custom class. Create a class with all settings (a better approach). Use a single static instance of the class to access settings. You can serialize and deserialize that class

  • Settings. The second approach gets closer to an already built-in concept in .NET - Settings. Take a look at it, it seems that the Globals class is in fact a custom variant of a settings configuration

Ivaylo Slavov
  • 8,839
  • 12
  • 65
  • 108
  • thx..Sorry if this is unclear in post but I'm not actually serializing Globals. Globals is just where the refernce to the current level in memory is, and I'm serializing the Level object, which is a mainly a LIst of Rooms, which are a List of other things etc. I will have a look at what u said.. Also I think I need to read about "manual serialization" in post I reference its called "raw serialization" which I think is not right and why I couldnt find info about it – Guye Incognito May 15 '13 at 14:31