Game Tuning

Introduction

The process of tuning a game is a tricky one. If you try to do this on your own you will inevitably tune the game to your individual preferences. Also, your increasing experience of playing the game will make you think that the game is easier than it is. It's essential to get other people playing too, but not too much, or they'll get used to it as well.
 
Tuning can be done at the same time as play-testing and bug-hunting. During that time, anyone play-testing is going to be accumulating knowledge about the game, and formulating ways to play it.

I "borrowed" some screenshots from the interweb for this article for illustration purposes. Hope no-one minds that I used their screenshot of my game, and thanks.
 

Progression

What sort of game progression do you want, or need? Do you want a game that gets harder as you go along? Do you want the game to be fairly linear?
 
There are a number of ways that a game can progress. Typically the early arcade shoot-em-up games just repeated the same thing but maybe the Invaders were closer, the Galaxians a little faster, or more trigger-happy. That progression is quite easy to build into algorithms. The start positions and numbers of enemy can be used, and the chance of firing calculation can include the level number.
 
A puzzle game would start easy and then introduce more devious puzzles, better hidden items, more stages to solve the puzzle, that kind of thing. Again, size matters, the game area could be increased, for example.
 
Story-type games don't necessarily need to get harder; the complexity of figuring out the plot will keep it fresh. These games must be tough to manage, there are so many ways that the players could fail to engage the plot. I played "Dear Esther" the other day. It felt fairly linear, and I was just admiring the scenery. It's a nice 3D engine and it leads you through the story pretty well. The only time I got stuck was when I was trying to walk round the underground waterfall pit and kept slipping down. Fortunately there's youtube! 
 

Same or Similar?

Most arcade games appear to play very similarly every time you play. Some are identical: we used to count shots in Space Invaders and we knew that on the 23rd shot you had to shoot the flying saucer for 300 points, and every 14th shot after that would always yield 300 points - it's not really random at all, but if you don't know how it's doing it then it'll look random.
 
Personally, I always favoured the idea that the game would be different every time, but in a controlled way. For example: in Gribbly's Day Out the Gribblets all start in their designated positions but can then choose to jump around randomly. By the time the player has found them, some could be a fair distance from their start positions. The Paradroid ships are populated with each robot randomly chosen from 4 different consecutive types, some of which are also increased by the ship number. In Uridium: some formations are generated behind the player, so it depends which way you're flying at the time, and Uridimines might appear any time. For me that creates a better long-term game because you don't know exactly what's coming. We let the SID chip on the C64 generate the random numbers, so they were not reproducible. Anyway, my point is that if the game setup is different every time then your playability rating per level is going to be a little more fuzzy and should be noted as such. It doesn't matter either if occasionally a more difficult level sneaks in early.
 
You could argue then that my games might be unsuitable for competitions as you couldn't guarantee the difficulty, but overall the randomness balances out - the house always wins in the end!
 
In this internet age if you wanted to synchronise two or more remotely connected computers you would use seeded random numbers to ensure that they all behaved the same. We therefore use both seeded and unseeded random numbers nowadays. You can have an array of unseeded numbers for things that don't matter, such as explosion fragments that don't interact with anything, and use seeded numbers for generating game elements that need to be the same on all machines. That doesn't prevent you from sending the random number seed from one machine to the other to get a different synchronised game every time.    
   

Chasing Perfection

It goes without saying that a game must be able to be played all the way through. There must not be any bugs or mapping mistakes that would cause the game to not be completable (my new word, Susie Dent, please get it added into the OED). There was no online update capability back then, everything had to be working before the first run of tapes was made.
 
I also want to make this very clear: updates inconvenience your users. Sure, it's great to get those bugs fixed, but there shouldn't be any, and it takes a lot of time and effort on the part of every user to keep their software up to date. I get 1.2Mb/s here. VS2017 with all the trimmings took almost a day to download, on each computer.
 

8-Bit Days

Once I left my IT job to write games I kept in touch with my friends there and used to visit them most weekends with a work-in-progress version of the game I was writing at the time. It is invaluable to seek other people's overall opinions.
 
I've been looking at a few youtube videos of some of my old games being played, or reviewed. Clearly many of these reviewers did not have the original instructions manuals that came with the games. This leads them to get rather frustrated as they don't know what to do or how to do it. The manuals are important, and worthy of their own blog page.
 
Arcade games need to attract people to play them, so they can have quite detailed demo or instruction sequences, but generally they also try to keep things fairly simple as they are only trying to provide a 5 or 10 minute player experience.
 
Computer games can be more involved, typically an 8-bit game might take one or two hours to go through all the game, once you've learned to play it, and studied the manual for the rules of the game and any hints we might have included in the text. I always used to write the manuals, including the back-story, for my games. Steve Turner did likewise.
 
While watching a chap play Gribbly's Day Out on youtube, I realised that he didn't have the manual and despite the instruction to "Rescue the Gribblets" as he started, he didn't know what a Gribblet was. He started to fly around and mess with the power grid, which is advanced stuff that you don't need to do much at the beginning, and ignored the jumping creatures that he was meant to rescue. If I had put a picture of a Gribblet next to the message he'd at least have known what he was looking for. On the other hand, should I have any sympathy for someone who hasn't got the manual? I'm all in favour of good official documentation. Nowadays there's a lot of unofficial documentation online and it's just spread all over the place.
 
When I watched another chap playing Paradroid, he hadn't realised that if you ram another robot, or roar into it guns-ablazing, you have to back off when it explodes. Explosions can damage the smaller robots. There are sound effects that allude to the damage, and if you watch the rotation speed of the player icon you can see that you are taking damage. He also didn't know what the re-energiser blocks were, so didn't know he could recover his energy.

How much information do you have to give the new player? This depends on whether they can blunder about in the game for a while and figure it out for themselves. Again, the arcade machine doesn't mind collecting a few swift 10 pences while we get used to the game, as long as we do. I don't spend a couple of days on the instruction manuals and stories so that they are ignored, or Heaven forbid, not paid for.
  

My 8-bit Testing

My first 4 games were conversions of Steve Turner's Spectrum games: 3D Space Wars, Seiddab Attack and Lunattack (twice). For the most part these games were just plotting gaphics as fast as they could, I don't remember any speed regulation in the main game loop at all, and you can feel the control mode struggle when there are a lot of big ships on screen in 3D Space Wars. The other two titles had more graphics on screen for the background all of the time so the main loop was better regulated. It'll be interesting to see what they do on the super-speed Spectrum and C64.
 
I did put a speed control on my Dragon 32 3D Space Wars to allow the player a bit of control, and the controller was a proportional one, though not the keyboard.
 
A programming tip then, rather than make your control modes constants in the code, put the values into variables so that you can adjust them on-the-fly. That way you can tune up the control mode in real time.
 
Steve and I used to test each other's games too. I spent a fair few hours playing Avalon, DragonTorc, and AstroClone on the Spectrum. After each session we could give feedback on whether we though anything was too tough or too easy. Once you've built up some experience on your own game you know every little detail, other people don't know the underlying algorithms so they know less than you do. For example, I knew that the Paradroid 90 sentries would fire a few rounds off and then pause, as if to reload, so I could wait until they fired a salvo, then rush them. Other people might not figure that out. That's why it's really important to watch how other people play, and ask them what they're thinking.
 
When you let a publisher play your game then, it's best to make sure you're there to show them how to play first. Of course they'll have difficulty playing it, and they'll have more trouble accepting it if it's not exactly like the last block-buster. Innovation can be a dirty word to them. I also like to get most of the work done so that they only see the near-finished product. If you show something too early then the full impact of everything you've done is lost, and you'll be tweaking stuff unnecessarily for them for ages.
 
I'm not convinced of releasing early versions of games on Steam or other platforms either. Yes it's nice to get some feedback but again it's like knowing what your birthday present is going to be in advance, and being able to play with it before it's finished being built.
 
My preference is to complete the coding and provide a demo level, like we did on magazine disks. They were always produced last minute as a cut-down of the finished game. We would remove the end sequence and replace it with a sales message. Just try and put some of your best graphics in the demo.
 

Gribbly's Day Out


Gribbly's Day Out had 16 levels. I didn't want them to just play through one after the other, but I did want an easy trainer level to start with, and a monster last level to end. In between I arranged the other 14 levels roughly in difficulty sequence, but... then I messed with the next level selection algorithm so that the more Gribblets you rescue, the more levels it can choose from for the next one.
 
You have to rescue 6 Gribblets or more anyway to progress. If, on level 1 you rescue 6 Gribblets it'll just open up 1 more level and you'll get level 2 next. If you rescue 7 Gribblets then it'll open up 2 more levels. I can't remember if it tries to give you the highest level you haven't been to next, or picks one at random that you haven't done yet. The philosophy was that the better you do, the quicker you get to the higher levels. It always saves the 16th nasty level for last though. 
 
When I was setting up the Gribbly's map background layouts I did start to create some more deviously small gaps to fit Gribbly through. I also set up a couple of levels of tunnels with multiple small gaps. You don't want to irritate the player by then putting all 8 Gribblets at the other end of the tunnel, that's just torture, so don't be too mean. Put some easy ones to rescue too. That gives the player the dilemma of rescuing the easy ones first, or the difficult ones.
 
I used to practise the new levels a fair bit. If there was a gap that was too tight a squeeze and I could only get through every 4th attempt, then it needed to be eased off. You can't spend too long testing all the gaps because you'll get used to them. That's where my trusty test team came in. Once I was fairly happy with a map I could take it to them and let them try it out. If they complained too much then I'd make a note and change it for next time.
 
The only other parameters that changed per level of Gribbly's were the homing instincts of Seon, the ultimate meanie, he got more feisty, and the life-cycle of the other meanies speeded up, so they didn't spend as long in each form. The rest of the difficulty was in the map designs.
 

Paradroid



The Paradroid deck maps can be accessed more or less as the player chooses, so the sequence became unimportant. I always start the player on an easier deck. The difficulty of the game then came from the size of the decks and which robots appear on them. I tended to make the cargo decks generally contain a lot of battle droids, and the 999 cyborg was always on the bridge with some big side-kicks. The decks all have names and some hint more than others at what sort of opposition to expect. Engineering has maintenance droids, the crew decks have servant droids.
 
Since the player can become any droid in the game, the game is balanced, or unbalanced by the player. I just had to make sure that the little droids couldn't damage the really big ones. So that was a new feature for me, bullets that don't hurt the bad guys at all. 
 
There's no concept of spare lives in Paradroid. If you've taken over a bigger robot then I needed to make sure it could withstand a couple of hits from the big weapons, and if it gets shot from under you then you should run away fast. Since the game applies the same rules to the player as the other robots, then again it self-balances. 
 

Uridium



For Uridium I wanted pure arcade. Having got 50 frames per second and a nice multi-colour metallic look, I went for a straightforward linear progression. There were some walls on the first deck to crash into to teach the player "the rules", and most dreadnaughts are as long as they can be.

The meanie fire decision routine included the dreadnaught number, and the number of times the last dreadnaught had been reached. It hashes a number together, then gets a random number and if that's bigger, and there's a sprite available, the meanie will fire. I also had different wave formations that I could generate, each with up to 5 ships. I decided to create smarter singleton waves for later on where 1 ship tries to line up with the player, and I had a fire instruction in the algorithm so it could "force fire", and being a singleton there were plenty of sprites available as only 1 wave was active at a time.

Similarly the Uridimines linearly progress in their chance of production, and I could add more or less Uridimine ports on the levels easily enough, you could really put as many as you want wherever you want.

The data for the backgrounds was kept with the formation data for that level. That way I could shuffle them about in the source editor quite easily and arrange them in what I thought to be order of difficulty. It also allowed me to slot in another easy level at the beginning just to give players a warm feeling that they can progress.

Finally, since the Manta control allowed it to fly on its side then I could start to utilise some really narrow gaps, and not just on their own. It became like Gribbly's. While I was creating the background map data for a level it would be the first ship and I could have as many plays at it as I wanted, and without any formations attacking. That gave me time to see that the Manta could get from one end to the other. I had become a competent flyer and needed to back some bits off a bit, but by the time the player gets to level 15 they've probably played on the previous levels for a fair amount of time, so I felt if I could do the level, and I'm not that great a player, then plenty of others will be OK.

I did 16 more levels for Gribbly's 2nd Day Out, and Uridium Plus, and I tried to make the later levels a tad harder again than in the original. For the record, I clocked Uridium twice to reach Iron 3 times before being beaten, but only clocked Uridium Plus once, having copped it on level 10 or so for the second time. My top score on Uridium was 537,035.
 

Alleykat



For Alleykat, I wanted the player to be able to choose the races that they wanted to compete in. That way, if there turned out to be a type of race they couldn't get on with, they could avoid it altogether. So in some ways the races pan out like the Gribbly's levels, but you don't have to play them all, though you can. You can only enter races you can afford, so since the entry fees ramp up, along with the prize money as the races progress then you can't go straight to the difficult stuff, and you need to complete the races.

The different background types, of which there were 8 graphics sets, each had a chance threshold that a player bullet would destroy it. For the weaker types on the early levels it's a given that one shot from the right height will destroy the background piece. I then rigged some tougher types that they'd maybe have a 40% chance of going, so you might need 3 shots on average, but it could go in 1, or it might take 7. That meant that I didn't have to store how many shots each background piece had taken. You could also say it was a bit more realistic.

I tried to set the values on most backgrounds so that they would likely blow up before you got there (which would take them out for sure, while damaging the player). The Skullnia backgrounds are impervious to bullets though. That meant that I could create tracks that had to be negotiated rather than destroyed, at least for the first lap. As the race goes on the other ships start taking out the background pieces for you. 

The actual backgrounds are algorithmically generated. I could set the chance of a blank piece and the chance of a high or low piece of background at each hurdle. I also thought I could set the distance between the hurdles too. The algorithm also has to ensure that at least one passable piece of background is in each hurdle, For the last race I also made sure there was a nice big impervious-to-bullets skull that you have to fly into the mouth of right in front of the player at the start.

There are also energy pellets on the ground in the races, again  algorithmically generated by random chance so I could make plenty or few in each race  Those of you with the manual might also know that finishing a race with full or nearly full energy gives you a bigger energy tank for the next race meaning you can take more damage. That gives the player more goals to aim for. Topping up your energy as the race season progresses gives you a stronger ship by the end. With more sprites I might have been able to show that on the screen. If only I'd had the sprite multi-plexor then.
 

Morpheus



The Morpheus tuning up was completely different. Previous games had been using a lot of the RAM space for game maps, and although Alleykat generated its maps, I had 8 2K character sets in there to take the place of the maps. For Morpheus I wanted lots of sprites. The attack waves are divided into 50 levels, so I had to initially invent 50 sets of attack waves and then try to get them into some semblance of difficulty order. I had also built into the game a very flexible ship feature system so the player could be using a well-armed and well shielded ship, or they might have not developed it, or they might have unbalanced it with bad choices. Success in the game requires the player to develop the ship with good choices of equipment, and keep upgrading as better kit becomes available. Probably I wouldn't go for the giant hull, that was to demonstrate that you can go too far. 

Morpheus does end, but I can't remember how. There are 50 levels, and although I tested each of them individually and could beat them all, I am ashamed to say that I was only good enough to get to level 44 of the finished article in my best sitting. I was OK with that because by then we had some better games players than I in Graftgold, so I figured someone would beat it. Steve used to get letters from players that had beaten Avalon or Dragontorc, usually within a week of release. We didn't think that would be possible.
 

Intensity



Each level in Intensity is a discrete battle. There are almost 80 levels in the game, arranged in a 5 high x 16 wide rectangle. You start in the middle on the left and have to get to the right-hand end. The 5 horizontal strands represent different levels of difficulty, the top alpha route being the hardest. Some levels allow you to progress to the right, some only allow up or down, so the route is not necessarily simple to get to the end. You will have to play more than 15 levels for sure. The rewards are higher on the alpha strand too, but you need the better ships that can fly over higher obstacles.
 
When I was designing levels I was trying to make more difficult backgrounds all the time. I was able to design new backgrounds always as the first level before moving the data into it's designated place. I had to decide where the levels would go. You can firstly design easy or difficult features, but then the level takes into account where it is in the map for the meanie generation and transformation times. Also, the background layout plays a part as the meanies can get on the decks more frequently if there are bigger gaps to get through. Bigger decks mean they splat on the underside, like flies on the windscreen.
 
By placing the crew exit hatches carefully you can force the player to keep moving the drone or face the consequences, or keep the exits close for an easier level. You need to know what elements to alter to make puzzles or add to the difficulty.
 

Our 16-bit Testing

Our forays into Atari ST and Commodore Amiga territory required us to form teams. This usually meant the main programmer, plus 2 or 3 graphics artists and nearer then end, the sound and music expert. There was also Dominic Robinson with system support for the game OS he had written, allowing us to write in a pre-emptive multi-tasking environment that was lean for games.

I'll miss out Rainbow Islands  from here because we were not tuning the game up other than to ensure that we had replicated the game as closely as possible. We had a lot of documentation from Taito, which gave very detailed speed and algorithm information for the player controls and the meanies. The rainbows on their own deserve a blog page.
 

Paradroid 90 



For Paradroid 90 then I would generally design the ship layout, since it all had to fit together with no overlapping lifts on the side view, and the connecting data had to be fed into the assembler and debugged. We designed the levels on an editor written in STOS for the Atari ST. I had the graphics artists design some of the background characters to create features, and decorate the backgrounds. I did some of the background pieces myself just because sometimes it's easier to get what I wanted.
 
Having a team then means that you can let everyone have a go at playing the game, whilst reminding them that they're paid to do a job, and not just play. They have to know when to stop. Actually, since for most of the development life of a game it would only run on the programmer's kit anyway, we wouldn't make up playable disks until near the end of the project. Game tests generally consist of one group of levels assembled in rather than loaded. Therefore, to play the game they'd need to play on the programmer's kit.
 
Paradroid 90 deck designs followed the same idea as on the C64: each deck had a purpose and was accordingly populated. The cargo decks could be bigger with even more robots on them. I cut down on the types of robots because we had to do over animated graphics in 8 directions, and that was eating up a lot of memory. I then diversified what I could do with them. I could have patrolling sentries on specific short routes, and I could have static sentries that would guard locations, making them harder to ambush.
 
As each ship was taking shape we could test them as the first ship and prove that we could play them all the way through. The overall game design still balanced itself nicely. I made the transfer game AI more intelligent to make it more challenging for the player. The bigger decks made for better encounter areas so I was quite free and easy with big mean robot distribution.
 
Whilst I could get to the standard end of the game in one (long) sitting, I failed to beat the secret extra pirate ship, though I had beaten it standalone. Again, I was happy that someone somewhere would beat it. Anyone?
 

Fire and Ice



Fire and Ice was my first original 16-bit title, I suppose you might say. I had less steer on this new design as platform games aren't my forte. It's nice to change genres though to keep things fresh. Phillip Williams was the lead artist and took a great interest in the design of the sprites, the backgrounds and the puzzles, as did Jason Page. They were happily throwing ideas into the mix.
 
Since the arrangement of the lands had to go from icy cold to desert hot, we had little flexibility to swap things around to better serve the difficulty. We chose the lands based on themes and put them in latitudinal sequence. I had made the mistake of putting the slippery levels first. Seems we put penguins in the North Pole too, sorry penguins!

Each land had its own Coyote movement constants to decide accelerations, top speeds, friction and drag. Apart from the ice and undersea sections the values were broadly the same. If I was doing a sequel I might try Japan, Peru, Australia and Antarctica, with polar bears. I'd like to represent Wales somehow too. 
 
When we went to 16x16 pixel graphics we needed a new map editor. Steve wrote one on the PC. The graphics were done in DPaint, also on the PC. Phillip did most of the original graphics and I programmed all of the meanies. I do remember that we weren't happy with the Coyote's speed so I went to London to meet up with Jaz Rignall to see what he thought of the demo. The result of that discussion was that I speeded up the Coyote. This changed the jumping speed, gravity and the sideways accelerations and speeds, basically they're all related. After we were happy with that I tried to play one of the first developed levels and realised that the jumping meanies were affected by the gravity change and I had to recalibrate them. The next related area was all of the ice weaponry, all of that needed adjusting too. Best to get your physics constants all sorted out early!

Fortunately making the Coyote quicker didn't mess up the jumping gaps as his overall jumping range was kept similar, otherwise we might have had lots of map adjustments to make as well. Fire and Ice doesn't require the pixel-accuracy of, say Manic Miner, otherwise we'd have had to be even more careful. The Coyote top speeds were all in whole pixels, the accelerations had accuracy down to 65536 of a pixel, as did the co-ordinates. The plot routines clipped off the sub-pixel positions. 

The majority of tuning adjustments came from adding more meanies until there felt like too many, then taking one or two out again. Meanie start positions were entered into my assembler code, not the map editor, so I kept a tight rein on those. Similarly the strength of the big bosses needs to be regulated carefully. I hate meeting seemingly invincible big bosses, especially if you can't see you're making progress against them. I do like the Flying Shark boss tanks that start flaming so you can at least see you've damaged them.

We did end up making the first icy lands as easy as possible, most meanies don't fire back, just because the control mode is a bit of a handful on ice, and I was not trying to create a shoot-em-up. The team's input on this game was vital for more variety. Phillip and Jason especially were coming up with plenty of ideas.

Uridium 2




This one was the toughest of them all.

We started off with a dual-playfield version. This gave us 7 colours for the front layer, and 3 for the back lower layer, which scrolled in parallax. Phillip Williams created a prototype ship which looked nice, though with the limited colour choices it looked a big cartoon-like. He did get the scale nicely. We then realised that most of the moving objects would also have to come out of the same 7 colours, and that made them blend in all too well. Reserving 1 or more colours for obstacles was also impractical, as was reserving some colours for the sprites.

The smooth parallax scrolling did look lovely, but we reluctantly decided to use the 5 bit-planes for 1 32-colour layer. Unfortunately Phillip left Graftgold shortly after this so he didn't get to do any 32-colour backgrounds. 

I was having trouble getting nice graphics from the guys that I thought we should be capable of, given that this was our first 32-colour game. Since the background graphics define the whole game arena they've got to be good. Other companies were getting the hang of the extra colours.

They graphics also have to be functional. It has to be obvious what bits of the dreadnaughts not to crash into. This might be signalled by big shadows being cast, and also their own colours. It turns out that the colour choices I made on the C64 and the starkness of the graphics were what the game needs, and all the extra colour choices were muddying the waters.

I also wanted 6 different styles for the backgrounds, but we struggled to get even one. If the background obstacles are not obvious then the player will get frustrated crashing into them. We managed to enlist the services of Stephen Rushbrook, who was quite local.

The background graphics were made from 16x16 pixel characters, drawn with DPaint, and then fed into the PC map editor. The maps tend to have to be at least partially put together by the graphics artist because they have to design the blocks and make larger constructions. No-one else is going to be able to piece them all together, it's like a custom jigsaw puzzle where all the pieces are square. You only have the pixels to see how they fit together.

If you're not the artist then you might use two blocks then you might map pieces together that happen to work now, but if the artist then changes a couple of blocks then your incorrect use of them might break. This is why I was happiest on the C64 doing my own graphics, maps and programming!

Anyway, Stephen Rushbrook tuned in to what I needed very quickly. He started with a graphics set that ending up becoming the second set of 4 ships. It had very clear lines and bright almost glowing wall pieces. This set actually was intended to be the first set, but due to publisher demand for easier ships to play on, it got preceded.

This is where the playability gets tuned. You can't necessarily change the levels that you've done to make them easier, you might end up throwing away some of the drawn features that are a tad too difficult, but no-one likes throwing away good work, so you move it on up and try to then draw something that's easier to play from scratch. Unfortunately Renegade were having trouble playing the early levels so kept asking for it to be made easier to start with.

We ended up with a new first set of ships, which looked a bit smarter than the old first set, but with no walls at all on the first couple of levels, then we added some on the next. Since we kept the next set of 4, the first level of those, which was to be the easy opening level of the game, gets easier again. Somehow Uridium without walls is like a tank without any ammunition.

By the time we got to the fourth set of 4 ships, Mr. Rushbrook was getting into his stride and came up with a solid-looking set of graphics, and some evil laser turrets. At this point it was my turn to try and make the game easier. I was play-testing all the levels and with the horizontal and vertical scrolling, the real estate was getting large. A new problem was starting to occur, the levels were easy to get lost in. A smarter bunny than I might have put more than one landing strip on each level to balance that out, or helpfully marking the final landing strip(s) on the radar, but we started to think that navigation was going to become a bigger part of the game. So be flexible with the game design if opportunities for expansion present themselves.

If you have an end sequence, you tend to want to make the player really work for it, so the final level(s) tend to end up being a little harder than they ought to be. When the development time is up, you have to go with what you've got. All you an do is rearrange things a bit. You don't want a really tough bit in the middle and then it gets easier again, you'll always lose some people who give up.

I can't remember now how many ships we gave away on the magazine demo disks, but some people have reported that they couldn't manage those levels. They were only easy levels too. Unless your game adapts to how well the player is doing then there's no way to match up with everyone's abilities, and if you do try to adapt then you end up with players that know they shouldn't try too hard and the game will go on easy on them. Plus, no-one gets bragging rights. Wouldn't work at the Olympics, would it? "I decided not to run so quickly, so everyone slowed down for me and I got the gold." 
 

The Final Words 

Sorting out the playability and progression of a game is very important. Trust your instincts. As the game designer you've got an edge over most other players in learning to play the game first, and grading the difficulty is still the same comparing one level to another. Just make sure you can do all of the levels, preferably in a single session, but at least playing them one by one. If you lose 10 lives getting through one level then it's too hard! With a little practise you should be able to clear each level without too much hassle.

Let some other people have a play, watch them, help them, and listen to their feedback.



 
 
 
 
 
 

Cartesian and Polar Co-ordinates

Introduction

I started to talk about Cartesian co-ordinates in a previous blog, and thought I'd better clarify for any non-mathematicians what that is, and then add on the concept of polar co-ordinates, which I started using sporadically from Morpheus onwards, i.e. 1987.

I'd been playing Gyruss in the arcades, and then on the C64. On my trip to Chicago in 1986 to get Uridium started on the 16-bit machines, I met the programmer who wrote the C64 version. I got interested in the circular patterns that Gyruss produced.

That was a real rushed trip as I had to get a passport and a US visa in about a week. This required trips to find the Peterborough passport office and the US embassy in London (without Sat-Nav!). Probably another blog-page could be devoted to Chicago.
 

Cartesian Co-ordinates.

We use Cartesian co-ordinates on maps and screens, amongst other things. In a 2-dimensional system we use 2 co-ordinates, by no small coincidence. Conventionally we use X for the horizontal, and Y for the Vertical. Relating that to the memory in the Commodore 64 that is used to display the screen in 8x8 pixel characters, the top left character is the first byte, the next byte is to its right, for 40 characters. After 40 bytes we get to the second character down, on the left edge, followed by another 39 bytes across.  
 

World and Screen Co-ordinates.

For a 2D scrolling game on the C64 we would have the whole map laid out in characters in a big buffer. This buffer would not be in the 16K video RAM. The map might represent an area of 6 screens wide and 4 screens deep, as a Gribbly's example. That's a buffer 256 characters wide by 80 deep, so some 20K of the available 64K of RAM. That's an estimate, I don't have my listings to hand.
 
We need to know where all of the game objects are on the map, so we need Cartesian world co-ordinates that allow us to index into the map. You might need to do that for background collision detection, and to stop objects from leaving the edges of the map.
 
It makes sense for the world co-ordinates and screen co-ordinates to be the same sign so that you can quickly translate from one to the other. The player's position in the world decides the screen scroll position, then that in turn decides everything's on-screen relative position, by a simple subtraction of their world position from the scroll position. So there's a strict pecking order. Always get the player done first, work out the "camera" position, i.e. the scroll position for the screen, then work out the rest of the objects. 
 
Again for Gribbly's, once you work out the screen relative position you can decide whether another object is on screen or not. If it's off-screen, it doesn't need a sprite. I was running 16 objects maximum, but sharing 5 sprites to display them all, so they had to share. Once an object was on screen it would keep a sprite until it left the screen area or got bubbled. That led to some brutal decisions about what happens to a sixth object trying to enter the screen area.
 

Joysticks and Screens

Non-proportional joysticks use 4 switches to detect Cartesian X and Y movement, or lack of, in 4 directions, giving 9 valid combinations, including centred. Some crude control modes just apply speeds to the player based on the joystick input. I always preferred to apply accelerations  to the speeds before then applying the speeds to the position,  so that the speed is applied gradually. You can also apply a different braking rate if the input direction is opposite the current movement direction.
 
Whilst there have been polar control modes, such as Lunar Lander or Asteroids, these control rotation and speed by button, it is seldom that we saw a circular proportional controller in the early days. Potentially we see those on some modern game controllers, though they might still be square, so need some software modification to the values received to make the control circular.    
 

Polar Speed

In order to get into polar speeds, you have to start manipulating vectors and work out sines and cosines. What we want to achieve is to represent the same overall speed at arbitrary angles, not just up, down, left and right. This involves working out the Cartesian X and Y components, to sub-pixel accuracy, of arbitrary angles and speeds.
 
Now the C64 doesn't have any floating point support, and not even a multiply instruction. Fortunately, I wasn't really thinking mathematics, I was just thinking that I wanted to get some pretty effects  You have to be thinking in hexadecimal for ways to do things. The key is always the Power of Two. I needed some sines and cosines, and a way to multiple them by speeds to get pixel distances.
 
You also need to be able to convert from Cartesian to polar so as to work out in which direction an arbitrary object lies, and how far. We managed to find an approximation routine that was much quicker than doing the big calculation. Also, polar vector addition is easiest carried out by converting to Cartesian, adding, and then converting back to polar. Gravity sometimes needs to be applied to objects that are moving polar. You can choose to switch from Polar to Cartesian once you've started. It's rare that you want to continue with polar movement in an environment with gravity. That's a major difference between a top-down game and a side-on game.

It's more useful to know the polar direction to a target than the distance, though the Paradroid 90 robots could only "see" a certain distance. If your polar calculations are accurate rather than fast, then you could use them for collision detection. Our 16-bit algorithm was accurate to about 10%, which is enough for visibility, but we didn't use it for collisions. The algorithm has been published, we didn't invent it, but it was based on making a guess and looping about 3 times improving the guess, which involved a square root calculation, so we didn't want to be doing that too often. Nowadays you can get fast accurate answers in floating point.
 
Sometimes you might not be moving in the same direction as you are facing. Imagine a drift car driving round a track, so you might want to store an object's facing direction separately from the movement. The two will want to align over time, but certain actions might cause them to differ.
  

Morpheus

I had been playing an upwards scrolling top-down shoot-em-up on my Amiga and something caught my eye. In the grand scheme of things it wasn't particularly important, but it irritated me. A ground-based turret fired 8 bullets at once, spaced at 45 degrees, so up, right, down and left and the 4 diagonals. In the real world, the diagonal bullets would come out at the same speed as the others, forming an octagon, but these came out in a square shape.
 
Now I can see that the initialisation would be minutely quicker when setting the 8 bullets' speeds. You just use zero and one value for the various X and Y speeds, either negative or positive. If you just had a lower X and Y speed for the diagonal bullets, which you can work out in advance, you can get a better pattern, and equalise the overall speeds of the diagonal bullets.
 
I got to thinking then, that I'd like to do some pretty patterns with pixels firing from the middle of the screen, This all ended up as the title screen on Morpheus, as well as the background stars for the game, and is all part of the control mode too.
 
I decided that I needed some sine and cosine values to represent a number of angles. Now you might have been told at school that there are 360 degrees in a circle. I am here to tell you that they got that wrong, there are 256. At least there are in the computer world, the Matrix, if you will. Looking up values in a 256 byte table is a nice easy task for the CPU, and I believe I repeated 64 values from the beginning to be able to add a quarter of circle to the sine values to get the matching cosines.
 
I sat there with my hex calculator and worked out the hex values for the 256 direction sines using SOH-CAH-TOA that we had been given at school: Sine equals Opposite over Hypotenuse, Cosine = Adjacent over Hypotenuse and Tangent = Opposite over Adjacent. We know the hypotenuse is a constant sweep of a clock hand round the clock face. Due to the low level of accuracy, some 8-bit values came out the same, but when the sine of two next-door angles came out the same, the cosine would be different, and vice versa, so there was no duplication.
 
I then had to choose a scale for the speed. This is largely arbitrary, but depending on our calculation method we need to work in whatever units make the CPU maths easiest. Again, we want to be working to a few binary places of sub-pixels to get some accuracy. Nothing much is going to be moving more than 8 pixels a frame, bearing in mind that we are moving everything at the magic 50 frames per second. Anything going at that speed will be across the screen in less than a second. 
 
I do recall that for the Amiga polar system I considered increasing the number of possible angles to 1024, another finely-rounded number. The thought of working out that many values and typing them into the assembler put me off, we stayed with 256, which I still re-calculated to higher accuracy. The polar distance of 1 pixel was $0400, and the sine table values were 14-bit signed numbers this time. When the polar speed was multiplied by the appropriate sine value, we got a 32-bit answer with the number of pixels in the top byte, and the part pixels in the rest. We would then have arithmetic-shifted the number 8 bits to the right to give us 16 bits of pixels and 16 bits of sub-pixels. The world and relative co-ordinates would be in that scale, giving 10 screens wide using the positive numbers.

I also remember keying in the original set of 256 8-bit values for the sine table, and testing them all. There were a few typos which showed themselves up when I rigged up a test-bed to fire a group of pixels at slightly different angles at once. 

I think Steve Turner found all this polar nonsense rather bemusing at first. Sure, I could get some pretty explosion effects, but what was the point? Little did we realise that soon enough we'd be doing MotoX on the PlayStation and we'd be needing the polar knowledge.
 

Intensity

The player and drone ships in this game use polar movement. The joystick Cartesian input is converted to a polar desired direction and the player ship swings round to that direction in a smooth curve. I was just trying something different. The drone follows a polar path too, which can be seen if you give it a new destination while it is in flight.

The meanies are all using polar movement to track the crew, though the final fizzing meanies take a zig-zag path to the player ship. They still need to know the polar direction as they are modifying that target direction for their flight.
 

Paradroid 90

The robots in this game are using polar movement and firing. The heads of some robots swing round too, and line-of-sight is used by most robots. Hence you can sneak up behind many of them. Since many also have hearing, if you fire then they will turn to face you, and fire back, of course. The polar routines are used all over the place to allow the robots to fire at any angle to hit the player. They rarely miss.
 

Fire and Ice

Polar movement is used for the various ice weapons, but then Cartesian gravity is also applied. You can see the multiple ice bullets fire in a neat spray but get distorted by gravity. There was a lot of simulated physics going on in this one as I encoded the ground characters with slopes and allowed the ice to roll down the slopes.

The trickiest bit was stopping the ice still when it rolled slowly into a valley, as the small accelerations due to the two adjacent opposite-slope pieces kept the ice oscillating.  The puppies also apply a bit of physics to be able to jump to another platform. It's the same physics equation that the Gribblets use, which also make an appearance here.

If you know what gravity acceleration you have, and you know you want to jump to another height in 16 moves, then you can work out what initial velocity you need. I worked this out at run-time every time, but actually in Gribbly's there are quite a limited number of possibilities so I'd have been smarter to store the limited number of answers in a look-up table. I still think it looks really clever when the Gribblets or puppies jump upwards or downwards.
 

Uridium 2

The homing missiles all use a polar homing algorithm, the Uridimines do not. I'd seen the homing missiles of the arcade game SlapFight, and thought that they take a lot of the hassle out of the game, but then noted their cheeky nod to the plight of polar homing. Since they can only turn at a certain rate, then if they skim past a target they have to go round again, and can quite easily miss again. They seem to let the homing missiles come out straight a fair way before chasing the target. They may be including a minimum distance from the target before going into chase mode. 

My solution was slightly different: initially the homing missiles come out of the Manta forwards, and then select a target. If there isn't one they'll go forwards until there is a target, or they leave the screen, this doesn't usually happen as there are nearly always plenty of targets. If the homing missile manages to go round 360 degrees on full lock it knows it must be going round the target, so it goes into enforced straight flight for a couple of cycles and then starts homing again. You might only see that happen once a game, it happens real fast, and you're probably too busy to notice, but you would notice a homing missile going round and round not hitting the target.
 
I did one time get interrupted at work by a guy's email asking how the Uridimine algorithm worked. The email came to me via the managing director and HR, so that got rather embarrassing. Please don't do that to people.
 
Just for the record then: the Uridimines simply accelerate by, say, 1 pixel per cycle in the X direction towards the player, and do the same in the Y. The X and Y speeds are then capped to within, say, 5 pixels a cycle. It's really dirty, and rather embarrassingly means they move diagonally faster than horizontally or vertically, where they oscillate.  Fortunately you have nothing to compare them with because the Uridimines all chase the player from the off! The top speed has to be less than the Manta's top speed, as they are intended to tempt the player to rush off at high speed, or loop to height to avoid a collision. I wish I'd done an enemy ship that released a whole swathe of them. Maybe next time... I can't think of a reason why they shouldn't go high and be able to take out the Manta in a loop either.
 

3D Cartesian Co-ordinates.

All 3D games that allow flight will be using some kind of 3D polar system, along with their 3D Cartesian co-ordinate system. As well as an X and Y co-ordinate, we add a Z. Conventionally the X and Y usually go across the ground surface, and Z is the height.
 
There are 2 different ways that have been used to do that, wouldn't you know it?  They call then left and right-handed systems. If you keep X going left to right and Z going up, in a left-handed system the Y comes towards you, in right-handed it goes away. DirectX uses a left-handed world. I'm fine with that; it's about time us left-handers had a say.

Then there's the screen pixel layout. Traditionally we managed with X going left to right, and Y going top to bottom. You can use the X and Y co-ordinates to simply and quickly (thanks for the catchphrase, Rich) calculate the address and pixel position for plotting. This all changes on the PC, but that's another story, for another blog. Also maybe the story of how we can simply build a ladder to the moon (out of matchsticks). Easy to ask...

My issue with 3D is that everything has to be done properly. Uridium cheated in that the Manta bullets could go high to hit the enemy ships that flew over the player, and could go low to hit ground targets. Viewed directly from above you can't tell that's ambiguous. Maybe the Manta is firing two bullets, one high and one low, with Bluetooth so that if one detonates, so does the other? Hey, if one photon can pass through two slits then anything's possible! 

If we ever get a 3D Uridium then there will need to be some extra guns on the Manta, and the control mode is going to be more extra-dimensional. Lucky there are more controls on a game controller these days.
  
 
 
 
 
 
 
 

Sounds Interesting

Introduction

Sound effects add a whole extra dimension to a game. That was easy to hear in my C64 game development days. I usually waited until most of the game was written, play-testing in silence, before commissioning the sound effects. This also kept the peace in the development "office" (Steve's dining room). We didn't have a sound system in the room either, we worked in silence most of the time. Some days we didn't speak at all, we were so deep in concentration.
 
I say "commissioning the sound effects" because I didn't really take to sound at all, it was too mysterious. In return for my play-testing time of Steve Turner's Spectrum games, he wrote the sound routine, the music, the music player, and designed the sound effects of most of my early games.  
 

Dragon 32

My first games were on the Dragon 32, and whilst I can't remember anything about the sound routine itself, I do remember that Steve Turner designed it, and may have written it too, based on his ZX Spectrum routine experience. Our early Seiddab Trilogy games mostly required only firing and explosion sound effects, fortunately. In order to keep the music and effects running smoothly; you need to have an interrupt routine running every 50th of a second and on the Dragon 32 and Spectrum we would loop for a while sending values to be output to the speaker. You might regard these as very crude sound samples, only 8-bits, but they were algorithmically generated rather than recorded. To get the best quality you would need to use all of the CPU time to continue to play sound data. Clearly for a video game this was not possible: the graphics were taking most of the time. The sounds were therefore compromised by only playing data for a short time every 50th of a second.   
 
Both the Spectrum and Dragon had rather rudimentary sound capabilities then, intended more for simple beeps and boops, but the C64 had SID.
 

SID

The Commodore 64 SID chip was a new type of sound generator for us. It had 3 sound channels so could produce 3 separate sounds at the same time. It also produced its own waveforms: square pulse waves, sawtooth waves, triangle waves and noise. In its simplest form then, the SID chip can also produce the beeps and boops of yore with ease. To get better sound effects you have to algorithmically sculpt the frequencies produced over time, and also sculpt the volume over time, called the Attack, Decay, Sustain and Release, or ADSR.
 
Steve chipped in (pun intended) again and wrote the sound routine, Each sound effect would consist of a few bytes of control data. You would initially set the waveform type, the Attack, Decay and Sustain figures and the frequency, and then every 50th of a second the sound routine would run and modify the frequency and trigger the Release phase at the required time. We had an inner and outer loop counter, and frequency changes to apply in each loop. 
 
We found that you need to think about how you use your 3 channels for sound. Do you want sounds to interrupt each other? Do you want some to take priority over others? Typically a sound effect was assigned a channel to run on, and a priority, so that less significant sounds would not be sounded if the channel was playing something important. You can use the sound effect number as the priority if you're happy to shuffle the sounds around to get it right.
 
For explosion type sound effects you would select the noise waveform, and quickly ramp up the volume to full and then let it slowly die away. For firing sounds we worked out that the player firing sound will be used a lot, so it mustn't be too irritating. We tended to go for softer triangle wave effects rather than noises. I also had another agenda for SID: it could produce random numbers, generated on the 3rd channel only, we could set it to noise mode and read the produced value. I therefore made sure that only noise waveform effects would be sent to the 3rd channel, and when it wasn't busy it silently played high frequency white noise to itself. This caused a good fast turnover of un-reproduceable random numbers. 
 
I did try to come up with some sounds for Gribbly's Day Out, but I found it difficult to visualise how sounds are produced from the few numbers we were feeding in. Even the simple bubbling sound, I knew what I wanted, but couldn't see how to get it. We didn't have a sound editor, we just used a C64 running the sound routine and used to set up the numbers for sound effect #1 with my ABMON debugger, and trigger the sound with the joystick button. When we got it how we wanted it, just write the sound parameters down and key them into the source code table for the next assemble.
 
In despair then, I asked Steve to create the sound effects for me, which he did in very little time, probably a couple of hours. Typically we might have 20 to 30 sound effects in a game. The game was almost complete, which allowed me to determine where I wanted the sound effects, and what sort of sound effects I wanted. The sound effects should all fit together, so creating them all at the same time is a good idea. You can then set up the effects in the game and see what it's like. You can quickly tell if any are irritating or there's too much going on, or not enough. Less so if you are playing music as well, of course. Suddenly the game comes to life.

When coding the sound routine, you will need to know what effect, if any, is currently running on each channel, and this will need to be cleared when the effect finishes. Likely your pause mode then will need to switch all the sounds off immediately. It shouldn't be necessary to restart them when you continue, more sound requests will be coming in pretty soon. If you have a master volume control in either the hardware chip or coded into your software then you could nicely fade the effects out.
 
People have told me that the snapping sound that SEON made was particularly menacing.  
 

Paradroid

Every game got a clean slate for the sound and the music. Generally our sound routine itself was the same, since the hardware was the same, doing the same job. Occasionally something clever turned up in other games, such as Impossible Mission, which had speech. We suspected that quite a lot of memory and processor power went into that, so we didn't feel a need to investigate.
 
As Paradroid developed, I was realising that my use of the available RAM space was going to be tight. I had implemented a dictionary system for the text, which might or might not have been as economical as just writing all the text out long-hand, but programmers don't necessarily think like that, we want to write some new code. There were a lot of sprites for the robot pictures. I had tried to save space with a routine to generate reflected multi-colour sprites on the fly. The deck maps were also done in a new way and were quite expensive.
 
Now us programmers don't like to take working code out, so when it came to writing some music for the title page I only had 150 bytes of RAM left. That's just not enough for a decent tune. The game was almost complete and I wasn't going to remove anything.
 
At this point so people might say: "Get in there and optimise something then." We tended to optimise the code for performance already, not so much for space considerations, and since we didn't want to detrimentally affect the performance, we would not want to alter existing working code. I've never followed the philosophy of just getting something working and optimise it later if necessary. Everything has to be top notch all the time. If that makes me an idealist and a perfectionist, then I'll take that. 
 
Steve had done most of the sound effects with his usual efficiency. I felt that I also wanted some lower key sounds for the backgrounds. If you watch Star Trek and listen when they're on the bridge or in engineering there are sounds going on all the time. It helps to make the place sound functional. You don't need a full factory production line belting out all the time, just something gentle in the background. Similarly when the Daleks are on Doctor Who there's always a pulsing heartbeat going on.
 
I decided to have another go at creating some sounds. Once more I struggled, and in any case creating a lot of little sounds would require quite a bit of memory, which I didn't have, and likely a control routine to manage the sounds. I started messing about with some of the loop and frequency change counters, putting much bigger values in than I should. This started causing the frequencies to wrap around, and the effects lasted much longer. It was producing some lovely gurgling sounds. I started taking notes of the values and then almost randomly altering them and getting more nice sounds, some like chattering robots. I then had my sound effects for the title screen instead of music.
 
The background deck sounds in the game are low priority. Once a firefight starts, the louder firing and explosion effects take over, and you don't notice that the background effect has stopped. As soon as the firing stops, the background effect comes back in.
 
When the deck is cleared, the lights go out and the deck sound effect stops, giving an eerie cold and empty feel to the place.
 

The 16-bit Sound

When the Atari ST and Amiga came along, they were playing sound samples. Suddenly then, you need a way of creating these samples, and capturing them. They simplified the sound routine somewhat because you no longer had to control the ADSR, nor the frequency alterations, that's all included in the sample. You just tell the chip to play the sample at a given frequency, which you probably would fix for all the effects anyway, and shut it off when you run out of sample. I believe we had the option to control the ADSR still,, in case you wanted to loop a shorter sample, and frequency alterations for a bit of tremolo on the music instruments.
 
The Atari had 3 sound channels, and the Amiga 4, split into 2 left and 2 right. This made for slightly different sound channel assignments in each version of Rainbow Islands, Paradroid 90, and Fire and Ice. I believe I did include the option to trigger sounds to left or right channel based on the screen position of the object making the sound on the Amiga. It would have been nice to have a left-right pan register for each channel.

Jason Page would likely have written our sound and music routine, which runs every 50th of a second on an interrupt. You don't want that running inside the main game loop in case there's an overrun, and the music might repeatedly stall. The sound routine was playing back samples rather than relying on fixed waveforms, so the effects were more created up-front on a separate sound editor, though I suspect that we also still had all of the C64 loop and frequency change controls, and maybe the ADSR volume envelope controls, so that we could get multiple sound effects from the same sample, which could have been just a short simple waveform.
 
Once again, the priority of the sounds effects becomes important. You don't want to interrupt loud or long sound effects with shorter ones as it becomes obvious and shows up the limitation of channels. Everything should run cleanly and smoothly. It's better for a low priority sound to not come out at all while, for example, the Rainbow Islands "the water's coming - Hurry Up" siren sounds. Therefore, when you make a call to request a sound effect, the routine you call should check what is running on the selected channel already, if anything, and gracefully decline if something more important is happening.
 
While on the subject of Rainbow Islands: if you've played it, the game displays "GOAL IN!" when Bub completes a level. This has 7 letters in it, and they are coloured the same as the gems, in rainbow colours, red to violet across the screen. It's a little hint to how the different coloured gems are produced. When we got to do the U.S. release of the game, the publisher didn't think much of the slightly quirky Japanese phrase and insisted it be changed to "GOAL !". I did try to point out that 2 colours would be missing then and the timing would all be messed up, but they insisted some more, so we dropped the "IN". I am disappointed that I didn't think to at least change the "IN" to "!!" so there were still 7 characters.
 
Here's the code we had to put in:
 
  SetGoalIn               ; Select a set of delays for pattern
If NTSC=No                ; If NOT the American version...
  Activate InitN          ;   Give me an N
  Activate InitI          ;   Give me an I
EndC                      ; End If
  Activate InitL          ; Give me an L
  Activate InitA          ; Give me an A
  Activate InitO          ; Give me an O
  Activate InitG          ; Give me a  G
  Delay                   ; Finished for this game cycle
  Repeat   6*Second       ; Wait for 6 seconds
  Activate InitX          ; Give me an X for eXclamation mark
  Delay
 
The I and the N only get created if it's not the NTSC American version. The letters are generated in reverse because they are each inserted into the object linked list directly after this object, and that restores the sequence to the correct order. There are other places I had to alter to move the 5 remaining letters together too. Was it really that important to de-quirk the Japanese game?
 
It still irritates me that publishers think they know best. I'll need to do another blog page sometime about all the things they asked us to remove and whether we did, or just hid them.
 
I seem to have digressed from the sounds. Let's move on.
 

Fire and Ice

We wanted to have the Coyote playing the piano on the title screen, and Jason had built some barking into the music. Philip Williams, who was lead graphics artist, asked whether he could make the Coyote bark in time to the barks in the music. The short answer was no, but the longer answer was, have it done in a few minutes. We wrote a little control routine to trigger some barking frames of animation when a certain "instrument", the bark, appeared on one of the sound channels. We also had to monitor the music player to check the tune was still playing, so that we could stop the piano from rocking when the tune finished.
 
I was playing Super Mario Bros.U and liked the way the little meanies did a shuffle in time to the music. I thought, why didn't we ever do that? Then I remembered that we had, just not in the game itself, only on the titles page. 
 
The CD32 version of Fire and Ice (anyone got that and a CD32?) had CD tunes that Jason went away and recorded. There's at least one tune for each world. In this case, our Coyote has no idea when the barking sounds might be playing on the CD. I don't think we got into figuring out the timings and coding them in. 
 

Virocop

After I finished Uridium 2 on the Amiga, and had my soul crushed by the cancellation of the in-progress CD32 version, I stopped working on my own games. I assisted with some of the Virocop features, mainly the big-boss sections. Incidentally, Virocop had a last-minute crash bug to find, right in the last big-boss screen. We spent ages hunting that one down, and it turned out to be a sound request call for a sound effect that didn't exist, so it threw random data at the sound routine, which was enough to kill it in an interrupt call.
 
 

PC Sounds

Graftgold moved on to PC and PlayStation development. We had successfully converted Rainbow Islands to the PC, PlayStation and Sega Saturn, written in C.  We then set about writing a tank game. Everyone in the company was working on the same game for a while, in an attempt to produce something bigger than before. We were using the MotoX 3D landscape engine that Steve had developed, and had also migrated from DOS to Windows, and seen the introduction of the first hardware accelerated graphics cards. It was truly a time of change.
 
I worked on a number of system routines during that time, including the sound routine. A 3D game called for a more sophisticated sound routine, I felt. The PC by this time seemed to be able to cope with mixing as many sound effect samples together as we cared to throw at it. We could also assign a stereo position to the sound effect (5.1 hadn't quite arrived!) so we supplied the horizontal screen relative position of the effect and the distance from the camera to the sounds to reduce the volume, plus I added a delay at the start of the sound based on distance: "If you hear the bullet, you're already dead!"
 
I also felt that a lot of games suffered from identical samples going off repeatedly and starting to sound very mechanical. I chose to optionally add a small amount of frequency change to bullets and explosions effects to give some variation. This had to be optional because the music player drove the sound routine, and you don't want the bass guitar to get randomly de-tuned, trust me. For aircraft I also calculated and stored the distance to the camera so that I could effect some Doppler shift on the engine sounds based on speed relative to the camera. I expect everyone's doing that kind of thing now.

By this time, Jason had moved on, and Lee Banyard was doing our sound effects and music. He also did our Empire Soccer effects and music. I have no idea how he was doing the effects, he just used to disappear into his room for a while and come out with the effects. Remember, this pre-dated the popular interweb as we know it, which might be a good place to start and end these days. 
 
For sounds effects in my next venture I shall just the get computer to say: "Alexa, what does an AK47 sound like?"