Rainbow Islands

Introduction

The 1987 Taito coin-op Rainbow Islands is a very cute game. It`s the follow-up to Bubble Bobble, and features a little character "Bub", in dungarees, who is trying to free all of his friends who have been changed into monsters. In 2-player mode, the second player is "Bob".


 
Just so you know, here is a spoiler alert: there are game facts that you might not know, below.
 

Conversion to Home Computers

In 1989 Graftgold were invited to convert this game to 5 home computer formats: Commodore 64, ZX Spectrum, Amstrad CPC, Atari ST and Commodore Amiga. Telecomsoft had bought the conversion rights, at least for the UK, maybe more. At that time there were 7 of us and we had an office above a fruit and veg store, with very uneven floors, and an iron staircase for access.
 
We agreed to do the job, for a fixed sum, based on getting the arcade machine and source graphics and documentation from Taito. The job, we reckoned, would take about 9 months and milestones were assigned, based on our knowledge of the game and that it showed 7 islands on the start screen.
 

First Problem

Remembering that we had a first floor office and an iron staircase at the back, more of a fire escape really, we first had to get the arcade machine up those stairs. That took all of us dragging this monster upright arcade cabinet up the stairs rather slowly, and likely quite dangerously. These cabinets are made of 3/4" chipboard, and contain all of the workings of an old CRT TV, and more. The jammer board is the size of a PC mo-bo.
 

5 Skus

This game took the whole team:
John Cumming took charge of the maps and graphics,
Gary Foreman did the C64 version,
David O'Connor did the ZX Spectrum and Amstrad CPC versions,
Jason Page did the 16-bit and C64 sounds,
Steve Turner did the management and the Z80 8-bit sounds,
Dominic Robinson did the technical design and support,
I did the 16-bit versions.
 

What we got from Taito

Taito sent us sheets of graphics on disk. We got background character sets and sprite images for each island, plus the resident graphics for the rainbows, fruits and the main character. On the arcade machine these would be displayed by the sprite chip, probably in 8x8 blocks of pixels ganged together as required. We knew that the arcade machine had more colours available to it than we had, so John had to figure out the best 16-colour palette to use that would let us display the rainbows, gems and fruit on any level, and still give us a couple of extra custom colours for each level. We would then have to map the original graphics into our palettes and tidy up any colour discrepancies.
 
We did notice that there were some graphics frames that we hadn't seen in the game, especially for Bub and Bob. There were some frames where Bub`s legs were arranged in a surfing pose as he slid round the rainbows. There was another sequence where he took off his shirt to reveal a Superman outfit. We reckoned that was for his invincibility mode. Since he's also invincible for 2 seconds after appearing, shown by him glowing (I won`t say "flashing"!) then they already had a way of showing that. Also likely DC would have pounced on them. They later got us to write a new tune for the US release because the original tune sounded a bit too much like "Somewhere Over the Rainbow", enough for someone to hold out their hand, anyway. Wonder what the arcade machine had on it in the US?
 
John wrote a mapper using STOS, an Atari ST enhanced BASIC environment, so that he could make up the backgrounds using the background tiles they supplied and we had mapped to our palette. One Friday night we got David to play the game the whole way through. He was our sharpest arcade player. We used to watch him play various games in awe at his reaction speed. We videoed him playing the game. By this time we had discovered that the game had a "bad" ending after island 7, i.e. well done but you didn`t do it quite right. We needed that on video too, so he played it wrong, then followed the advice given in the ending to play it right. Imagine our surprise then when he got to the end of island 7 and 3 more secret islands rose up out of the water. We were expecting just a different ending.


 
The 3 new islands were also the tallest yet, and the Dragon Island 7 levels are pretty tall. Plus, the ninth island had a more modern graphics style of one of their other games, with loads more colours in the background and sprites that we couldn't possibly map down into our 16 colours total. There was also another bad ending if you didn`t play the last 3 islands satisfactorily, plus the proper good ending. Since we hadn`t budgeted for these 3 extra islands in the timescale and money, we had to say enough was enough. Telecomsoft weren`t aware of the extra 3 islands either so they had to agree that we either didn't do them, or we'd need a lot of extra time and cash.    
 
 

Working Up the Levels

John was busy doing the maps by using a VHS video next to his Atari ST. He would pause the video and map the level quickly, as the pause mode un-pauses after a minute or so to avoid wearing the tape out.
 
We knew we needed to compress the maps down to take up less space to get them all on the floppy disk. Dominic came up with a design for the Mega Compressor, as we called it. We could see that their maps were made of 8x8 pixel squares, like the C64 used, but were quite often arranged into 16x16 blocks. We also noted that the same blocks were used on all 4 levels of each island, so there was duplication.
 
The Mega-Compressor was designed to run 8 passes over the 4 maps per level, and it was looking for common pairs of consecutive characters either horizontally or vertically. Starting at the top, it looks at the first two characters, then buzzes further across and down the map to find the same characters. If it finds at least 2 more duplicates it stops and substitutes a new "macro character" for the first of the pair, and blanks out the second one. It has to store the original two characters in a macro list, and then it repeats the substitution everywhere else across the 4 maps. The first pass was a horizontal one, now it runs a vertical pass, again looking for repeated pairs, but one below the other. It can also then pick up macros too, so a new macro might be two macros one below the other. We have compressed repeated 2x2 characters into one macro that consists of two other macros.
 
I can't remember that scale exactly, but if we let John have something like 1024 characters to do the backgrounds then in a 16-bit word we could use all the numbers over 1024 as macros, giving us over 31,500 before we ran out. We needed the top bit for the run-length compression later. 
 
The next pair of passes would only consider two characters separated and followed by blanks, so it would likely start identifying and packing down consecutive blocks of 2x2 characters, of which again there were a lot as the backgrounds were quite straightforward.
 
We allowed the compressor two more pairs of passes. After that it did a simple run-length of the remaining data. If there was a string of at least 3 blank characters then it would count how many, and again substitute a macro with the top bit set and a count of how many zeroes it had substituted.
 
It was tough enough writing the assembler for that, and the de-compressor, without getting too much info about how well it was doing. The packed file would tell us how many macros it had created, plus its final size as compared to the start sizes of the maps. The compression process might take the Atari ST 20 or 30 minutes.

I hadn`t done any data compression before this, mainly because C64 data is pretty small anyway, and your decompressor routine is going to be fairly big, so what`s it going to save? We got to use the Mega-Compressor again for the Paradroid 90 maps, we just adapted it to do 16 maps instead of 4. This process might take the Atari ST 90 minutes. Later we started using a more generic packer so that we could feed it anything.
 
The way the team worked was that we led on the Atari ST, John getting the graphics sorted out, and I was developing the software to run the game. David and Gary were then looking after the Spectrum and Commodore 64 versions. Dominic worked out how to store non-moving Rainbow and Fruit images in the background, making little stacks where they overlapped. This feature was used again in Paradroid 90 for crates and doors.

We were able to deliver completed algorithms and graphics per island to the 8-bit platforms for them to implement as best they could. We had the Taito documentation, which included diagrams and graphics, so although we could see that some features had changed for the final game, it took a lot of the speculation out.
 
 
 

Sprites

When we first looked at the game; we reckoned that the sprites were typically 32 pixels wide. The meanies on the first level are caterpillars, birds, ladybirds and spiders. Imagine our surprise when we discovered that the caterpillars are actually 48 pixels wide. I expect that the Taito graphics chip just makes custom sprites out of 8x8 blocks, as many as you want. Our 16-bit plot routines were written to plot 16 or 32 pixel wide sprites to any height. We could gang them together, i.e. use a 32 and a 16 to make a 48, indeed we had to bolt multiple 32 pixel wide sprites together to make the big bosses. We also split the objects into looking straight ahead, or left-facing. We then generated the right-facing images at run-time. We also reckon that the Taito graphics chip was more than capable of flipping characters and sprites in the X and/or Y dimensions, it may even have been doing 90 degree rotations.
 
 
 
I was nervous that plotting 48-pixel wide sprites for many objects would be too much work for the Atari ST to get done in the time. I had John scale down the caterpillars to fit them in a 32-bit sprite, reasoning that the size wouldn't matter too much. After spitting a few bullets he set to work. As well as the walking frames in two different colour schemes, which again the Taito graphics chip could likely do with two palettes but we couldn't afford to do in real-time, the caterpillars can walk round rainbows, at the appropriate angles.
 
 
 
As we progressed, shrinking the 2nd island, Combat Island, vehicles, we got to the 3rd island, Monster Island, where many of the sprites were 48 pixels wide, but the game was coping pretty well, so we relaxed the shrinking operation to use the original images from then on. Monster Island coped well, so we used all the original graphics after that, although we were still using having to compress all the level palettes into one 16-colour set. 
 
 
 
I didn't want John to spit any more bullets by telling him I'd like the original sprites back on the first 2 levels. He was busy making the graphics all fit into Commodore 64 sprites and Spectrum graphics so he was pretty busy.  
 

Spiders

I want to give special mention to the spiders on the first island. They have some innovative behaviour that we hadn't seen before in sprite games, and that made for an interesting time for us to copy that behaviour on a bitmap, since we were not using hardware sprites on the Atari ST on account of there not being any. Actually we couldn't really use hardware sprites in the Amiga version either because the sprites actually have to display in front of the main background, and behind the water when it rises up the screen. The arcade chips had the advantage of two playfields.
 
 
Back to the spiders then. When they're above the player they bounce around on the ground, moving left or right towards the player. When the spider is below the player it can cast a web upwards and then climb up the web. This meant writing a simple vertical line drawing algorithm and a control routine to search upwards and span the distance between the search point and the spider. The web line can also fade out once it is not needed. The big spider does a simpler web line. Anyone writing a platform game should just see if their game system can emulate such spider activity.
 

Rainbows

Bub, and Bob in 2-player mode, have to climb from the bottom to the top of each vertical-scrolling level. They can run and jump, and fire a star, which arches over; leaving a rainbow behind. The star is quite important as it is quite likely that it will hit a meanie at some point, and the meanie flies away spinning and comes down to ground, leaving a fruit or other object behind. There are 80 different fruit, and each one appears in turn. The first yields a low number of points when collected, all the way to the brown money bag, which yields 10,000 points if collected. The fruit disappear after 5 seconds. OK, so a money bag isn't a fruit, nor are crowns, nor sushi, but that`s what the game element was called.
  
The rainbow stays on screen for 6 seconds before flashing for 1 second and then fading out. Up to 12 rainbows can be on screen at once but the oldest ones will fade out early so that Bub or Bob are always ready to make new ones.
 
On collecting a red pot, Bub or Bob can fire two consecutive rainbows. A second red pot adds a third rainbow. A yellow pot makes the rainbows form quicker. These powers are lost if Bub or Bob is knocked out by a meanie.
 
If Bub or Bob jump up into a rainbow it will begin to fall, the documentation referred to this as crushing or crashing, taking any overlapping rainbows with it. Any rainbows fired together are overlapped by default. Bub or Bob can jump on a static rainbow by holding the jump button, and the rainbow will not fall. By careful jumping and firing at the same time very fast progress can be made upwards. You can also lay traps, even with 1 rainbow. Fire many rainbows on top of each other and when you`re ready; jump into them to crash them all at once. This technique is especially useful against the big bosses.

It was rather fortuitous that the rainbows remain static on the screen. They would take a lot of plotting if there are 12 on screen and moving. The trick though is that as they are static they can be plotted as character overlays instead of sprites. Since meanies are generally killed by rainbows being built then there aren't too many near the rainbows requiring a complex character rebuild every frame. The arcade original is just doing the job with hardware sprites, so clearly it has a lot of them available.
 
Falling rainbows can kill meanies and collect fruit and other items. This also applies to meanies and items just above the rainbow when it falls. As opposed to the star that fires ahead of the rainbow, meanies hit by rainbows, and also yellow and red stars, are flung away and when they land they turn into a gem, in one of the 7 rainbow colours. The colour is not random, as you might think. Note carefully where the green gems are, for instance. They're always near the horizontal middle of the screen. Red gems are always on the left, purple gems always on the right. Now you know that; you can set traps by placing rainbows below or above meanies, and "crash" them with a small jump at the right time. When the meanie is in the right position to spin off in the direction it was moving, you can judge where it will land. This should allow you to collect all 7 colours of gems within each island.
  

Every Third Meanie

When a meanie is despatched it produces either a fruit or a gem, as distinguished above, but every third meanie produces something a bit more special, according to this list:
3rd - shoes, collect to run faster - only one level of speedup,
6th - red pot, add 1 rainbow per firing, up to three max,
9th - yellow pot - make rainbows form faster, only one level of speedup,
12th - red pot, as above,
15th - yellow star, explodes upwards,
18th - crystal ball - reveal monsters true selves when spinning away blue, they are the Bubble Bobble monsters,
21st - red star, explodes all round,
24th - statistical special
 
So now you need to watch what is produced when you kill a meanie to know if you're going to get a gem or a special. There's no point in setting a trap for a meanie to get that last purple gem if the previous two kills produced fruit or gems, because this multiple of three is going to produce a special.
 

Gems

The importance of collecting gems can't be understated. The Completed display when you get all 7 gems on an island gives you an extra life. This is to emphasise the importance of getting all of those gems. Having all 7 gems when you beat the big boss at the end of the island yields a big gem from the chest, rather than a big fruit. Big gems are as important as little gems! There is also another surprise in the boss room if you have collected all of the little gems in sequence, left to right.
 
When you get to the boss room, there is an extra silver door. You can get to the door before the boss starts attacking, where you enter a secret room. In the secret room there will be one or two big bonuses. The first one, in the spider boss room, is permanent fast shoes. Good players will deal with the big boss, collect the big gem from the chest, and then go through the secret door to the secret room, where you get another big gem and the bonus.
 
But wait, there's more. At the top of the secret room is an 8 character code. The letters are rather stylised, but they are LRJB. This is a code that can be keyed in on the title screen, the one with the big rainbow, before you add credits. Sorry, I can`t remember if you can use the joystick too, using up for J, Left for L, Right for R and fire for B. If you enter any one of the seven codes from the secret rooms then you can start with that feature. There is a small sting in the tail that the game steps up the difficulty level if you use a cheat code, and as each island is completed and if any secret rooms are entered, so the meanies will be meaner.
 
It is definitely worth visiting as many secret rooms as you can. You can avoid fighting the big bosses and get permanent features.
 

Statistical Specials

The game is keeping count of what you collect! It even carries over from game to game. It is also counting other events, such as Hurry Up! messages and the player losing a life. This can allow for more exotic statistical specials to come out after a few games. There are 43 statistical specials in the arcade game, and I added a 44th, a Graftgold key can appear.
 
The simplest statistical specials are the 3 rings. Firstly, any time you collect 3 red pots, or 3 yellow pots, or 3 pairs of shoes you will queue up the next statistical special to be one of the 3 rings. Actually, if no statistical special is ready to come out when it's time to produce one then it will randomly select one of the 3 rings. Also note that you can only get one statistical special per level, so if you miss it, there will not be another that level. There is also a priority system in place, which we took ages to decide on as the documentation was ambiguous. If the statistics say that a particular special is ready, and one is already queued up, the rarer one takes priority, and the more common one is lost. We tried it that the more common one takes priority too, and that code rarely gets triggered that it needs to compare anyway, usually only one gets tripped in. Especially if, once you've powered up with the shoes, 2 red pots and 1 yellow pot you avoid collecting any more of those items. With the rarer item taking priority though, you don`t need to worry about the pots and shoes.
 
Some of the statistical specials contribute to other statistics, forcing you to collect them to get the even rarer specials, while others cause special features to activate. They might also make something unusual happen when you complete the level.
  
Statistics       Collect...                    ; Causes...
RubyRing         3 x Shoes                     ; Points for stepping
CrystalRing      3 x Red jars                  ; Points for landing
AmethystRing     3 x Yellow jars               ; Points for rainbows


Necklace         77 x Rounds                   ; Gives all 7 gems in right order
Special          33 x Games                    ; Make features permanent
Pentagram        30 x Completions              ; Bonus life
HolyComet        2 x Crosses                   ; Random special


RainbowCross     3 x Any lamps                 ; 4 fast rainbows
ThunderCross     2 x Any rings                 ; Lightning bolts from sky

RainbowDrug      27 x Rounds                   ; 4 magic balls round Bub
MagicalCape      10 x Player deaths            ; Invincibility
HolyCup          15 x Any jars                 ; Single flash of lightning
PeacockFeather   6 x Hurry messages            ; Guardian Angel orbits Bub


CopperRod        6 x Copper crowns
SilverRod        8 x Silver crowns
GoldenRod        10 x Gold crowns
 
Balloons         2 x Any rods                   ; Balloons rise from floor
BookOfWings      8 x Shoes                      ; Bub can fly
Clock            3 x Any Tiaras                 ; Meanies freeze for 8 seconds

BlueTiara        120 x Enemies crushed          ; Flashing stars from sky 16 secs
GreenTiara       20 x Enemies killed by fairy   ; Red stars on crashing rainbow
RedTiara         30 x Enemies killed with star  ; Red stars from jumping

Bell             20 x Rounds                    ; Bell rings on hidden fruit
StarMasterRod    2 x Capes                      ; Hidden Fruit = red stars

RedLamp          20 x Red stars                 ; Big money bags from sky
YellowLamp       10 x Yellow stars              ; Hidden fruit = Money
BlueLamp         5 x Holy cups                  ; Hidden fruit = Crowns


RedWand          7 x Red diamonds               ; Crash rainbow turns to cherries
OrangeWand       7 x Orange diamonds            ; Crash rainbow turns to tomatoes
YellowWand       7 x Yellow diamonds            ; Crash rainbow turns to apples
GreenWand        7 x Green diamonds             ; Crash rainbow turns to chocs
BlueWand         7 x Blue diamonds              ; Crash rainbow turns to eclairs
IndigoWand       7 x Indigo diamonds            ; Crash rainbow turns to cakes
VioletWand       7 x Violet diamonds            ;   "      "  turns to pineapples


RedHolyWater     2 x Red wands                  ; End of level fruit 4,000 points
OrangeHolyWater  2 x Orange wands               ; End of level fruit 5,000 points
YellowHolyWater  2 x Yellow wands               ; End of level fruit 6,000 points
GreenHolyWater   2 x Green wands                ; End of level fruit 7,000 points
BlueHolyWater    2 x Blue wands                 ; End of level fruit 8,000 points
IndigoHolyWater  2 x Indigo wands               ; End of level fruit 9,000 points

VioletHolyWater  2 x Violet wands               ; End of level fruit 10000 points

GraftgoldKey     2 x Feathers                   ; Jump generates special stars
 
 I'm not sure what the copper, silver and gold rods do in our implementation. These metals feature in the last 3 islands, I may have had to curtail those.
 
There are a lot of different special bonuses that you need to look out for as you watch the sequence of third bonuses appear. Some are directly helpful, such as if you keep dying you'll get invincibility, or if you keep getting Hurry messages you get a Guardian Angel.
 
The 33 games bonus was one we used to trigger on demand in DEBUG mode because that gives you 3 permanent fast rainbows, and fast shoes.
 
When playing the game, in order to maximise the rarer bonuses` chances of appearing I used to avoid collecting gems, pots, and crystal balls that I didn`t need. The gem wands will start to come out after a few levels as they are high priority, and gems are often collected.
 

Publishing Hiccup

As we neared finishing the game, it was starting to go out for previews. Then the unthinkable happened: Telecomsoft got sold off. I believe that invalidated the Rainbow Islands contract with Taito, and the release got put in limbo. We completed the work and received our fee, but we wanted to see the game released, and it wasn`t going to happen.
 
Probably a year passed, and some keen journalists, notably Garys Penn and Whitta, were still keen to see the game released. Somehow they managed to get Ocean to talk to Taito and arrange for the licence to be renewed and for our versions of the game to be released.
 
 
Finally the game went out for proper review and got released. Later it got an award from a European organisation. We heard later that the award was collected and later abandoned in a night-club, somewhere in Europe. Miraculously the award did reach us many weeks later, albeit slightly damaged. As developers, we were naturally chuffed to bits to get such an award. 
 

PlayStation, Sega Saturn and PC

We were later asked to produce 3 new versions of the game. Gary Liddon tells me he was instrumental in getting Acclaim on board. These were written in C, so we started again, but we had an ace card. All of the game elements were programmed in our own Alien Manoeuvre Program (AMPs) language, which was an interpreted language generated with assembler macros. The advantage of a higher-level language like C is that the majority of the code works on all 3 platforms as it is compiled into the native machine language of each machine.
 
I was able to adjust all of the AMPs for the full 50 or 60 frames per seconds using the Amiga data, and alter some of the programs such as the gem display that we could now do as a sprite overlay rather than a split screen. We had to convert the AMP interpreter to C, which wasn't too tough, and the game sprung out of the new data. All of the AMP language commands needed to be converted too. They were many, but quite small.


 
We were also asked to produce a more up to date set of graphics from the originals. Colin Seaman was the lead artist on this, and he created a new background layer to scroll in parallax, and he enhanced all of the game graphics. He worked really quickly, and always did a first class job. Rainbow Islands was packaged with Bubble Bobble, which we didn't do. We were told later that Taito approved our Rainbow Islands enhanced graphics, but not the Bubble Bobble ones, which never got published.

We did restore the first two islands' shrunken sprites back to their original sizes, since we had more colours available and could use more of the original graphics. Having more pixels also helped with the enhanced versions of the sprites.
 
I pressed for transparent rainbows, which the PlayStation did admirably. I thought the Sega Saturn was also doing semi-transparent rainbows, but the video I watched of that disagrees with my memory. I do have the game, mint in box, but not a Sega Saturn, just a controller!


 
I used an Amiga A1200 to develop the data, and I could run the game at the full 50 frames per second. The A1200 would even have been able to do a second back playfield. The Amiga, sadly, was already on the wane, so it was never going to be produced.
 

US Variants

I said earlier that we had to change the main tune on the U.S. release. There was another alteration we were asked to make. They didn't get the "Goal In!" phrase, which is a bit quirky, but the point is that it has 7 letters, done in rainbow colours. The first 6 letters arrive in a choreographed fashion, and the exclamation mark arrives last. By getting us to remove the "IN" from the phrase; we had to alter the choreography of all the ways the letters can arrive, and it messes up the rainbow colours. I suspect also that it is a hint that the colours go from left to right, the same as the gems are produced. Apparently removing the quirky Japanese phrase is more important than that. They could have just rolled with it like we did...
  
 
Too late I thought putting in 3 exclamation marks, in blue, indigo and purple  would have been a reasonable compromise. Maybe after 28 years I should let it go?
 

Conclusion

Taito designed this game very, very nicely. Sure, our implementation was quite accurate, thanks to the documentation that we received, plus Graftgold`s attention to detail and hard work, but the real reason this game received attention is because it was designed really well. The notes we got alluded to the fact that the game was designed and written over about a 2 year period, that's where a lot of hard work went in.
 
Things are not as random as they seem in the game. As with many arcade games: they are intended to play exactly the same every time. We rarely had to call the random number generator. This makes the game predictable and players can learn where things are and what they'll do, giving them more accomplishment every time. Note that since the special bonuses are accumulated from game to game and not reset, you will get slightly different features appearing as you keep playing. The arcade players would see these and wonder what was happening. For your home computer versions: now you know. 
 
 

Being "In The Zone"

Introduction

Over the past few months I've seen a number of reviews or play-throughs of our games on youtube. This has shown me any number of game features that I had forgotten. It shows me how blurred things become over time.
 

Scale

My first Dragon 32 project was converting 3D Space Wars. This took me around 6 weeks to code and add a few graphics. This is just a guess; but I suspect there were around 6,000 lines of assembler code in there and the rest was graphics and storage. I was using an assembler on the Dragon 32 and a DragonDOS disk drive. I had to split the game code into manageable lumps because the 32K of RAM had to be big enough for the editor, the assembler, the source code and the object code.
 
I do recall that we had to load the assembler into different memory locations to be able to assemble the various blocks of machine code into their correct locations. On the one hand 6809 code can be assembled relative so it uses branches rather than jumps, but at the same time fragmenting the code like we did meant that we had to load the various code lumps into absolute locations so that cross-calls knew where the code was.
 
Within the 6 weeks of development I created the code out of nothing, we had no library code to refer to and no monster libraries of code on the then non-existent Interweb. All we had was a 6809 assembler reference book (which I may still have but haven't seen it recently).
 
Since Steve Turner was coding in hexadecimal machine code on the Spectrum with only 4-character labels for jump locations, I was the first to create source code for one of Graftgold`s games. I was creating my own routine names and variable names.
 
By the end of project I knew all of the routine names and the location of most of the variables in the "zero-page". For the technically minded, the C64 6502 chip allows short fast instruction access to bytes in the first 256 bytes of RAM, i.e. 16-bit addresses starting with a $00, where each 256 bytes is a page, hence zero-page. That`s where you want to put all of your variables, where you can access them quickly and with shorter instructions. The 6809 allowed any 256-byte page to be designated as its fast access page. Whilst you could change the page number in flight you probably wouldn't unless you had 2 games in one set of code. I didn't use page $00, the OS was using that, and I needed the OS to poll the analogue joystick.
 
When we finished a game we would print it on the dot-matrix printer, at great length, a module at time. We didn't have space in the machine to include code comments so we added them to the listing in pencil. This process usually took about 3 days. It gave us a break from coding. I kept all the listings under my desk in one folder and it was quicker to refer to the old source code on paper than load up a different module than the one you're working on. I'm still looking for that blue folder. I know it`s around somewhere.
 
The process of game development then was that I'd play the game for half an hour or so, writing down any adjustments that I wanted to make, or bugs that I'd found. Since the game was split into separate modules I wanted to work on each module in turn once. I'd therefore load up the first module and see what bugs or changes needed making to that module and do those, then load up the next module.
 
Sometimes a module would expand so much that it would encroach on where I'd defined the next one to start. I'd either have to move a big routine to another file or relocate the next module in memory up by 256 or 512 bytes. This might cause a cascade and I'd have to move all the modules along a bit. I had an address for the top of the module, and then offsets from the top to the various jumps to the subroutines inside the module.
 
I used a jump table at the top of each module to get from a known address to one deep in the module, in the same way that modern DLLs do it. Trying to call routines deep inside a module would have been very high maintenance on keeping the addresses up to date. I figured it would slow down development a lot since one mistake would probably cause the computer to lock up and take ages to debug. Even at the end I could have adjusted all the calls to make the game slightly faster but any last-minute bugs would again be difficult to solve. I tried to organise it such that often-used calls were done in the same module. This would use a short-range relative BSR branch-to-subroutine instruction.

The Dragon assembler was pretty fast, and so was the Dragon 5.25" disk drive. The assembler was actually a multi pass one, rather than just a two-pass job. If it needed to do more passes to resolve some more forward references then it would just get on with it. I could probably do a whole book on why keeping C to a one pass compile has caused me so much grief, but I suppose since they released C in 1972 then they're not going to change it for me now.  
 

 The Next Game

We would write the next game by stripping out all the game-specific routines from the latest code, leaving the utility routines that we'd need next time. All of the plot routines would stay, including the font plotter, and the sound routine. We'd spend a little while seeing if we could improve those routines we were keeping.
 
When I switched to the C64 I had the Commodore Macro Assembler and the very s-l-o-w 1541 disk drive. I could create one single program from assembling multiple files. The only rub was that this process took about 30 minutes.
 
Once I`d attempted to fix all of the bugs and add any new code, it was time for the assembly. During this time the 1541 disk drive would grind away, and I`d switch the TV aerial selector to the other C64 and get on with any graphics alterations or additions I wanted to do. I would dread that there was a typo in the code and the assembly would fail. It wasn't a sophisticated system with a make file so it knew whether it would need to recompile only certain files, it insisted on doing the lot every time. It also occasionally decided to destroy the floppy disk contents, so a source backup was always a good idea before a compilation.
 
By the time I had completed Uridium; the code was probably nearer 10,000 lines of assembler taking up about 16K of the machine. Some of the routine names came over from the 6809 code base, which helped with continuity and "The Zone", but since the machine architecture was so different there was little in common. The whole program was split into maybe 10 files, and I still knew which file had which routines. You couldn't afford to keep loading the wrong source file. I kept a list of modules and routines as a quick reference.
 

 PCs Take Over

A big change occurred when we got our first PCs in 1987. They didn't have hard drives, only twin 5.25" sloppy disks, but they did have about a Megabyte of RAM, of which they could bring 640K to bear in a DOS environment. Windows hadn't been invented! We had to boot up DOS from floppy disk in the morning. We had enough memory to set up the DOS files in a RAM disk for quicker running.  

We bought the EC editor, which must have been pretty popular because Visual Studio 6 at least had EC compatibility modes. I seem to recall that it was still under development because we had to contact the author for some advice or updates on at least one occasion. It was a nice editor.

 We bought in some cross-assemblers for Z80 and 6502 and had to key in any code we wanted to keep again. I can't think how we'd have got files off of a C64 floppy drive or Spectrum tape onto a PC. We connected the PC to the C64 or Spectrum through the parallel port. We had to write a small code loader to run on the target machine to read off the parallel port. I continued to use the C64 to draw sprites and fonts. We would still load those from C64 floppy drives, and of course the final save to turbo tape had to be done on the C64.

We still didn`t have a debugger as such. We had my simplistic monitor that allowed us to dial in a memory location to look at and see the value there, and update it. Steve took the design a bit further and had it display a few consecutive bytes. Since we were always poking around in the game`s variables then it kept all the addresses and expected values very fresh in our memories.
 
We were still working in relative quiet as there were just the two of us working in a small office behind Steve's garage. There was just space for two desks side by side, piled high with bits of electronic equipment. We were still using TVs for the monitors to the target machines, though we decided to use amber monochrome monitors for the PCs, which made the source code appear nice and clear. Having that quiet environment was usual I suppose for the way we had both worked in our previous jobs and allowed us to really concentrate on the job. We also worked 9 to 5, which was quite unusual for games programmers of the time, many of whom only saw a morning from the other end as they were going to bed.

We didn't even think to install a stereo, not even a radio or a cassette player in the office. We maintained the professional hours and office environment. that we were used to. Only later when we expanded into a bigger office did we get a stereo, which led to the Tanita Tikaram incident. I'll leave that for another time! I've still got the mental scars.
 

The Big Switch to 16-bit.

By the time I got to move onto the 16-bit machines Graftgold had grown to 7 of us. Dominic had already written a pre-emptive multi-tasking system for the Atari ST, with a view that an Amiga version was not far away, and by making calls to his OS the differences in hardware would be invisible to us. Along with that came linked lists and allocated memory. These changed the way we constructed our software. The joys of these are well-known to all C programmers, and 16-bit assembler programmers. Likely there aren't so many 32-bit assembler programmers since the 32-bit and up CPUs are not really designed to be used with assembler any more, it`s just too complicated. 
 
The biggest change then is working within a team. I had to call someone else`s code on a frequent basis. I can say it really helps having the author of that code on the next desk. It means you can get new functionality added if you need it. I was also doing less graphics, actually none at all for Rainbow Islands, and only the fonts for Fire and Ice and Uridium 2. I did do some of the background pieces for Paradroid 90.
 
I had all of the game code in one place and was co-ordinating all of the graphics as they went into the games. In the early games we were saving graphics from LBM bitmap edited sheets into .dat files and adding the sizes into the code manually, followed by including the raw graphics with an incbin statement one by one. We would use 16 pixel wide sprites where we could, or 32 pixel wide sprites. We could also gang a 32 followed by a 16 or use multiples of 32 pixel sprites for the  big bosses. The Amiga blitter chip was pressed into operation for plotting, but we had to enlarge the data for the sprites to include one mask for each bit-plane to be able to blit the whole sprite in one operation, else we had to blit each bit-pane separately.
 
Over the course of 4 games there was a lot of commonality of the plotting routines, object movement and general mathematics. That helps to keep you "in The Zone". Even if you choose to do something a different way you can still use the same routine names. Of course it's all the differences that take the time to write. Once we were using hard drives to store the code it became easier to put code into more logical file names so the number of files expanded. We used file types of .XX and .XXH for generic files of code and headers, and then split ST- or Amiga-specific code into .ST, .STH, .AM and .AMH files.
 
I pretty much still knew where everything was, and it also helped that by the time I was writing Uridium 2 I was also providing support for Virocop, keeping me familiar with all the code. The file sizes of especially the routine that contained all of the game object subroutines were growing immensely. Rainbow Islands had the Mk I simplistic movement controls and I honed those down for Fire and Ice with experience. Once you've gone a certain distance down a path, if you realise there was a slightly better path, it's still not worth going back over everything you've written. Save it for next time.
 
We were able to put decent comments in the code, which really is quite important for assembler, but we weren't printing off listings because they'd have taken about 1,000 sheets of fan-fold. Having the code in front of us for even longer development times kept the familiarity with the code, and the better code editors that could load more files at once allowed us to see the code easily without a listing.

When most of the code is your own, there is a familiarity that you can`t get with other people`s code. You have a confidence in changing routines because you know how they`re called and by which functions. Changing other people`s code requires a lot more caution and experience. Indeed I have rewritten other people`s routines in the past so that I better understand their limitations, or in some cases to widen them. I have even rewritten entire COBOL programs in some extreme cases, as I have mentioned in previous blog pages. Understanding the code is vital, and it`s very much harder to do that if that code was written by someone else, and likely has been amended by more people over time. It can become gnarled and odd-looking.

I don`t think I`ve ever looked at anyone`s code and thought: "Wow, that`s really neat." Other people`s code just isn`t familiar enough to look nice, even if I`ve shown them how I want it done. I can only conclude that anyone who has ever seen my code must think the same. I guess we all think we`re the best programmer in the world, and somehow we`re all right. I know I am, I`ve got the trophy to prove it! :-) I think it`s made of plastic... 
As time goes on even our own code becomes less familiar. Firstly, there's more code to consider. I dread to think how many lines of code I`ve written over my lifetime, and in how many different programming languages. I don`t expect I could write any COBOL now, nor any assembler, you just have to be "in The Zone" at the time.


 

In Conclusion

It`s great to see people take the time to video our games played all the way through and posted on youtube. These act as a reminder to me of what we achieved in putting the games together at Graftgold. It also proves that they can indeed be played all the way through. I can`t say that I`ve completed many other games, or at least got them to loop back round to the beginning with the difficulty increased. Arcade Scramble is the only one I can recall.

As time has passed I find that I have forgotten the smaller details in the games, such as the exploding fireplace in Fire and Ice Scotland, and the Victory Points in Uridium 2, so just when I was thinking that our games could have had more complexity in them, I see them again and it's all there.

I built the games to play differently every time rather than be totally rigid like some scrolling arcade games. That means even if you`ve watch a video, your game will play differently, every time. That hopefully is what keeps them interesting and is one of the reasons why people are still playing those games today, some thirty plus years after they were released.

When you`re writing a game you need to concentrate on everything you`re doing and using, all the time, just to stay "in The Zone".