the robotron diaries like pepys with sprites in
They'll be waiting to cheer
Your life re-lived
 

Introduction
What is there to say about this game that hasn’t already been said? Almost universally lauded as one of the greatest games of all time, a perfect balance of risk and reward, hard but never unfair. But you’ve heard all of that before…

So, in an effort to more fully understand exactly what Robotron does so well, I’m going to try and write a playable version of it.

For the Neo Geo Pocket Color.

In a week.

The idea has several attractions. Firstly, I don’t know whether I can do it and somehow that seems a fitting tribute to the none-more-hard Robotron. Secondly, I’ve been slacking on the NGPC side for a while now and maybe a project like this is what I need to kick me back into it again…

But mainly I’m hoping that trying to recreate the game from the ground up will, perhaps, give me an insight into what makes it so good.

I don’t intend to produce a fully authentic version of Robotron – I won’t, for instance, be spending more time than I absolutely have to on the graphics. And the limitations of the NGPC input mean that I will have to reach some sort of compromise on control.

Friday

Okay, first things first, there’s a whole set of mundane tasks which always define the start of a new project and I won’t dwell on them – suffice to say that, only after a couple of hours, is it time to crack on and put some real code together.

Everything in Robotron lives within a limited 2D plane. There are no exits, no maps, nothing – the “level” is almost irrelevant, the entire game is defined by the characters on screen. All we really need for each character is an X and Y co-ordinate and a few bits of information about it’s type. So, having this basic sprite structure, cobbling together a game setup routine and a bunch of fairly standard stuff (collision detection et al) becomes almost trivial. I’m just populating my arrays with nonsense for the time being but that won’t last long.

I’ve also knocked up a game/lives/level set of loops for the main game. Nothing too complicated so far…

The Weekend

No time for code this weekend – got to go to Essex for a birthday party. I am a very lucky man indeed.

Monday

The basic game structure is in place, so the first step is to populate our game world with a few character blobs, and then to concentrate on giving the player some control over the hero.

But first, I’ve got a little matter of “work” to get finished…

(Later that evening)


Look at that blue circle thing! That’s you that is!

This is my favourite bit of doing a new game, when you first get control of something on screen and you get to move it about a bit. Okay, it doesn’t look like much, but that blue circle and purple slashes on screen are the very essence of Robotron.

All I have to do with the shots now is to destroy them when they hit the border. But I I need a game border in order to do that. Which means that the next job is to setup the basic game environment. Back in a tick…

(Even later…)


See those shots? See ‘em? They go away when they hit the border they do. It’s the little things that matter y’see…

Okay, maybe a bit more than a tick. I was distracted by John Lydon moaning about a wet bed. Look! The player is now restricted by the game boundary, as are the shots - which are recreated after they reach the edge. I’ve had to use more than the four sprites that I originally thought in order to achieve a consistent firing rate – we’re up to six now.

Now, you may think that the difference between using four sprites for the shots and using six is kind of trivial and, to an extent, you’d be right. But one of the reasons why I wanted to do this on the NGPC is that it is limited to a maximum of 64 eight pixel square sprites at any one time. It may seem odd to deliberately limit yourself in this way - after all surely I could do this using DirectX or OpenGL and not have to worry about stuff like this?

But. Working within the limits of the hardware is one of the defining things about Robotron. After all, similar limits would have been (and were) imposed on Eugene and the crew. If I really want to understand the design decisions that make the game what it is, then I need to be similarly restricted. So, faced with this “problem” of having a limited number of sprites, I’m forced to ask myself “What would Eugene do?”

And I don’t have to look very far for the answer. If you look closely at Robotron, you notice that the designers made a very similar decision. In the heat of battle, it may look and feel like you have a hot stream of laser death screaming around the screen, but (and this is very noticable in MAME) at any given time you only have a limited number of discrete shots on screen (I think it maxes out at about eight – it’s hard to count).


Stop counting the bullets and play the bloody game. Who do you think you are? Dirty Harry?

In fact, looking at that screenshot as I am now, I’m now wondering whether to space my shots out a bit further - which might save me a couple of sprites for the Robotrons.

Talking of which…

(More time passes, it’s approaching midnight now… Stoned Love has just cued up on the iPod.)


Yes, those yellow and pink things are supposed to be the evil Robotrons. I did warn you about the graphics.

Getting them on screen (even if half of them are off the edge somewhere) is easy enough, but now comes the fun bit. Getting the little buggers to start to act like the evil Robotrons that they are. A quick run down of Robotron behaviour is in order…

Grunts
Ignoring the spurious acronym, these are the most basic of the Robotrons in terms of movement behaviour. They basically run directly at the players position, regardless of what’s in the way. They start quite slowly but accelerate constantly until they’re careering about in a flock behind the player – the definitive Robotron experience.

Hulks
What, initially, seems to be more complex behaviour does, I think, boil down to “Hulks dick about a bit, randomly changing direction and may or may not home in on the nearest member of the last human family”. I’m really not sure that there is any actual stalking behaviour in the Hulks genetic makeup, but there may be. They only move in horizontal and vertical directions – no diagonals here.

Neither of these behaviours are especially complicated. In fact, it’s hard to see how they could be simpler.

So. Grunts first I think and then it’s probably time to call it a night…


Anyone who has ever played Robotron will recognise this situation…

This is absolutely fantastic! Within twenty minutes I’ve gone from “well, if you squint, you can sort of pretend…” to “Fuck me, this is Robotron”. Twelve lines of code are all that were needed to fully reproduce Grunt behaviour. That’s twelve. The more I look at this, the more clever it becomes – firstly, you don’t need to perform boundary checking for the Grunts. Because they’re following the player (who can’t leave the game area) they are not capable of leaving the game area either. It’s so obviously a trick that you don’t even realise it’s a trick. The other thing is that, because the Grunts are slower than the player, the “flocking” behaviour just happens – you can see it forming in the screenshot above. It’s emergent behaviour at it’s very simplest and very finest.

There are reports of the original development team playing early builds of Robotron, sans firing (which was a late addition to the design by all accounts), just running around levels packed with Grunts and making them crash into things. I can see why – I’ve been doing much the same… It is now 2:30am and I really should think about sleeping…

Tuesday

First things first. Let’s implement the hulk and human family movement types. The human family potter about in much the same way as the Hulks, bouncing off the walls and basically not doing an awful lot in the way of self-preservation.


That is what we in the trade call a “busy” screen…

So far so good. We now have in place most of the basic elements of the core Robotron levels (we’re missing Spheroids and Enforcers at the moment).

But, as you’ll have noticed, I haven’t mentioned killing anything yet. As it stands, the game feels like Robotron (in fact, more than I’d expected at this stage), but the bullets pass harmlessly through the enemy ranks and the Robotrons mob the hero without killing him. A kind of group hug dynamic. So, it’s time for me to wheel out a collision detection strategy, and time for me to ask again – “What would Eugene do?”

The problem, in a nutshell, is this. We have a player (that can be hit by any Robotron – that’s up to about 50 collision tests), the last human family (which can be hit by any Robotron – this could be anywhere up to 600 collision tests depending on how many members of the human family there are on a level) and a number of shots (which can hit any Robotron – about 300 collision tests). We will also, in later levels, have enemy shots to contend with. But I have a sneaky way of dealing with those lined up.

That’s a lot of collisions to calculate in every frame. So what can we do about it?

Well, I suppose the first thing to do is to try and implement some brute force collision checking and then see what effect it has on speed…


Eat hot laser death! Um. Little pink thing…

Ooh. Actually… It seems to cope fairly well – or, at least, it does with my test level (which consists of 10 Grunts, 5 Hulks and 3 members of the Last Human Family). Let’s see how it copes when I start to increase the numbers…

Wednesday

Well, today has been interesting…

Haven’t really had much time to spare today, what with two client-visits in different counties plus a few drinkies in the evening, but a few snatched moments on the train have, at the very least, allowed me to put a proper level structure in place.

A Robotron level can easily, and completely, be categorised by the number of each type of Robotron that it contains. The first level contains a dozen or so Grunts and one of each member of the Last Human Family, the second contains a few more Grunts, half a dozen Hulks and one single Spheroid, the third contains four spheroids, even more Grunts and a good few Hulks and so on.

Having implemented a level description structure, my NGPC Robotron is now functionally complete. Yay me!


Looks great – slow as anything though…

But, as expected, the additional demands on the collision detection method made by increasing the number of Robotrons to around the 50 mark start bringing the game to a grinding halt. So, what does this tell us about Robotron?

Simply this – a brute force collision detection strategy just won’t work. There are far too many things happening and interacting on screen at once to effectively deal with them all, all of the time. So, we have to try and apply some intelligence to our collision detection.

Firstly, it only makes sense to test collisions for objects which are close to each other. Why should we waste precious time testing for collision between a shot on the left of the screen and a Robotron on the right. So, by dividing the screen into (slightly) overlapping areas, we can narrow down the sheer volume of collision tests required by only testing those collisions which occur within each area – a bit like when your Grandad told you what “back to square one” really meant.

The other tactic worth pursuing is that not all collisions need to be tested in every frame. Because collisions occur on a sub-pixel basis, any two colliding objects will remain in a “collision” state for several frames. This is especially obvious when playing the original in the Hulk/Family collisions – it is, quite often, possible to steal a family member from underneath a Hulk. A surefire sign that some form of selective collision detection is going on under the surface.

These are both classic coding tricks – the first is that, given an arbitary list of data to process, it is almost always faster to sort your data first. The second one is more subtle, but it basically boils down to ensuring that critical tests (in this case collisions between the player and the Robotrons) are always performed while less critical tests (collisions between the Robotrons and the family) can be done in slower time.

Could this be why the family, and those Robotrons who hunt the family, all move relatively slowly compared to all other characters in the game? I think so – it simply gives more time for the game to calculate the collisions between them.

Thursday

My time today will be spent trying to fully implement the collision strategy as outlined yesterday. If I manage to solve the issues surrounding that by lunchtime then, and only then will I have a chance to look into implementing the remaining Robotron behaviours before the deadline looms large.

But first! I’ve got to find out why I have a rogue sprite! When I start the second level, I get one sprite which decides to start behaving oddly. I must be exceeding my sprite limites somewhere…

I don’t really have (nor did I expect to have) much time to devote to the other Robotrons, but in essence we’re just implementing them in much the same way as we did for the Hulks and Grunts. Here are my thoughts on how each type might work…

Spheroids
Spheroids are like Hulks – squared. They zip about the screen in eight directions at high speed, bouncing off the walls, changing tack at a moments’ notice and generally being a pain. But their worst habit is that they drop off Enforcers on the way…

Enforcers
Enforcers are odd. They alternate between a basic Grunt-like chasing behaviour and a go-off-and-hide-in-the-corner-and-shoot behaviour. It’s this last habit of shooting vaguely homing shots at the player that truly makes them evil. Individually they pose no great threat, but collectively they’re a major pain in the bum.

Brains
Brains are the real oddities among the Robotrons. They’re the only ones to exhibit any real intelligence, hunting down the last human family (disregarding the famous “where’s Mikey” bug). I would implement the searching behaviour as an extension to the collision detection method outlined above – determine which humans are in the same box as the current brain and then move towards them.

Quarks
Quarks have a similar movement pattern to the Spheroids, although they only move in diagonals. Again, not deadly in and of themselves, but more for their spawn…

Tanks
Tanks = Complete cunts.

I have a strategy, which I suspect I won’t have time to implement, for dealing with the spawned Robotron types (and their shots). I have a fixed number of Robotrons which my engine can physically support (56) – I just cannot have any more than this on the screen at once. So, as the player shoots Grunts, I intend to reuse the slot vacated by the newly deceased Robotron and populate it with either a spawned Enforcer or Tank, or with a shot. Effectively making Enforcer and Tank shots a new type of Robotron. The rate of attrition of enemies should ensure that some spare slots are always available for newly spawned Robotrons – unfortunately, my Robotron playing skills are not sufficient to test whether this is a tactic that the original uses.

Conclusions

Okay, it’s hardly the most complete game you’ve ever seen, and there is a lot of work left to do to turn it into a finished product, but I’m very very pleased with it. Even in the half-completed state that I’ve managed to pull together over the last few days – it feels like Robotron.

So, has this exercise taught me anything about why Robotron is so good? I think so. Robotron’s greatness lies in it’s inherent simplicity. It doesn’t try and obscure the behaviour of bosses behind half-hidden rules, it doesn’t rely on pattern recognition or Ikarugaesque play by rote, it is completely transparent in everything it does. Everything that you need to know in order to play the game is shown to you from the offset. There is no sleight of hand herein. Grunts behave in a simple, easy to understand, fashion. As do Hulks, Spheroids, Brains and the rest. But the mixture of these, individually easy to understand, characters provides endless complexity.

I am, more than anything, reminded of that other game defined entirely by the behaviour of six characters – Chess.

Notes about the source and playing the game

Source code is available here – feel free to download it, laugh and point and otherwise do whatever you want with it. It’s not really designed for prettiness, but you should be able to follow it by cross-referring back to here. Main.c is the main game loop, but all of the hard work is done in Robotron.c – all other source files are the standard NGPC libraries – albeit slightly modified ones.

If you want to see what I came up with in the week, then you’ll need ROBOTRON.NGP and a NGPC emulator (or the real thing and a flash cart of course). For emulation purposes I recommend NeoPop http://neopop.emuxhaven.net/ for Windows users and NeoPocott http://neopocott.emuunlim.com/ for other platforms. I have only implemented four levels, once you beat those (and they’re not difficult) the game will crash in a heap – you have been warned!

AHCHAY, February 2004.

Comment Here. (It's working again)

They'll be waiting to cheer


 


© 2003 Smart Circle Limited