How we approached the design of our HTML5 game framework

First of all I just wanted to say that the framework we’re working on (which we’ve nick-named Kiwi.js) isn’t just a Photon Storm project. I’m jointly coding it with the super-talented Ross Kettle, and you should definitely check out his blog for some exciting WebGL and Stage3D experiments, including a rather neat Furious Furball demo. We’ve also got the Instinct Entertainment team behind us, providing service and plugin development and community management – and of course once we release it, hopefully you can join in too!

But I just wanted to talk a little about how we’ve approached the design of the framework.

There’s no place like home

I suspect a lot of frameworks are born out of a collection of ‘commonly used’ classes that the developer has in his toolbox. When you start to repeat the way you do things several times over, you naturally start forming common templates and processes that will speed this up for you. There’s nothing wrong with this approach, but it does mean that end-users who come to your framework often have to force themselves to work the same way as you do. And if there’s one thing we’ve identified – it’s that everyone codes differently! 🙂 This is especially true in JavaScript. To some the lack of OOP is a real issue, and they reintroduce it back into JS via external libs. Others really like using jQuery style method chaining and some even wrap their entire game up in one single massive function.

The important thing is that they’re all different, and it was essential to us that we let you code your game in the way you want. So we’re not enforcing specific methods of coding on you when it comes to actually building your game. Internally within the framework we’re doing things in a very set way, and if you wish to get deep and dirty with plugins then you’ll need to follow our lead. But on the outside we’re making it as flexible as possible, so that you can approach the structure in a way you’re familiar with.

Our design is driven by analysing games

This may seem blindingly obvious, but in studying a huge number of frameworks over the years it strikes me that this doesn’t actually happen much! We’re building a game framework, so we want to be sure that the features it has are useful for games.

In order to do this we sat down and went through a huge collection of games – from early Atari video games to modern iOS and console hits, and all kinds in-between. Sports games, RPG, action games, physics games, dungeon brawlers, racing and even Text Adventures. We picked 100 games initially, stripped away the story and drilled down specifically into the game mechanics and what would be required in order to successfully re-create it using our framework. This is a process we continue to do. By dissecting as many games as possible we’re finding lots of common mechanics that are helping prioritise our development roadmap.

Here are some examples:

Space Invaders

You’ve a big group of aliens moving in sync, randomly firing at you. As the invaders fire at you (and you at them) there is pixel-level destruction of the bases. From this simple game it was clear we wanted our Group object to be flexible enough that we could apply a transform component to it, updating invaders at once. Our collision system should be able to support group to group collision and we’d need the ability to dynamically modify the base sprite image at run-time.

Galaxians

Very similar to Space Invaders, we’d take the same group abilities and then add Path support, so the galaxians can follow smooth paths curving down towards the player and shooting at him, rotating slightly as they go. This game would also require a bullet pool and bullet management system.

Smash TV

Requires a massive quantity of sprite updates and collision checks happening every frame. Very large bullet pools with constant object recycling, 8-way movement and firing and all of this supported across two players. Also features large end of level bosses comprised of several sprite segments animating in unison. For us the take-away from Smash TV was the need for careful optimisation of our internal groups, and a means to handle collision on a rapid basis often using very small bounds.

Blasteroids

This bitmap based Asteroids style game would require pre-baked sprite rotation support. Shooting at any angle, inertia, thrusting and velocity. Also everything can wrap at the edge of the camera smoothly. Collision detection is precise and not based on bounding boxes.

Once you’ve gone through a few games you start to spot the common elements, for example:

Gauntlet

Very large scrolling tile map and large quantity of baddies coming from spawn points. These requirements were new, but the 8-way movement and firing, multi player support and large quantity of on-screen baddies was the same as Smash TV. The weapons also have limited ranges (usually just to the screen bounds).

Xenon 2

This classic shoot-em-up features a large vertically scrolling tile map. So we can use a  similar system to the tile map required for Gauntlet, except it has multiple parallax layers to it. More importantly the sprites can ‘dive’ between the layers, swapping collision group as they do so. Again there are a large number of sprites visible and a large bullet pool – with lots of  alien paths,  building on that needed for Galaxians. A simple starfield effect in the background could lend itself well to an optional FX plugin for the framework and it also features an in-game shop and power-up system. While these are not directly framework specific they do open-up the can of worms that is in-game UI and controls.

Shinobi

More tile map action, this time horizontally scrolling. Only you can jump between different layers of the tile map, meaning we need to support one-way collision tiles. The player fights based on key combinations which are often context sensitive (i.e. if you’re close to an enemy you can hit instead of throw a star). The player animation is broken down into parts – legs, body, arms, all linked together in unison. Finally baddies can traverse the map, jumping gaps and jumping down to get you – which lead us to question if a basic AI system ought to be considered from the start.

Operation Wolf

A large scrolling playfield with coordinate and timer triggered events (baddies attacking, helicopters flying on, etc). This sequencing of events became a huge re-occurring requirement the more games we explored. The game is a simple shooter – just point and click. But it has a lot of overlapping sprites, and you only want the sprite at the front to receive the collision, so we’ll need to make sure our collision system can respect sprite depth – and also make sure our sprites can be depth sorted for rendering.

Track and Field

This is a button mashing sports game. It needs precise timed key events, but they are against the game timer, not a ‘real world’ timer. Also the animation speed of the sprites are based entirely on the speed of your key presses, which means our animation playback needs a frame advance feature (or the ability to dynamically set the fps rate). The scrolling speed also requires the same.

Super Sprint

Requires top-down collision detection with irregular shaped track objects. There is car propulsion, driving, skidding, cornering and handling to consider for our motion class. On some levels the track overlaps as well which means the track collision needs to change based on if you are under or above the road. This lead us to consider about swapping between collision layers and paths flowing between layers as well.

StarQuake / Monty Mole / Manic Miner

These are single screen adventure games but set on a map. So the camera needs the ability to snap to a new ‘screen’ within the map but still position all baddies and items locally. The most interesting part of these games however are that you need the ability to reset parts of the map, for example to deal with destroyed tiles or moved items. The original map data must be able to be restored, either all of it or just a part of it. This lead us to consider the fact that our tilemap system should allow you to create a snapshot of the tilemap at any point within your game, and be able to revert back to a previous snapshot as needed. We envisaged having to deal with collision issues, for example if you restored a snapshot that caused the player to become buried in a tile that wasn’t there before, but we explored having options to let the developer deal with this such as ‘kill the object’, ‘move it’ or just return a list of all objects that are effected and let them deal with them on a case-by-case basis.

Zork, Colossal Cave and other Adventure Games

Ignoring the text input and parser for a moment these games all require something we spotted again and again, the more we delved – and that was the sense of mapping game data on an almost room by room basis. In an adventure game you’re literally placed into a ‘room’, it can contain items, exits or other characters and retains its own state. Sometimes things dynamically change (i.e. exits appear based on the state of an object or something in your inventory) but essentially you’re looking at little data buckets for every location.

As we studied more and more games we identified this requirement. In the single-screen games above it was needed to maintain the state of items within each screen, in point-and-click adventure games it was needed in a graphical way. Even in trading games like Elite or tactical games like X-Com you could consider the resources of each planet or sector as ‘rooms’ and the objects within them. It was this that lead us to conclude that some form of game object management was a really high priority. It wasn’t just about the sprites and the particles, but the underlying data the game needed too. So we’re planned in classes to support this: room creation, item placement, inventory and states.

F-16 Combat Pilot and other Flight Sims

Ignoring the 3D side of these games for a moment and you’re dealing with a large scale game world, with object placement within it (buildings, tanks) and the ability to move around in 3D space. This means path finding, movement and collision through 3 axis. Not a trivial requirement to add, but with WebGL firmly planned in the future not something we should ignore either.

Game Mechanics ahoy!

And we literally carried on like this with page after page of games, only a fraction of which are represented in part above. Don’t let the ‘retro’ nature of the games up there put you off – try not to look at them in their original state, but rather look at what they contain inside, what would supporting their mechanics open-up? As we progress with development we’re going to be actively checking-off games from our list and will even milestone points of the framework against them. Rather than just saying ‘the tilemap class is finished’ we’ll be asking ourselves ‘can we now make the map from Sonic?’ and similar.

It’s important to point out that we’re not coding superfluous pieces into the framework just to cater to a subset of games we picked, but that we are identifying mechanics that are globally useful, and implementing those instead. It just seems to make a lot of sense to us to prioritise like this.

 

Posted on July 20th 2012 at 2:54 pm by .
View more posts in HTML5. Follow responses via the RSS 2.0 feed.


30 Responses

Leave a comment

Make yourself heard