Alpha starting again Saturday 2013-08-24 20:00 CET

Castle Quest is back, with a second alpha phase starting this Saturday 2013-08-24 at 20:00 CET! This time, the alpha will be completely open, so feel free to invite any of your friends to join. You will not need a registration key to play.

After the last alpha phase, we made several big adjustments to the game to respond to the feedback from players. One of the main problems turned out to be longevity: people rushed through the game too quickly, and settled with a particular army composition they were happy with, without experimenting with possibly better compositions. To remedy this, we made several adjustments to the core gameplay:

  • Auras were removed. They were fun the first few levels, but eventually became a brainless chore, as you just replaced your worst aura by the new one. Instead, first hit now depends on the age of the creature (see next point).
  • Creatures are now born as younglings, will age as they fight and will eventually die. An average creature has a lifespan of about 30 battles, and goes through 3 life stages: youngling, adult and veteran. Adults have a higher first hit chance than younglings, and veterans have a higher first hit chance than adults. Thus, the creature age replaces the aura as the mechanic that determines who has the highest chance to attack first in combat. The fact that creatures die also pushes you to experiment with different army compositions. Summoning a creature has also become immediate, and does not require a ritual anymore.
  • Each creature is born with unique DNA. Sometimes, creatures will evolve interesting traits that give them an advantage: creatures might live longer, become a veteran faster, get first hit chance bonuses and so on. If you have summoned a creature with interesting DNA, you can sacrifice it before it dies to preserve the DNA in an amulet, which can be traded with other players. But you can also combine two amulets to create children that inherit the properties of both parents! This way, you can create powerful bloodlines of creatures that can be sold or traded for, and that can really improve your power!
  • Rituals now take a certain time to complete, instead of taking a number of battles. For example, an improvement will take 6 hours. However, when you are online during the ritual, certain events can occur that will allow you to reduce the total ritual time. Also, as a kingdom you can start boosts that further decrease the time needed for a ritual. But whether you use the boosts or not, you will still have to wait a certain amount of time before the ritual finishes.

With these changes, we hope to give the game a much longer lifespan, without annoying players or making the game boring. On one side, rituals take time, so you will not be able to clear the game in a couple of days anymore. On the other side, people who want to play a lot still have plenty to do while waiting for their rituals to finish: they can work on breeding more powerful creatures and can experiment with their army composition.

We hope to see you back in great numbers tomorrow!

Castle Quest Beta Signup!

Castle Quest is nearing alpha/beta release, so we set up a registration form for anyone interested in participating in the alpha/beta of Castle Quest! If you subscribe, we will also keep you up to date on development progress as we near the alpha test. The alpha is currently scheduled for April 2013, and we will be inviting people from this list to participate in it. Be the first to playtest Castle Quest: subscribe now!

Subscribe here!

To whet your appetite, here’s a concept art sketch of the Dragon Nether Creature from the game:

Maximal compression for Websockets

While I was working on a proof-of-concept for a real-time websockets-based browser game, I came upon this curious issue that is packet compression in javascript. Say you have a real-time first person shooter, in which the server has to send a snapshot of the server state to each client 20 times per second. This snapshot will contain the location, direction, weapon etc of each player in the game at that point.

When you compress this using JSON, you get quite a big packet to send every 50ms. JSON is a very comfortable format for sending data, but it is not a very well compressed format. This blog post explains the problem very well in great detail. Eventually, the author proposes to avoid the object hierarchy altogether, instead flattening the data into one single array, which is processed on receival. This does reduce the packet size considerably, as no field names must be stored, but it also makes working with this array very unwieldy, and prone to mistakes.

To solve this issue, I wrote a little library that converts an object hierarchy to a flat array and back again, based on a template. This will only work if your data is highly structured, but this is usually the case for packets that are sent repeatedly. This way, you only once need to define a template of the object hierarchy of your data (including arrays), and can work in your code with the original hierarchy directly, instead of the flat array.

Here is an example application:

    // template
    var template = {
        field1: 0,
        field2: [{
            field21: 0,
            field22: 0,
            field23: {
                field231: 0,
                field232: 0
            }
        }],
        field3: 0
    };

    // data
    var data = {
        field1: 1.0,
        field2: new Array(
            {
                field21: 2.1,
                field22: 2.2,
                field23: {
                    field231: 2.31,
                    field232: 2.32
                }
            },
            {
                field21: 2.1,
                field22: 2.2,
                field23: {
                    field231: 2.31,
                    field232: 2.32
                }
            }
        ),
        field3: 3.0
    };

    // flatten to single array
    console.log(PacketFlattener.flatten(data, template));

    // resulting array: [1, 2, 2.1, 2.2, 2.31, 2.32, 2.1, 2.2, 2.31, 2.32, 3]

So how does this work? PacketFlattener will traverse the entire hierarchy based on the template, and just store the data, not the field names or hierarchy. It will also store the length of the arrays it encounters, as it needs this data to restore the hierarchy later. Below you can find the code that does all this:

window.PacketFlattener = {

    flattenData: function(data, template, array) {
        if (typeof(data) != typeof(template)) {
            console.log("Found mismatch between template type " + typeof(template) + " and data type " + typeof(data) + " during flatten");
        }
        else if (typeof(template) == "number" || typeof(template) == "string" || typeof(template) == "boolean") {
            array.push(data);
        }
        else if (typeof(template) == "object") {
            if (template instanceof Array) {
                array.push(data.length);
                for (var i = 0; i < data.length; ++i) {
                    arguments.callee(data[i], template[0], array);
                }
            }
            else if (template.constructor && template.constructor === Object) {
                for (var key in template) {
                    if (typeof(data[key]) == "undefined") arguments.callee(template[key], template[key], array);
                    else arguments.callee(data[key], template[key], array);
                }
            }
        }
    },

    unflattenData: function(array, template, data, templateKey, dataKey, idx) {
        if (typeof(template[templateKey]) == "number" || typeof(template[templateKey]) == "string" || typeof(template[templateKey]) == "boolean") {
            data[dataKey] = array[idx++];
        }
        else if (typeof(template[templateKey]) == "object") {
            if (template[templateKey] instanceof Array) {
                var n = array[idx++];
                data[dataKey] = new Array();
                data[dataKey].length = n;
                for (var i = 0; i < n; ++i) {
                    idx = arguments.callee(array, template[templateKey], data[dataKey], 0, i, idx);
                }
            }
            else if (template[templateKey].constructor && template[templateKey].constructor === Object) {
                data[dataKey] = {};
                for (var key in template[templateKey]) {
                    idx = arguments.callee(array, template[templateKey], data[dataKey], key, key, idx);
                }
            }
        }
        return idx;
    },

    flatten: function(data, template) {
        var array = [];
        this.flattenData(data, template, array);
        return array;
    },

    unflatten: function(array, template) {
        var container = {};
        this.unflattenData(array, {data: template}, container, "data", "data", 0);
        return container.data;
    }
};

After performing this flattening step, you can still use any compression method to further increase the compression rate. This blog post suggests to use BISON, a compression algorithm that will work best with numbers, as it stores each number as a single-precision character. This makes it the perfect compression buddy for the PacketFlattener! Using BISON after PacketFlattener will result in very concise packets that can comfortably be sent 20 times every second.

Finally, remember that the easiest way to reduce bandwidth is to not have to send any data at all – there are many ways to reduce the amount of data that needs to be sent, such as delta compression. This blog post sums up some ways to further reduce the packet size. These tricks will work fine in conjunction with PacketFlattener.

PacketFlattener can also be found on Github.

Evo Dash released!

We are extremely proud to finally release our first game! Evo Dash is now available on iOS and Android, both for cell phones and tablets. It’s been an incredibly rollercoaster ride from the first prototype made for the Ludum Dare competition of this August to the final release on iOS and Android, and I am very happy with how the game turned out.

Visit the official promo page to buy the game!

If you like the game, do not hesitate to review it on the store, share it with your friends and spread the love! We do not have a big marketing budget so we can use all the help we can get.

Evo Dash!

If you’ve been following our Twitter, this is old news already, but it’s time to make this official with a Blog post on our website. The last month and a half, we have been busy working on a side-project called Evo Dash, as the result of Karel’s entry in the Ludum Dare August 2012 competition. You can play the original web version here.

We are now getting ready to release this game on iPhone and iPad (Android coming later), and we have also released our official trailer:

The original Evo Dash was built on HTML5 canvas, but the new version was ported to Unity, because unfortunately, Canvas is still way too slow nowadays on mobile devices. Unity allows us to use its 3D capabilities to greatly boost the graphics, and also port the game easily to other platforms.

It’s been a great ride so far, and we are very proud of the result! Once Evo Dash is released, we will go back to Castle Quest development of course; we are by no means abandoning the project!

particle systems in canvas

Particle systems are a very cheap and fun way to seriously boost the quality of your graphics. They allow you to create beautiful visual effects, such as explosions, lasers, fire, and so on. The basic idea behind particle systems is very simple: by drawing lots (hundreds or thousands) of very small (a few pixels) squares or circles, which behave individually according to some rules, you can generate a visual effect where the sum of the parts is much more than the parts separately.

For Castle Quest, we implemented a powerful particle system that allows us to make spectacular spell effects. The following movie demonstrates two creatures fighting, using their full array of weaponry to kill the opponent:

Particle systems are used to great effect in most modern-day video games. They are especially suitable to be run on the GPU, since they are the perfect example of highly parallelizable operations: all particles must be updated and drawn according to the same simple algorithm, so the GPU can take full advantage of its parallelization optimizations.

However, HTML5 canvas is not (yet) hardware accelerated, so there are some limits to how much you can do with particles in the browser, even with today’s surprisingly fast javascript engines.

A naive implementation of a particle system could draw a particle on screen with the following code:

var grad = ctx.createRadialGradient(x, y, 0, x, y, size);
var a1 = alpha;
var a2 = alpha - 0.4;
if (a2 &lt; 0.0) a2 = 0.0;
grad.addColorStop(0.0, "rgba(" + r + "," + g + "," + b + ", " + a1 + ")");
grad.addColorStop(0.5, "rgba(" + r + "," + g + "," + b + ", " + a2 + ")");
grad.addColorStop(1.0, "rgba(" + r + "," + g + "," + b + ", 0.0)");
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(x, y, size, 0, 6.2831853, true);
ctx.fill();
ctx.closePath();

This code will draw an arbitrarily sized particle with a given color to the screen as a small circle that becomes transparent near the edge of the circle (to avoid sharp edges).

This works. It’s actually pretty damn fast in Chrome: Chrome can easily render 1000 particles on screen at ~33 FPS. But in Firefox and IE, this method slows down to a crawl. A couple hundred particles will work, but any more will quickly reduce the FPS.

Because we want to at least support 1000 particles on the screen (less affects the quality of the visuals), an alternative approach was needed. It is known that most canvas implementations are faster at blitting images to the screen than rendering shapes, so we can leverage this fact by changing the way the particle system works.

Instead of drawing all particles on screen using paths, we draw all possible combinations of sizes and colors onto a hidden canvas, and just copy the appropriate part of this canvas  to our main screen for each particle. The image to the right shows an example sprite sheet for an explosion.

In order to compare the performance of the three major browsers (Chrome 17, Firefox 11 and Internet Explorer 9), I have generated graphs of the average render time for 100, 1000 and 10000 particles on the three browsers:

Chrome is clearly the winner for this benchmark. In the naive implementation, Chrome is 8 times faster than Firefox and 6 times faster than IE9. For 10000 particles, Firefox crashed once while trying to render them; probably collapsing under their weight, as it took about 6 seconds to render one frame.

At 24FPS, about 41ms of rendering time for one frame is permitted without FPS loss. Note that all three browsers stay far below this for 1000 particles with the improved method. Chrome even almost manages to render 10000 particles at 24FPS, causing only a slight FPS drop. This is quite impressive, as a couple 100 particles are already sufficient to create spectacular particle effects.

With this optimization, the particle system is performant enough to cause no slowdowns on lower-end systems, and in the three major browsers.

HTML5 Canvas animation

One of the major issues with HTML5 game development is the speed of canvas rendering and javascript computation. While browsers have become increasingly performant, there are still some serious limitations to what you can do in a browser in terms of graphics rendering.

One of the most difficult issues to deal with is animation of complex objects. In our case, we are talking about creatures such as the imp depicted here. This shows a creature in an attack animation. The goal is to render tens of these creatures live on screen using HTML5 Canvas.

Two challenges pose themselves when dealing with this issue. Firstly, we want to reduce the bandwidth as much as possible, sending as little information as possible from the server to the client while still rendering high-quality animation. Secondly, we want to be actually able to render the animations in real-time in the browser, even on older systems.

Another problem is that our animator Hanne works in Adobe Flash, using all available functionality of Flash such as inverse kinematics (IK), layers, hierarchies and complex tweens to produce high-quality animations. The creature is split up into lots of small parts (arms, hands, fingers, …) and each part is animated separately in a complex hierarchy. Somehow, these animations have to be exported so that they can be used in HTML5 Canvas directly. There are 3 ways to go about doing this, ranging from extremely demanding for the browser rendering engine and cheap on bandwidth to easy to render but high on bandwidth. We will discuss the pro’s and con’s of each approach next.

Method 1: screenshots

This is the easiest method to code, and the fastest to render. Basically, you take screenshots of the animation every few frames, place them in a sprite sheet and send them to the browser, which draws the different parts of the sprite sheet in the correct order on the screen. Such a sprite sheet would look something like this:

While this method is extremely efficient to render in the browser, its bandwidth usage is often unacceptable. The above image is about 500KB large and the creature is relatively small. Things can quickly add up of lots of sprite sheets are to be displayed on screen. Yet, it doesn’t need any additional software to bridge the gap between the animator (Adobe Flash) and the user.

Method 2: live animation

The other extreme is to export the raw animation data from Flash, and to reconstruct the entire animation live in the browser. Instead of sending multiple screenshots of the same creature in different poses, we now send multiple small images, each containing a small body part of the creature. Then we send all the animation data (translation, scaling, rotation, hierarchy, bones, tween ease details etc) to the browser as well, and we animate the creature in real-time.

This method is extremely bandwidth-efficient. Sending numbers instead of pixels saves a massive amount of bandwidth. One issue might be that sending lots of small images results in a lot of overhead in HTTP requests, but this can be solved by compiling the different components in a spritesheet.

Of course, I didn’t deal with the elephant in the room yet. How do you reconstruct a flash animation in real-time in the browser, if you’re not using Adobe Flash player? This has been a tricky issue. Google Swiffy can read an SWF file and output a data structure that can be embedded in a browser, but it’s not open source and the data structure is a binary blob, which is hard to interpret and animate using your own engine/framework.

That is why I developed Silenus. Silenus is an open-source java library that reads CS5 .FLA files and emulates the Flash animation engine in order to reconstruct the animation in java to the smallest detail. This basically allows you to run flash movies without using flash or flash player.

Silenus takes advantage of the new data format that was adopted by Adobe in Flash CS5. Instead of the original binary format, CS5 .FLA files are now simply zip files with XML files in them. These XML files contain every little detail of the animation, up to the layer you last selected in the editor.

Silenus reads this data and builds a data structure in java that contains everything you need to reconstruct the animation in flash. Additionally, Silenus also reconverts the binary format that flash stores its images in, and creates clean PNG files that are easily portable.

But this still does not fit our problem exactly, as Silenus is a java library, while we need a javascript library to run in the browser. This is doable but tricky, as Silenus uses some pretty advanced computational stuff to emulate the finer stuff in flash. Why didn’t I develop Silenus in javascript to begin with? Because I opted for the third method, which combines the advantages of method 1 and 2.

Method 3: the holy grail (pre-render)

Method 3 combines the advantages of both methods, and produces output that is easy to render and cheap on the bandwidth. Instead of sending the raw animation data, we allow Silenus to compute the final location and orientation of each component for each frame in the animation, and we just send those numbers to the client, along with a spritesheet containing the different bodyparts.

This functionality is available through the RawDataRenderer, which simulates an entire rendering of the animation, and stores the locations of the different bodyparts at each frame, both in a serializable java structure and in json. As with the other approach, Silenus will also produce png’s that you can use in your browser with the rendering engine of your choosing.

To demonstrate that this actually works (and works fast!), Silenus is also available as a web service that allows you to upload an .FLA file and get back the data you need to reproduce your animation anywhere you want! It will also animate your .FLA live in the browser. The Silenus web service computes the final locations of the bodyparts once on the server, and then sends only this information back to the client, which can then render the animation at high speeds.

This method is a little more expensive in terms of bandwidth than method 2. It is also the only method that demands some computation on the server-side, as in both method 1 and 2, the the server only has to send the necessary data to the client. However, since the animation has to be rendered only once and the output can be stored in a database, this becomes a non-issue. And this approach more than makes up for it in rendering speed, while the bandwidth increase is negligible anyway. It’s really the best of both worlds.

A side-by-side comparison of the three methods can be found in the following table:

Conclusions

We proposed three methods for animating complex sprite-based objects in the browser. All these methods assume that the animation was done with Adobe Flash; this is very often the case, as Flash is an excellent tool for producing complex, layered animations. However, the methodology applies to pretty much all animation software.

Silenus brings the third method, which is both low on bandwidth and fast to compute, within reach for every game developer out there. Silenus will help you convert the complex animation data produced by flash into easily readable and compact JSON data, that can be stored in a database and retrieved for live animation in the browser later.

Silenus is an open source project, and contributions are greatly encouraged. More details on distributions, versions and user guides for Silenus can be found on the Google Code page of the project.

First concept art

Due to a few technical problems (mostly involving me not understanding wordpress), I’m posting this today instead of yesterday. But hell, it was my birthday, so I guess I can get away with it ;)

The 4 classes
Just like Castle Quest 2, the new Castle Quest will have 4 different classes. There will be Forest, Death, Air and Earth. The first thing I had to do (aside from designing this overly fancy website) was to find a way to distinguish the different  classes. Karel and me made a document with all our ideas on how the different classes would live, think and look. This will act like a guide and reference throughout the creation of the game. Hopefully our vision regarding each class will change and broaden over time.

Then I created a mood painting for every class. I’m not going to tell you which painting belongs to which class, if you can’t see that for yourself then I guess I didn’t do my job very well. So let me know if you don’t.

The 4 Classes

I tried to separate each class by colour and mood. This was very important because these drawings will determine a great deal of the things I’ll be doing the next couple of months as well as the look and feel of the final game.

Our very first creature
Fire ImpThis is how the first CQ3 creature looks!
This little fellow is called a Fire Imp and is the first in a series of class specific imp creatures.
I tried to make his look very neutral, a little naive and scared but very loyal in a cute way.

The imp is divided in different layers, so it can be animated in a cut out-like way. We are not yet sure of the final height of the creatures so I’m hoping all the details will remain visible in-game.
We also had to think out a universal system for the hitboxes and creature coordinates.
So basically what we did here was the following: we set up all the restrictions and must-haves for future creatures.

Here you can see some sketches along with some colour schemes for the other imps. I won’t tell you what class they represent either. Let your imagination flow ;) . Note that these are just sketches, and can (and probably will) still change while they are fleshed out.

Class specific imps

I definitely want to know what you boys and girls think of the graphics!
And I promise I’ll keep you up-to-date with the animation and the more class specific Imps soon.

Cheers

Sileni Studios founded

On 2012-01-02, Sileni Studios, a new game development studio aimed at producing high-quality browser-based game experiences, was founded in Antwerp, Belgium. The team currently consists of Karel Crombecq (lead designer and programmer) and Hanne Maes (lead artist). This website will contain all important information regarding Sileni Studios and the first game we are developing, called Castle Quest 3.

You can also find us on Facebook and Twitter.