Flax HTML5 Game Engine Development Diary Part 4

First off, I have to apologise. This post is a few days late, and I’m sure that all none of you who hang on my every word were beginning to froth at the mouth. Anyway, in this dev diary is an explanation of our audio system, because I worked on that this week. First, I’m going to explain how we handle files, because that’s pretty cool too.

File Handling

If you know anything about GWT, you know about RPCs. Remote Procedure Calls are magical bits of code that ask a server to do something. Server-side code in GWT is “proper” Java (as opposed to Java compiled into Javascript), so you can do things like use the java.io libraries. This means that we can simply do filehandling on the server, so Flax’d ask the server to create, delete, clear files and the like. Easy, right? I know!

The problem, though, is that these methods are non-blocking. This is, naturally, one of the reasons that AJAX is used. There’s a degree of multi-tasking going on. (Browsers generally limit network connections to two at a time, so it’s a small degree, but a degree regardless)

Non-blocking methods mean that the code doesn’t stop running while the call completes. Here’s the rather big problem with that:

The client could ask the server to create a file asynchronously. Then the client may write to the file. However, the file the server’s been asked to create might not actually exist yet, so your code breaks.

We get around this by using an event system. We were going to use events for other things anyway (like when loading certain parts of the engine, and for in-game things as well), so it was almost trivial to add an onFileLoaded event. I didn’t architect the events system, so I’ll shut up about them before I talk myself into a hole. Ciarán will probably talk about them in his next dev diary.

So, in summary, we read files like so:

  1. The client asks the server to read a file and starts watching for an event, onFileLoadedEvent (we have such awesome names for things).
  2. Once the server has read the file, it fires off an onFileLoadedEvent, which takes the content of the file with it.
  3. The client catches that event and continues doing whatever it was doing with the contents of the file.

It’s cheating a little because we’re sort of blocking the non-blocking methods, but it works.

Audio

Now for the fun stuff.

Flax’s audio, in keeping with the “we don’t need no damn plugins” mentality, doesn’t need any damn plugins. Provided, of course, that you’re using a decent browser with support for the <audio> tag.

Really, what Flax’s audio system does, is take our custom JSON audio objects, convert them into audio tags, and insert them into the page. Then, JSNI methods are used to play or pause separate audio tags.

Audio, as well as many other sections of the engine, is based on JSON objects. Originally, we were going to use XML to do a straight conversion (XML to HTML is rather easy), but we switched to JSON when we got serialisation/de-serialisation working, for consistency’s sake. Besides, doing it this way means it could also conceivably be done programatically (without using JSON files), though not without some work.

Really, it’s a rather simple system. We’ve got an Audio object (accessed statically), which contains play, pause stop, load JSNI methods. We’ve then also got AudioContainer objects, which are used to create and add the html audio tags to the page, and contain things like the tag name, sources, etc. The audio JSON contains a large number of AudioContainer objects, which, when constructed, add themselves to the page.

It’s perhaps not the most straightforward system I’ve ever thought of. However, it’s the fourth time I’ve re-engineered the system, so I’m prepared to forgive myself. If you’ve got any bright ideas about how we should implement audio, I’d love to hear them (because I’m only like 60% happy with this solution).

Sorry for the somewhat rambling post today, college is starting again on Monday and I’m a little preoccupied in getting ready. Never fear, though, Flax development will keep going. A little thing like college won’t stop us.

Previous Development Diaries

  1. Flax HTML5 Game Engine Development Diary Part 1 by Ciarán
  2. Flax HTML5 Game Engine Development Diary Part 2 by Carl
  3. Flax HTML5 Game Engine Development Diary Part 3 by Ciarán

About the Author

Carl Lange

I'm currently a Computer Games Development student at Carlow IT. I love programming and all things technical, and I'll learn anything if it's interesting. I'm passionate about technical education, and naturally about games. Check out my resume, and follow me on Twitter!

Visit Website

8 Comments

  1. Keep up with the good work guyz!

    So I looked at your code, I guess it is here: http://code.google.com/p/flaxengine/. Right?

    In FAudio, I don’t think you will be able to deserialize directly FAudio. Try to create a separate bean containing the audio data and only that, then deserialize the content you receive from the server to this bean. kfuntak added me as contributor on the gwtprojsonserializer project. I can try to help if you have a problem with the serialization.

    In the constructor of FAudioContainer, it looks like you are building the audio tag before setting the list of sources. Bug?

    • Author

      Thank you, Matthias!

      You’re right, that’s our code. We’ve not yet publicised the repo because the engine’s not at a working state yet. Nice detective work. 😉

      Yes, the FAudio and FAudioContainer code is still very much unfinished and buggy as a plague of locusts. I haven’t even yet built a JSON file to test it with. Certainly, the bug in the constructor is one of the stupid mistakes you make when your mind is on other things.

      So if I’m reading you correctly, the solution is to have a JSON file with a large number of FAudioContainer objects, which are constructed (and the tags added to the page, etc) and then destructed/not used again. FAudio itself shouldn’t be serialised/deserialized.

      Makes much more sense to me. Not sure why that code is still there. 😉

      Thanks for the help! Gwtprojsonserializer has made our lives about a thousand times easier, to the point that we mightn’t even have been able to develop Flax without it.

      By the way, out of interest, why wouldn’t I be able to serialise/deserialize FAudio?

      • I believe you would not be able to serialize/derialize FAudio because the library would know how to deal with the other methods… how to serialize an object implementing onFileLoadedEventHandler?

        My advice is to use a simple bean: members, getters and setters only. It is cleaner and it has a better chance to work with gwtprojsonserializer.

  2. Well, second though… The parser should just ignored whatever it cannot be serialized, but I am not sure this is the way it works.

    Otherwise, why are you using JSON? You could use GWT RPC since you have a Java server. I am using JSON serialization only because my server runs in .Net.

    • Author

      We’re using JSON mainly because we need to save our maps etc in some sort of format, and JSON made a lot of sense. For audio, not so much, but because we were already using JSON for the other data, we (well, I) decided to cut corners. It’s still up in the air though. Would more than happily go another way, though I’ve not had the chance to work on Flax in a week or so.

Trackbacks for this post

  1. […] This post was mentioned on Twitter by Nimoy Lissa Khan, Flax.ie. Flax.ie said: Carl finally wrote his dev diary, and explains our filehandling and audio system. http://t.co/NZERjGY […]

  2. […] Flax HTML5 Game Engine Development Diary Part 4 […]

  3. […] documented the old way I did audio in this blog post (co-incidentally, I also talked about file handling there, which, as I said above, we also […]