views:

72

answers:

2

I'm building a realtime action multiplayer game in Flash which is using too much bandwidth because it sends message objects as XML (as required by the Smartfox server). I'm now trying to cut down on that by serializing my objects to strings before feeding them to Smartfox.

I've tried JSON but it doesn't help much. Is there another serialization method that is compacter, for example that encodes numbers in Base64 instead of decimals? I don't care about human-readability in this case.

+1  A: 

You can give this a try. Serialize your objects to string using some method you have in place (JSON, XML, etc); then write the string to a ByteArray and compress it. The Base64 encode the compressed bytearray so you can pass it as text.

Other option could be using Flash native serializing format (AMF). This could be done too with a ByteArray, using the methods writeObject and readObject. (You should call registerClassAlias previously if you want to preserve the type information). Once you serialized your data to AMF, base64 encode the bytearray and pass it as text. Not sure if it makes sense to compress it; most likely not, since AMF is already compressed, but you could try both compressed and uncompressed and see if there's a significant difference.

Also, depending on your data, you could hand craft some kind of adhoc compression scheme that cannot be applied in the general case, but this will be more involved and will not neccesarily give the best results. I have a feeling that AMF will be a better option.

Juan Pablo Califano
I'm trying something like that now, using ByteArray.toString() to get a string version, but I'm stuck on turning that string back into a byte array
Bart van Heukelom
@Bart van Heukelom. Use writeUTF and readUTF instead.
Juan Pablo Califano
A: 

Make a serialize/de-serialize method with your own packet structure. Right now you probably have fromXML() and toXML() methods on your models -- now just add serialize() and deserialize() or toByteArray() or fromByteArray(). This will cut down massively on your size, however, there will be a lot more code -- for instance:

public class Ship {

    public var x:Number;
    public var y:Number;

    public function toByteArray() {
        var bytes:ByteArray = new ByteArray();

        // packet length
        // 4 bytes: length of entire packet
        // 4 bytes: x float value
        // 4 bytes: y float value
        bytes.writeUnsignedInt(12);
        bytes.writeFloat(x);
        bytes.writeFloat(y);
    }

    public function fromByteArray(bytes:ByteArray) {

        // we already know the size of our packet, so go ahead and don't read the length
        var length:int  = bytes.readUnsignedInt();

        // read the x/y
        x       = bytes.readFloat();
        y       = bytes.readFloat();

    }
}

I'm assuming you're creating big lists of items to be updated -- you might also want to only send data for items that change. Once you've created your master bytearray, you could compress it at that point, then send it over ...

Daniel Hai
@Daniel Hai. This approach can work, but it's a pain to mantain and scale. If you want to send a number of these objects (and/or different type of objects), you basically will be defining your own custom binary format. I think using an already existent one that you can use almost for free (AMF) is a much better option.
Juan Pablo Califano
He said he wanted it very compact :)
Daniel Hai