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
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
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
I’ve also knocked up a game/lives/level
set of loops for the main game. Nothing too complicated so far…
No time for code this weekend – got to
go to Essex for a birthday party. I am a very lucky man indeed.
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…
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
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
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…
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
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…
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”
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
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
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…
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
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
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.
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 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 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
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 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 = 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.
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
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 –
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
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!
Here. (It's working again)