Skip navigation

Category Archives: Games

I’ve never written much about the D language in this blog. I think it could fill many blog posts :).
Let’s just say I’m a huge fan and find it very rewarding to use.

Since 2012 I’ve been working on GFM a library to make it easier to create games and other types of pretty applications.
https://github.com/p0nce/gfm

Obviously it’s only interesting if you are interested in using D in the first place (but I wonder why you wouldn’t be with more information).

I believe GFM to be a reasonably useful toolkit for Windows/Mac/Linux based game development.
It is documented and reached 1.0 last week-end.

With the advent of the dub package manager, it’s only one line away to integrate in your project. You don’t need to use it all, since GFM has been splitted in dub sub-packages.

Advertisements

With a bit of lateness, it is time for a yearly Vibrant update.

Download and changelog are here.

I think I need to apologize to all Vibrant users: over the years I’ve been given quite a lot of feedback but I would not really listen to it. I was chasing my Own Thing ™. Vibrant had this particular gameplay that was so fragile that anything might break it. I would make endless adjustements and tiny changes instead, to keep the things going.

But this time I do not recognize anymore what this gameplay really was and how it felt. I do not even recognize the game, and what it was supposed to be.

I came to the realization I was trapped in a sort of gameplay over-tuning spiral, and that breaking out of the spiral would allow for things a bit more radical to be implemented. And many ideas I suddenly found good had been suggested to me years ago by users. I did just not listen. What was I thinking?

I’ve never did an update for Wormhol, and were asked to open-source it.

So there it is, along with other stuff: http://github.com/p0nce

The license is very liberal.

I wasn’t entirely satisfied with the state I left Vibrant 1.5, so I did a Christmas update.

Highlights of this 1.6 release are the ability to catch ships like powerups, a pause key, and overall a less forgiving gameplay 🙂

Download and changelog here.

Javascript

Disclaimer: this is a technical article without fancy images.


I can’t help but find Javascript spectacularly unsuited to game development.

Think about it: no integers, no 32-bit floating points, overall slowness, uncertainty, and the dynamic side of the langage gets it the way of JIT optimization. When you come from C++ and D it feels like a huge downgrade, and yes I did read Javascript: The Good parts. The features you need are not here while those you can’t use are plenty.

Moreover, the usual guidelines promote a programming style which favors poor performance. The Canvas rendering is slow but physics or AI can quickly become another bottleneck in your game if you rely on best practices.

Luckily you can adapt your code to help the JIT do a better work. This is a domain where I think premature optimization pays off. Using the Firebug profiler I chose to optimize everything in a consistent way.

Note that this performance guide is based on Firefox 3.6 and the optimizations presented here might be specific to this browser.

Objects

Objects worked better for me when created like this:

var C = function(x, y)
{
// initialize members, do stuff
};

Then assigning the prototype:

C.prototype = {
method1: function()
{
// do something
}
method2: function()
{
// do something else
}
};

Edit: it’s not the one true way, see this jsperf test to make your own measurements (thanks @kuvos).

Allocations

The problem with allocating memory is that it stresses the GC and provokes annoyingly long pauses in your game. I mean several frames being skipped where a stable FPS is your goal.

Consequently, there is no single new in the Crajsh game loop. The classic recipes apply: pools, FIFO, stacks, arrays. The pauses sometimes still happen though, because I allocate stuff for each new game.

Note: some operations seem to do hidden allocations, eg. drawing a canvas into another with a different size with Firefox.

Cache members, break encapsulation

I cached properties by hand anywhere possible. Member access is slow in Firefox 3.6 so it’s crucial to get them out of critical loops. If you inline some functions by hand, you’ll be able to cache even more property access. I did so.

I also replaced most of getters by direct member access. If you prefix all members with an _underscore it’s still easy to change a member name. This is less work for the JIT and less code.

Symbolic numerical constants can be replaced by a literal like this:


var a = /* tron.MY_CONSTANT */ 4;

That way you can still grep for it and your code is a bit harder to decipher.

Closures

I don’t understand why, but accessing to a closure (not just creating) introduces a slowdown in Firefox 3.6. The symptom is GC pauses. I’ve worked around the problem by removing all closures from my code. The JIT could theorically optimize closures but it doesn’t happen.

The Prototype.js bind function can help you to eliminate even more closures from your code. I might be wrong but I did see a speed-up.


Function.prototype.bind = function()
{
var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
return function()
{
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
};
};

Arrays

Array literals caused pauses in Firefox 3.6 much like closures and allocations do. It’s sometimes better to have a string literal and then convert it to an array.

I create all arrays with a sufficient size. No resizing happen in the game loop. Then, the bulk of the processing can be done by iterating on arrays, not object properties.

I also think it’s better to use monomorphic parameters and variables. Make sure the JIT know the type of each value where they are used. You’ll see a speed-up if you fill your arrays upfront with the right type, don’t let them undefined.

tl;dr: if you want good performance with Javascript, use a static subset of the language.

Optimizing Crajsh – Part 1 – Rendering

Rendering

Disclaimer: this is a technical article but with some pictures.


HTML logo

Why bother with Canvas?

I tried with Crajsh to make a game that would run on current PC browsers with outdated hardware. Making the game reasonably fast was a design goal from day 1 and I learned a lot about optimizing Javascript and HTMLCanvasElement during the process.

While I had been struggling to make my native OpenGL games work in most of today’s Windows PCs, Crajsh was reported to run correctly on an EeePC and 10 year old laptops.

OpenGL is much work

I went to HTML5 mostly because I got tired with OpenGL drivers out there. The ATI R500 was prematurely abandoned, and some integrated chipsets are still spread in the PC gaming world like a cancer. The stability of OpenGL drivers is not a given and it’s not always safe to direct your users towards the newest drivers with some vendors.

OpenGL development on the PC is frustrating. There is all these fancy features marked supported but you can’t use them because it does not work with card X + driver Y. Problem is: there is a lot of X and a lot of Y to test for. And eventually you can’t plug X and can’t find Y.

What happens next: you end up with multiple rendering paths, ugly work-arounds and uncertainty. OpenGL gives you much work in the real world and I wouldn’t advise anyone to use WebGL until browsers wrap OpenGL ES into software/DirectX where needed.

All of this prepared me to go back to software rendering. Now I think the HTML5 Canvas is suitable for writing cross-platform 2D games, provided you agree to pay the price of optimization.

Know about your users

If your game runs in a browser you can easily get the number of players, for how long do they play, etc…

A good thing is that they will always play the latest version. They are also more likely to update their browsers than display drivers, which is a nice bonus.

Using the CSS engine for UI layout

Implementing a GUI, or adapting an existing one for a game can get pretty complicated. The CSS engine and libraries like jQuery UI makes it straightforward. I suppose localization is easier too since the browser has been thought for that, while with native games it’s notoriously tricky.

When NOT to use the Canvas

  • You want deffered rendering, SSAO, shadow maps, etc… anything fancy
  • You want both high framerates and accurate controls.
  • You want full control over sound, not just playback samples and choose volumes.
  • You don’t want to spend time optimizing.
  • You can’t get yourself to use Javascript.

How to make Canvas fast?

Draw calls with Canvas are known to be slow and there seems to be several ways to work-around this sluginess.

Limit the size of the Canvas

This is what we see in a lot of current HTML5 games. Full updates become possible with a small-enough area. The obvious flaw is that a small game might be less compelling and immersive.

Partial updates

Another solution is to use a larger, screen-sized Canvas and make partial updates. This is suitable to board games, tower-defense, tetris, etc… If you want scrolling you’ll have to complicate the rendering.

Layer several Canvas

This is what some games like Canvas Rider and Biolab Disaster iOS do. The level is prerendered in a big Canvas and the player is drawn in another Canvas with a different z-index. Scrolling is achieved by offsetting the background canvas.

This method use the browser compositor which is likely to be very efficient. It’s probably the most suitable approach for most 2D games: tiled RPG-style games, platformers, scrolling shoot’em ups…

However it wouldn’t work with a few games like Crajsh which have a large tiled-world (up to 1024×1024 tiles) and lots of level updates. In this case maintaining a large Canvas is likely to be slower than maintaining an array of tile indices and a smaller Canvas. Also the memory consumption would be too high.

canvas rider

Canvas Rider

Vector graphics

One technically impressive game recently came to my attention: TankWorld.

Its creator implemented 3D-like rendering in Canvas to avoid WebGL shortcomings. Browsers seem to be efficient with vector graphics, probably thanks to SVG.

I think this is the best current method for 3D games until WebGL is ready. An obstacle to overcome is that browsers have varying abilities at drawing triangles, eg. TankWorld works faster in Chrome.

tankworld

TankWorld


The Crajsh way

My first naive version would draw each tile with a call to drawImage. This was obviously slow so I made the renderer track currently displayed tiles in the Canvas and update tiles as they change. As most of the world is empty blue tiles, I thought it would provide quite a speed-up.

How to render a large, rapidly changing tiled world?


This was indeed faster, but would slow down dangerously in crowded area with lots of non-empty, different tiles.

So I added an optional step which takes the previous Canvas content and offset it to follow the camera movement. This brought more speed and stability. The method works like this:

  1. Copy the main Canvas to an offscreen Canvas
  2. Blit the latter to the former with a drawImage call and the right offset
  3. With this move, 95% of the tiles are drawn in the right position
  4. Update the tiles which actually changed since the last frame (world updates)
  5. Force the update of some tiles to account for floating UI elements, and player animation in the main Canvas

Reusing the last frame leaves few draw calls to be made.


There is more tricks going on. Profiling with Firebug reports that the game bottleneck is the rendering function with less than 1 ms on average, and 10 ms at worst. As the callback is called every 50 ms, a frame skip is pretty rare.

Overall the game runs at a stable 20 FPS, which is not exactly smooth but works with a plain background. In my opinion a low, stable framerate is better than 60 FPS with random pauses in-between. I had a painful trade-off to make between framerate, lagging controls and gameplay. It made the game a bit more difficult that I wanted.


The next article will be about the specifics of Javascript optimization for games.

Optimizing Crajsh – Part 2 – Javascript

Here come more snakes

Yesterday we released Crajsh, a new time-waster from Mars. It was entered to the Mozilla® Game On competition.

It looks like that

A 3 player game.

The music was done by kaneel. I can’t thank him enough because he is easy-going and pleasant to work with. I heard he would be interested in more indie game collaboration.

The logo was done by Graindolium. It’s not his best work pixel-wise but he his on his own projects and I think this will turn out interesting.

This blog post is intended to focus about the game and not the technicalities. That will come later. I know it feels like we released a smaller, easier game that Wormhol was, but in reality it was quite a lot of work to optimize so that it runs smoothly in browsers. The game works in current browsers: Firefox 3.6+, Chrome 8+, Opera 10+, Safari, IE 9 beta.

Note that the development isn’t finished and feedback will be listened.

CRASH

CRASH from Digital Nightmare Games is the original inspiration. It’s an old DOS shareware I used to play with my sisters years ago. I don’t know what the original author is doing nowadays. I wanted to play it again in mid-2010 but it now requires emulation to work. Most of the good ideas come from this game and this is a way to pay respects to the authors.

I think what this game really got right was how limited the available information was to the player. You would pretty much don’t know where you are, where to go, how to reach ennemies… so you would try to make it through from restricted “tunnels” to small areas. This was pretty addictive. Fighting with AI players and trapping them was a lot of fun too, but on their own they would not survive long enough to make courageous strategies valuable. The AI wasn’t really mean enough.

So I tried to improve the AI and so far I’d say it feels like the computer is trying hard to kill you. This is fortunate because I’ve never programmed it this way. Seems like simple rules can do wonders when there is enough of them. At this moment the AI players do not survive as long as they might. Especially they don’t see the urge to shoot in a corridor setting.

A closed world

Like Vibrant and CRASH, you are enclosed in the game world with little time to breath. The map is wrapping: if you make it through a wall you will end up at the opposite point of the map.

There was a bug in the original CRASH about world boundaries. The map would wrap vertically. But if you did make it through the heavy East or West walls you would end up in the dangerous world of computer memory. The game would stop a bit after due to memory corruption. It was like discovering a forbidden area within the game.

Split-screen

Like Wormhol you can play Crajsh with 1 to 3 other players on the same computer. When the game end you get a world view of what happened.

 

world view

You lose. Here is why.

To make the game a bit more varied I included random patterns on the map and powerups. More content to come. As always your feedbacks are very valuable to me.

Now it feels like something finished

I’ve made a rather big update to Vibrant. I hope it will be decisive enough to be the last one.

DOWNLOAD + CHANGELOG HERE

This version fixes lots of annoying things and bring long-wanted features. All this is now listed on the Vibrant site itself (scroll down for the complete changelog).

I’ve also created the Arguably Useful Vibrant Help Page. It’s arguably useful.

I hope you will enjoy this release.

Yet another bugfix  release

Wormhol 1.4 changes:

  • Some people asked for more FPS-like controls. So be it. You can use WASD and your mouse to play the game. Yay! It’s not perfect, maybe A and D should make the ship strafe instead of turn (and one would turn with the mouse). If it doesn’t feel right to you, please tell.
  • Fixed icons in Windows 7. New icon (still ugly though).
  • Fixed ATI HD compatibility.

I’ve discovered a rare “everything gets black” bug yesterday, in a ship-collision. The problem is: I’m pretty confident it’s not introduced by this release. Not sure how I could eliminate a bug which happen once in a year.

EDIT: This release had an annoying bug so I removed the download link. Use 1.5 now.

What’s new

I’ve been lately busy with the Games From Mars website, learning server administrating, javascript and such.

I know, I should have work on Wormhol. But there was a couple of annoying things left in Vibrant that I think deserved a bugfix update. There it is.

>>> DOWNLOAD <<<

Vibrant 1.3 changes:

  • installer: there is a problem when launching the game from the download directory. Nothing happens. The installer now avoids that. If you dislike the idea of an installer let me know.
  • AMD/ATI compatibility: Vibrant should now support all NVIDIA cards, all AMD HD cards and some earlier AMD. The latter are very different from a bug point of view, so it may or may not work.
  • the game fallback in a degraded mode when OpenGL 2.0 is not detected. The game now has been reported to work on an Intel card, which was yet to see, but had problems with some old ATIs. (NOTE: the degraded mode was broken on release but has been fixed)
  • minor gameplay changes: less powerups in high levels, the turbo mode is a bit more powerful and costly, the auto-aiming is now weaker. So it’s harder to aim for newbies, while more rewarding for advanced players. I wan’t Vibrant’s gameplay to be hard and unfriendly, be prepared :).
  • ACHTUNG! The 1.3 version works improperly on ATI HD cards, use the 1.2 version instead.

As always, I would be midly happy to get your bug reports (the auto-generated log.htm file in the game directory) and rants.