Pages

Wednesday, 15 March 2017

Part 22 Building a shader editor

Graftgold Memories. 

Spectrum Music.

Making sound on the original Spectrum was a challenge because it had no sound chip just a port which you could set to 1 or 0 to make a faint click.  Sound is made up of waves so to make a sound you had to switch the sound port on and off in a regular pattern.   For example setting the port to 0 for a while then 1 for a while would produce a square wave. The pitch if the note is related to the time interval of the cycle of on/off.  Here lies the big problem for a sound programmer. A musical note mid keyboard is in the area of 512 cycles per second, about 2 milliseconds. To produce a tone you need quite a few cycles so the pattern is established. In computer terms that is a huge timescale.
A smooth game needs to run at least 15 frames a second. If the CPU is used just to make a note it is not doing any of the vital graphic processing let alone the game processing.  With no graphic chips the poor old CPU had to do everything itself.

There are a couple of ways to solve this problem. The first just gives the sound routine a certain time to make a note or sound effect each game cycle. So instead of a steady note a series of short notes is produced. Remarkably the ear seems to paste all these notelets together and a continuous note is heard.

A second really clever way used for the first time I believe in Technician Ted was do to something else useful while the sound routine  marks time whizzing round a counter loop. Instead of just looping it can do simple repetitive tasks at the same time. The sort of thing I mean is clearing the screen or copying a back buffer to the screen.

Getting Better Sound.
Just switching the port on or off produces a beep which is pretty uninteresting. If you change the proportion of 1s to 0s  you can change the square wave to alter the harmonics the ear hears. The volume also changes slightly being loudest when there was equal length of 1s to 0s.  The other thing easiest to change was the frequency by just slightly altering the loop length.

More Than One Note At once.
On the face of it the beeper could only produce one note at once but I figured if you superimpose two notes on top of each other and did a logical operation you could simulate two notes.
For example An octave harmonic.
Note 1.               0000000000111111111100000000001111111111
Note 2.               0000011111000001111100000111110000011111
 Result                0000011111111111111100000111111111111111

I did this in the Avalon music, devoting the CPU to the music and having a loop that counted down two different times simultaneously. I then flipped the sound port value whenever only one of the counters reached zero. I had to be careful not to change the time the code took when a counter reached zero so made each path through the code the same number of machine ticks (T states).

I think I was the first programmer to get the beeper to play proper harmonies. I found the routine sounded different on newer Spectrums , I didn't find out why, and some of the harmonies were distorted. I used the same routine for later games but changed the two notes to be almost the same note. This gave a thick synthesizer sound were the square wave repeatedly moved in and out of phase. This was my trademark sound on the Spectrum used for all my later games.

Sound Effects.
I was not a big fan of  beepy in game music so was not prepared to lose vital CPU  time to put low quality music in the game. However I considered sound effects vital, they really enhance game events and make a game come to life.  My SFX routine contained a simple loop but was driven by a data table. It had a start wavelength value and a change in wavelength value so each time the routine was called the note changed up or down. It had a cycle count which said how many times to change the note. It also had a type value which said what to do when the cycle count reached zero.  It could reverse the sweep or reset the sweep by changing the start note.  Finally there was the number of times to repeat the sweep.

These options allowed me to get all sorts of beeps, whoops, warbles etc. Their was also an option to use a random value by taking data from the ROM and applying the low bit to the port.  Some ROM
areas contained data tables and gave interesting effects. I would spend ages changing the start point with a monitor while the sound routine was running "tuning" up the sound effects by altering the start point for the ROM or the various data values.   We found that accidentally allowing the wavelengths to wrap  (ie adding 2000 to E001 would give 0001) gave really interesting effects. The droid voices chattering in Paradroid are an excellent example of this effect.

I sometimes used to amplify my Spectrum sound through a 2 X 12 speaker cabinet (with no amplification) as the beeper sound was very thin and had no bass.  The lasers and explosions in 3d Star Wars were superb through the guitar cabinet. I was very disappointed at the marks for sound in the Crash review, if only they had listened on headphones or through a proper speaker. 

Creating Tunes.

I played guitar in a rock band and used my guitar to make up most of the tunes that I composed for games. As The Spectrum was best at playing a single note at once I used to put maximum variation of tone by putting in lots of arpeggios across several octaves  rather like "tapping" with both hands on a guitar string.  The Ranarama theme tune is a prime example of this. I would play a bit on guitar then code the notes into hex codes. These were used as an index to a wavelength table. I just used a crib sheet of note to code values to convert music into data codes. I would then invent the next section and code it in.  As music repeats quite a lot I coded each section of the music then coded data that said which sections to play. This saved vital space on the Spectrum. I didn't usually try the code until I had completed the tune. I would then try it out and there would be many mistakes. Also some bits would sound weak on the Spectrum so I would play about with the notes to add interest. A tune would take me a few hours but I would revise the tune over several days to improve it.

It was interesting trying to recreate some of the Spectrum tunes on guitar. When I wrote them I never played them end to end just in bits. Then I added notes to make them sound more interesting. This made them the musical equivalent of tongue twisters on guitar and it was fun and challenging learning them as guitar pieces.

Deepest Blue Progress.

Last month I managed to get mega bases appearing in the game but the collisions were not working properly and guns on the base were not working.  I debugged the collision system and found some inaccuracies for large objects. I changed the algorithm that imagines a line joining the centres of two objects and loops through their parts to decide whether any part  sticks out enough along the line to touch the other object.   At the moment I am treating spaceship parts as deformed spheres which can be stretched into lozenges and/or squashed into elliptical cross sections just by having different XYZ max and min sizes.

The next step was to get the guns working. I realised that my power system did not cater for mega structures which were like several ships bolted together. The power was totalled at ship level so I revised it to sum the "ship" power so it would work for a mega base. Hmm what about mega ships, I will have to add those one day but first things first. I tinkered with the power system until the bases had power. I managed to get the turrets turning towards me as I flew by but they refused to fire. I found my friend or foe system was going a bit wrong so started to fix that. I then was ill for a couple of weeks feeling to muddle headed to code safely. You get to the stage in a game where you do not want to muck things up.

Instead I started playing around with shader effects. The online versions of Shader editors all seem while I to be OpenGL based so if I get an effect I like I have to recode it for Direct X shader language. It is pretty similar but annoyingly different in the names of standard calls. After a while of doing this I thought it would be useful to have my own shader editor as part of my graphics editing utility. I wanted to be able to choose a game graphic and then choose a shader to apply to its drawing. I wanted to be able to change the shader code recompile it and see the effect of the change.  I already had code to try a shader out and to save out compiled shaders and data tables to I port into the game.

So I added a giant text box to be able to display the text of a shader and added a few buttons to allow me to save or load or compile a shader. I decide against compiling while I type (as some of the online editors do) as I had frozen my graphic card many times while halfway editing a line. I was amazed at how few lines of coding it took to achieve this. I already had coded a multi line textbox control which had basic word processing functions. I had only used this for single line text entry so although tested for multi line when written had a few bugs when things had changed. These were soon fixed and I was tempted to add standard functions such as cut and paste, undo, redo but in the end decided it was unnecessary as large changes could be typed in visual Studio while the editor was running, then swiftly reloaded. The important bit for the online editor was to be able to make small tweaks to numbers or formula and quickly see the effect. Shaders are a devil to debug; I tend to build them up very slowly bit by bit so I know which line is causing a problem. Debugging shaders is a bit like alchemy. The code is run in parallel for lots of pixels and you may be interested in one pixel that goes wrong out of a million on the screen. One of the methods I use is to output intermediate variable values as pixel colours so I can check their range for all pixels at once. I have toyed with creating a shader version of ABMON the online monitor Andrew devised for examining and changing bytes while a game was running but that will have to wait till I am ill again and want another diversion.

Just for fun I created huge asteroid field so I could soak test the collision system. They worked fine in the game and were terrific fun to blast and shunt around but their generation took ages across all the hundreds of sectors. I reduced them down to a more sensible size for now and will look into the cause for the generation delay later. It is often telling to scale up numbers of some part of a game to check the limits. I plan to do time testing systematically when the game is in place. It is fruitless to waste time optimising things that are not going to cause a problem. If need be I will only create the detail of things like asteroid fields for viewed sectors. I often put in two levels of coding for game action. The first for things in view processed at full frame rate and the second for areas not in view where things can be updated in a much coarser manner, say once a second. 

Coming back to the game with the friend or foe issue needing attention I thought it was time to get all the stuff I had carefully coded working together as a game. I now had bases and they should build ships which should trade with friendly bases and attack enemy bases etc. All the code was in there for this, some so old I could hardly remember how it worked. At some stage you have to try to cram the whole game in your head so you can think things through end to end. First things first, the game should begin by  building a couple of bootstrap  bases for each faction. Then factions should start building scout ships that will look for resources and discover warp paths to other sectors and systems.

So I started systematically tracing the boot strap process.  My revising of the bases had disturbed the mechanism or bases using and creating resources. I changed the system to promote the resource stock holding to the mega base level. The sub base parts then added or subtracted from the shared stocks.   Pretty soon I had a shipbuilder base building a scout ship. The next step was for the ship to leave the shipyard and to proceed to the base that had ordered the build. This was a pretty recent routine that used the multi level network to find a path across sectors and systems if necessary. Needless to say this too had a few issues mostly due to the recent revision of the way I structured the networks.  I test routines after writing them but rarely devise test beds for large scale system testing. I find that best to do in the game itself and for that I needed several supporting systems each written and installed.  It is an exciting stage when all the systems start talking to each other as progress happens  quickly as long as there are no major design defects.

My scout ship left the shipyard, flew to a safe distance and then stopped. The pathfinder routine could not find a route to the home base which belonged to a different faction. That was because factions do not know each others sections unless they ally and swap data.  That was a routine I had forgotten about so was not yet written.

Programming Tips.

A little while back I saw a tweet from a developer who had a dog in a game that attacked sideways and wondered how to fix it. This has inspired me to write a bit on the movement of game sprites in early games and how the methods developed.



Game objects moved very simply in the earliest games. The Player sprite usually only moved in a single dimension. Think of the tank in Space Invaders or the bat in Pong.  This was because the original games were operated by a few buttons.  The movement was just a fixed speed either left or right when the appropriate button was pressed. The lack of acceleration or inertia while unrealistic gives a very immediate control and is very playable. Sometimes simple is best. Simple movement like this can be extremely addictive as it is predictable and is easy to learn.

Another dimension was quickly added with the invention of the joystick. Game playfields were almost all in two dimensions, X and Y,  or left/right  and up/down.  Early games just had fixed speeds for each dimension. Thus if you put the joystick diagonally   the sprite would move  X+Y  along the diagonal. The sprite would move faster diagonally ( for those maths inclined the square root of X squared + Y Squared). The envelope of the range of a single move would be a square shape, assuming the speed of the X move was the same as the Y move.  In the real world the envelope should be circular, speed is the same whatever direction you travel. So for these old primitive games the sprite appears to speed up when in the diagonal direction. Most games used this system in the early days. Later acceleration was added so movement starts off slowly and gains speed to a maximum.


Asteroids had a rotating spaceship moving in two dimensions and went a  step further.
Its movement is based on vector arithmetic and is the model you can also use in a 3D game for an object such as the dog walking about on a 2D surface.  The idea is that instead of having data as to the X and Y speed of an object you store it as a polar vector, that is an amount (speed)  and an angle (the direction it is moving).  If you want to allow the direction of moving to be different from the facing direction (move,back, sidestep etc)  you also need a facing direction.   For Asteroids the ship can only accelerate in the direction it faces. You have to reverse the facing direction and apply thrust to decelerate.  Something like a car or a dog would accelerate and decelerate in the facing direction in less skidding. 

Fig 1 The components of a polar vector (diagonal line) The radius represents the magnitude.


The first Graftgold game to use polar vector movement was Morpheus by Andrew Braybrook.  I thought it was over the top till I saw the results. Things moved in graceful curves and had a very natural look.

In Asteroids the left right buttons  change the facing direction . The move direction is worked out using vector addition. The easiest way to do this is to resolve each vector into its X and Y components,  add  the Xs, add the Ys  then work out the angle for a triangle with sides total X and total Y.  I have used  a look up table to do this in many games.  Here is the way I do this if you are maths savvy...

To get the index to use in the lookup I convert X and Y to positive then calculate  Y/ (X+Y). This gives an answer in the range of 0 to 1 which can be scaled to match the number of data items in the look up table.  The look up table is  built thus:

 for (i = 0; i<(DIAMOND_DATA_SIZE) ; i++)
   { /* step along x from 0 to 1 while x+Y = 1 */
      X = (i * DIAMOND_STEP);
      Y = 1.0-X;
      Value = X/(sqrt((X*X)+(Y*Y))); /* project to circle */
      Angle = (acos(Value)/ (2.0 *PI));/* convert to 0-1 */
      *Diamond = (FP)Angle;
      Diamond++;
   }

Fig 2 Diamond and circle


The idea behind it is to convert  steps along a diagonal line  that stretches from x=0,y=1 to x=1,y=0,
to steps along the first quadrant of a circle then for each step find the angle. Then we can look up using Y/Y+X . The division by Y+X normalises Y to our X+Y=1 formula.  It  keeps the data table compact. If you used Y/X for example the index would be massive when X is very small. I call the table the diamond table as if you consider all the quadrants the diagonal lines draw a diamond shape. After you have retrieved the angle you then consider the signs of the original X and Y  to see which quadrant the angle is in, and adjust the angle an appropriate  number of quarter turns.

I am proud of the diamond table method, I invented it from scratch and it has been used in many Graftgold games. 

In many cases you only want to add acceleration/deceleration  in the movement direction so you can just add to the magnitude leaving the angle untouched. Think of directing a  person around the room or a car around a track. You could just say turn left turn right, go faster go slower. In this simple model turning does not affect speed and  acceleration does not affect turning.

So getting back to the dog what it needed to do was move in the direction it faced.   To home in on its target it should turn toward the target (not move toward the target).  To  home it has to work out whether to turn a bit to the left or the right. There are several ways to do this , you could just work out the angle to the target  by using the X distance and Y distance and compare this angle to the dog facing angle. You then turn the dog by his turn speed left or right , then move him forwards.

That sort of homing routine can mean the homer never reaches its target as it cannot turn fast enough. This looks quite good for homing missiles as they pass and then make a huge turn and try again. If you want the homer to reach the target there are a couple of things that need adjusting. Think of parking a car in a bay. As you get near to your target you slow down but may need to turn more rapidly for a bit to get in the right direction.  Getting the slowing right in a game can be frustrating, Slow too much and you stop before the target. I usually make the final speed a function of the distance. This  can still mean you never reach as your speed slows down to next to nothing. You get very close but not quite there so you need to slightly skew your formula or widen your hit zone.


With floating point arithmetic people generally just use in built sine and cosine routines. Being old school I hate  using radians; I do not want to have to keep on dividing or multiplying by Pi. I like an easy to use angle system where 1.0 = 1 revolution clockwise so have my own sine/cosine routine. In 8 bit 256 would represent 1 revolution. Thus an angle would range from 0 to 255. You could just add angles together or subtract them and they would just wrap round and you get the right answer. With floating point  1.0 means 1 rotation, you just do normal arithmetic then take the fractional part to combine angles. However in either system if you want the difference of two angles (say to decide whether to turn left or right) you need a signed answer ranging from almost -1  to almost +1 revolutions.

It still pays to try to eliminate the number of square roots used while manipulating vectors. Never work out two square roots to compare distances, just compare the squared amounts. The worst routine I ever saw was in an arcade game Graftgold converted to home computer formats. The original code wanted to calculate the minimum distance a car could be from a point. It went into a loop that calculated the actual distance by using a square root or the sum of squares , compared the answer to a constant. If the distance was too great it moved the car a bit and went round the loop again. Guess what, the car ended up at a distance of the constant  so the complete loop with all it's square roots was completely unnecessary. We replaced it with moving the car to the required distance and it worked perfectly eliminating a very nasty CPU bound bit of code.

One of the complications using polar vectors is deciding the approach to moving backwards. Do you consider this as a vector with a negative magnitude, or do you reverse the angle? You certainly must not do both.

You can just store the vector as X,Y amounts rather than an angle and a magnitude or even as normalise X and Y components and a magnitude. I  use a 3d vector  X,Y,Z in my space game.  I use the objects matrix to convert the vector to the object frame of reference, add  forward/back side thrust, limit the speed then convert back to the world frame of reference.





Thursday, 2 February 2017

Part 21 Building mega bases in space.

Graftgold Memories.

In the early days ordering things was a bit of a hit and miss affair. Many of the firms supplying hardware add-ons or software were small businesses and sometimes the quality was less than desirable. I once bought a music development program that ran on the C64. It was just about impossible to use as it did not gate the key input. That is if you pressed a key sometimes it would register many times. Normally you gate the input so you do not recognise a key down until you read a key up. I did notice at the demo of this software that the demonstrator had a weird keyboard style flicking his finger at each key to get a short sharp staccato press. As the commands were all single key presses it caused all sorts of problems if you typed normally. When I complained that it needed some improvement , helpfully explaining how they needed to program the input routine, the company refused to admit there was any problem. They said they could find bugs with any program if they fiddled about with it.  Not ours! We took quality control very seriously and would not release a program with a known flaw. We tested each others programs trying to find issues, not trying to make them work. Hewson then gave the programs a second level of testing but found very few bugs. More often they would come up with ideas for improvements and we would discuss these. Sometimes they found the control too hard or wanted the gameplay tweaked.  Usually very few changes were made, they trusted we knew what we were doing and that paid off.

Later other publishers would try to push us to out their ideas into a game and that usually did not work. I remember one game where the publisher wanted us to add a host of embellishments to the main player control. Bear in mind that we had designed all the maps for the existing tight control mode. So we added new animations for skidding to a halt, acceleration after a slight skid when going into a run etc like a cartoon character as they demanded. We changed all the maps as jump gaps were affected. The control mode was then sloppier than before but quite pretty to watch. We sent the game off for their testing and they cam back and said it was better before. At least they admitted their mistake but it had cost maybe a man month of work. Sometimes simple is best. \I remember a space game with a moving ship at the bottom of the screen and testers of a publisher agreeing it was the best control mode they had seen and praising the clever programming. I pointed out that it had no acceleration and just moved left and right at a set speed so was actually the easiest way to move a sprite.


Deepest Blue Progress.

So I have ships that can be built from predefined parts, each with various functions such as proving energy, shields, weapons or just hull structure. I have a space divided into regions connected with warp paths that have to be discovered. I have a set of AI routines to navigate , fight , trade between bases but need to add more detailed stuff such as asteroid clearing, picking up containers. The big thing that is missing is the space bases. These are an essential piece of the game plan. They process the various resources to make other resources. The trade is between these plants and that makes money which pays for the ships. Ultimately its the resources that the fighting is over and the bases are the things that have to be protected. All this is designed to give the world an organic life cycle which acts as a background and purpose for the action.


HUD Docking Display
I had some test bases in the game to work on the AI ships docking routines. I thought I would take a break from the hard stuff be programming the player docking routines.  I wanted a HUD display the looked pretty but also clearly helped the player to dock at the correct angle and position. Sometimes things you think are going to be simple turn out to be a great deal more complicated. Docking requires controlling relative speed  and angular momentum in  3 dimensions, that's 6 different things to monitor, plus the 3 special distances so you stop at the right point. I had a look to see the display they use  dock to the international space station. The lack of graphics on some of the displays looks really ancient, just lists of numbers. 

I tried a couple of approaches. One gave a HUD display that showed the a dynamic path leading from the ship to the docking point. I started using a homing algorithm then realised this was not good enough. You not only have to arrive at the correct place, you have to be in the required orientation. This was not trivial, the easiest way seemed to be to start at the dock point in the correct direction and work toward the ship.

I also tried a virtual runway approach were I displayed a stylised runway on the HUD , fixed in space. This had the advantage of being simpler. However with the player ship visible on screen when the ship turns the camera shifts position to stay behind it. (Imagine the camera on a stiff pole extending out the back of the ship and slightly upwards).  The shifting of the camera makes the runway turn as you would expect but the parallax effect with the ship causes it to appear to swing across the ship when making course corrections. It was just not easy to use in this camera mode which is quite popular.

"shades of Uridium "
I also tried using the standard attitude HUD which shows an artificial horizon and an attitude ladder. This was promising but did not show enough information. I tried various combinations but it was all too easy to give too much information. I started to realise half the problem is that docking  is a tricky operation. Landing is bad enough. I have often crashed on a flight sim after a successful mission especially if the frame rate is slow.  I thought that maybe I should get some big bases in the game and try runway landing. It would be fun to have huge bases and runways that you could fly down and strafe, shades of Uridium or StarWars.

Mega Bases.
The problem with huge graphic models is they need to be made of smaller chunks so you can do things like collision testing or visibility testing. You don't want to plot polygons not in view so it make sense to discard parts of a model that are off screen. I already had a system of building ship models from ship parts but thought I would go a step further.  Base would be made up of macro pieces that were effectively like a ship made up of parts. These macro pieces would be self contained base parts that had a specific function such as converting raw ice asteroids to water. Then several base sections could be joined to form mega bases rather like space cities.

Mega base editor.
This meant tweaking the space dock ship editor screen. It need to be able to work in three modes.
The existing one to make a ship out of parts.
A new mode to build base macros out of parts.
A new mode to build mega bases from base macros.
It need a new plot routine to orchestrate the drawing of the mega base. This was fairly painless.
The most difficult part was joining the pieces together. I remembered all the fun I had trying to get the ship parts to fit together. Now I had to figure out the positions and orientations when the parts themselves are composed of parts in various positions. I ended up revising the original routine to make it easier to use. Each part had a set of joins with angles and positions. I had to promote the required joins to the macro part so that could go through the same routines. After much head scratching and drawing diagrams it all came together.

Back in The Game.
Now the big test, create a mega base and save it out and see if it appears in the game. This revealed a few bugs in my reorganisation over the last few months. New code had to be added to process a mega base, treating it as a collection of bases that shared resources.  Finally the base appeared on screen. The collisions did not always work but it was being drawn in the right place.  I switched on my guns and gave it a pasting. The bullets were not always finding their mark but the feeling was good. Now to add some test runways and get the docking/landing working for the player. Then I need to revise the AI docking to use the new system. 

Programming Tips

Andrew recently was tweeting that there ought be more resource about debugging given that technology of debuggers has changed so much over the years. I only use a fraction of the capability of Visual Studio most of the time. Here are some of my techniques.

Debugging is rather like detective work. The process begins by identifying there is an issue with some code. Debugging is the collection of evidence regarding the issue, using this to form a hypotheses of what may have happened and devising tests that are devised to disprove any incorrect hypothesis , eventually proving the correct hypothesis.  

So where do you start? The first step is to understand what the issue is. To do that you need to know what is supposed to happen and what has happened.  It may be the issue is actually what it is designed to do, either because the design is wrong or your expectations are wrong. If you are not working with formal design specifications or documentation then you need to rely on your understanding of the code and its annotations. 

Testing is a vital part of collecting evidence. You can narrow the investigation down by trying to identify specifically when an issue occurs. Chance can lead you in the wrong direction, if you form an idea of what made an issue occur make sure you prove it by trying it again with and without your idea .

When a fatal issue occurs it is important to collect as much information as you can before retrying and destroying the evidence. If it is a rare issue it may not occur for ages. Try to understand at least the end sequence of events that "caught" the issue. Don't be tempted to make a fix before proving you know what is happening. It is all too easy to make a bug worse.  

In the worst issues the whole thing goes pear shaped and destroys any evidence. Record what happened and retry. Try to narrow down the possible cause. If this does not help use a binary chop approach. Take out half your program and retest.  Keep reducing the code until it works.  Put the offending code back and start taking bits of that out.  Thus narrow it down to a small section of code.


So what evidence can Visual Studio provide? The main things I use are the stack display, tracing ,breakpoints watching variables and watching memory.

Stack Display.

If it is intact the stack shows the nested calls the program made to get up to the present position. You can click on any line in the stack display to change the stack frame. This puts the view of the relevant code in the code display and allows you to view the local variables as used by that stack frame. Thus you can see if the correct values were passed into the call. It allows you to quickly navigate up the chain of calls to get a feel of what is going in, giving you the context of the current processing.

A well designed and written program has good call names with definite tasks so it is easy to see what is happening from the stack. For some classes of bug the stack may be corrupted so shows nonsense. When this happens immediately suspect local variables because they are stored on the stack as part of the stack frame. If you have a local array or a pointer to local variables you can easily write over the call return addresses on the stack. So when the stack appears to be rubbish immediately suspect local variables being misused. Never return the address of a local variable to a calling routine. The variable does not exist after the return instruction.  Finding out which routine is causing a stack corruption is hard. Use the binary chop method or clues from any data you can look at. 

Memory.

This shows a block of memory accessible from your program. You can drag pointers from the code window and drop them onto the memory panel to display the memory where they are pointing. You can copy and paste names or addresses or type them in the Address. The slider is awkward to use as it scrolls too quickly for a small window. Instead use the cursor keys to scroll or page through the memory. What I like about this display is that changes are shown in red. If you suspect you are writing out of bounds look at the memory and see the red changes. Look slightly above and below where the data should be to check it goes in the right place. You can even change the data if you type over it, but take care.

Sometimes I need to debug why a field gets a strange value in it. I will set up a memory window then do a course trace until it changes. Then I will repeat this time stepping into the call that caused the issue.


Watch


I tend to use the watch display more than the local display as I can just select the things I want to monitor rather than seeing everything. If you always use the same names for your main pointers then you can use the same watch over many calls following the processing. You can change values by overtyping, which can be useful to set up specific test conditions. Changes are again shown in red.

A typical use of watch will be to quickly  check all fields of an initialised structure hold reasonable values rather than hex CDCD in debug mode.  You can also easily spot released structures with values of FEFE.

Note the easily read 4 character name that identifies the structure in my example. It is useful to add these, at least in debug mode, to help you find your way about and easily spot a mistaken object. It can be hard to remember which is which sometimes when doing operations like collisions involving more than one object.


Tracing

Tracing can be time consuming but is essential for proper testing and debugging. I like to trace all new routines to see them working as I intended. This often gives me insights into how to improve them to work better or be more robust. I put breakpoints (F9 or click margin) on all code routes and remove them as they are traced. This is a simple way of code coverage. Any remaining breakpoints are on code that has yet to be exercised to is not yet prove to work. I use the trace along with the other displays to see what is happening when.

A typical problem of tracing is that you may be interested in just one specific object amongst a huge number making it difficult to trace. You want to skip over  all but the chosen object. You can do this with a conditional breakpoint or by inserting an extra if statement isolating the object, To set a condition right click on the breakpoint  and choose condition. You then type your condition as a C expression. There is an option to break if the evaluation changes, useful for finding when a variable is unexpectedly changed in a huge loop that would take ages to trace.
You can also break when a line is executed a number of times by selected Hit Count. You can disable breakpoints with useful conditions that you might need later.


Sunday, 11 December 2016

Part 20 Navigating the cosmos

Graftgold Memories.

The Legend Of Avalon was one of my favourite games to develop. Andrew and I were firing on all cylinders and this was perhaps our most creative period.  I wanted to try something completely new. I had just read a book about Glastonbury and the Arthurian legends and thought this would be good subject matter for a game. I played Dungeons and Dragons sometimes and wanted to recreate the feeling of exploring a huge underground complex of rooms and tunnels with a 3d view. Nothing like this had ever been done, the nearest to what I wanted was Attic Attack which used a top down view. I experimented on paper with a side view. I drew scenes rather like a stage play. I cut out a frame and moved the scenes underneath to see what it looked like. I then adopted my Lunattack horizon routine to display the edges of a room. It was built in sections so I could easily have different room sizes. I knew I couldn't scroll too many graphics so decided to keep the background mostly dark with the suggestion of wall texture here and there. The illusion worked well. I then added the wizard. I modelled him in plastacine and sketched the model from 8 directions on squared paper then roughly shaded the squares. This was converted manually to hex codes and keyed in. As the graphic was large and needed 8 frames I could not afford walking animations so designed him cross legged so he could levitate around.  That is the secret of designing for limited resource. You have to make a feature from the limitation. 

I wanted a huge event based adventure that matched the complexity of text based adventures. I designed a central system that meant I could code the adventure very compactly.  I did this by having standard objects which were described by about 8 bytes for each state. 
Each object/state had:
Graphic Number : Thus could visibly change of the state changed.
Text Number:        A description of the current state
Movement pattern. So their behaviour could change per state
Event:   This was the event that the object  emitted in this state.
Trigger:  The event the object wanted in this state to change to the next sequential state
Flags:  Whether it could be picked up,moved, had gravity etc.

The event and trigger were the key elements. Each object emitted its event at its current location. The events/triggers were either specific events so a specific object could cause another object to change to its next state, or general events such as applies a force that can break things.  For the current room the objects put their events in a list. Some events were limited to a local X,Y position others were room sized. Each object also looked in the event list for its trigger and if it found it and the position matched it changed its state to the next state. That generic mechanism was all I needed for the whole adventure.  For example a mouse was in an invisible untakeable state until triggered by the cheese to appear,move and be takeable. It then emitted the trigger to change the state of an invisible key part.
I built up a huge chain of triggers/events to form the adventure plot. Also ai characters , magic, missiles etc all emitted events that could change things.

Dragontorc adventure object state data. 


Deepest Blue Progress.

I said that writing a game is like running a marathon. I have been at the point they call the wall where you wonder whether it is worth carrying on. Each step is painful  and no end is in sight. You just have to grit you teeth and keep going. I keep a diary and look at what I have accomplished over the last few months. That reassures me I am getting somewhere even though the "to do" list seems as long as ever.   Last month I did some important refactoring of the main structures to make the world data more manageable. Now it was time to get the AI using the new structures so ships could fly between sectors and systems.

To recap I had divided the galaxy into star systems.  This kept data segregated and meant that each could be run on a different server in the future. Systems were connected by warp paths.  Systems consist of a number of sectors designed to restrict the coordinate size of each space region to avoid huge floating point numbers that would be inaccurate. The sectors contained the space objects such as asteroids, bases ,ships and sector or system warp points.  So there is a three level network of nodes.
At the top level is a network of systems. Each is a network of sectors, each of which is a network of patrol points to navigate around a sector. This tiered design prevents networks having too many nodes. To navigate you need data about combinations of nodes which gets exponentially huge. With small networks you can devise simple look up tables to help things navigate.

"What is the next step to get from A to B?"
A tiered network had its own headaches. A warp point needed to know to which system/sector/locality it pointed. The game only creates systems as they are discovered so all of this is dynamic.  The key routines for the AI was a routine to supply the answer to the question, "what is the next step to get from A to B?". If A and B are in different systems the AI needed to  know what is the next system to go to, what is the next sector to get to this warp point, and what is the next local step to get to the sector warp point.  Each step of this needed coding as an AI program that could drive the ships around. As it was complicated I needed it to be generic so any kind of ship could just use it.

I had already designed the AI mechanism. An important feature of AI control is that it is an inverted program structure in Jackson speak. That is each cycle does a bit of the processing for each ship then the next cycle picks up from where it got to last cycle. Thus a ship's routine may have a structure such as
Loop thru Nodes
    Drive to Node.
    If close choose next node
end loop
The loop structure is inverted, that is it is spread over many game cycles rather than just running till it exits.  Ways of doing this are discussed in my programming tips.

I coded this with a state based process system. Each AI program through several states which can loop have conditional statements or call other AI programs. So a ship doing navigation to a new system can change to a fighting pattern to defend itself then resume its navigation when finished.

"The more I thought about it the harder it got"
As a diversion to all this background programming I thought I would add a gameplay element so I could see the game working again and tease out any issues that may have crept in. I had added asteroids and wanted a way you could play around with them so thought I would add a harpoon to grab them. Then you could tow them , collect small ones. Maybe the same mechanism could be used to grab ships or space junk. I wanted to have a go at inverse kinematics so thought I would have some kind of chain or arm with multiple joints. To make it easier I wanted them all the same size. I coded the basics of the new object except for the positioning. The more I thought about it the harder it got.
One end of the chain had to be fixed to the hull of the ship , the other either free or fixed to another object. The hard problem was when the chain was fixed and not taut. How do you work out the positions of all the links in the change? I looked up many web references  and quickly realised this was not a trivial subject. Most methods were too slow and cumbersome. I spent days sketching diagrams and struggling to understand the maths. In the end I implemented my own method after looking at the FABRIK method. That iterated back down the chain and then forward until it converged on a result or was abandoned. I improved on the design to give a much better guess at the orientation of each link so I could get a reasonable linked chain in once pass. Its working pretty well but glitching slightly as it changes from taut to slack modes. I will revisit this later as I want to make use of it first to check it is worth keeping. I tried capturing asteroids and for a while they were ok they suddenly catapulted off into space. It was all due to the maths of the reverse collision, when the chain pulls the asteroid.  I had forgotten that taking the dot product of the chains direction and the asteroids move lost the sign of the move and just says whether it is along the chains vector. Easily fixed you need to take the original move components multiplied by the dot product and remember to reverse them for the pull effect. I also added mass into the equation so the ship and asteroid are both affected, rather like a collision in reverse.

I added a mechanism to retract the chain to couple the asteroid to the ship. This was what I needed to pick up containers and transport them. So next  I coded a container object. I wanted these to be stackable and also linkable like a goods train so added special collision code to deal with this. The containers would assist in the shunting by acting as if they were magnetic and so align themselves as they were moved close together. I now need to work out a control mechanism so the ships can control grabbed objects. The chain will probably be a kind of robot arm similar to the space shuttles arm. I think I will try this out and if it is fun use the same code to allow the player to build things.

 Programming Tips.

I had a request to talk about programming AI routines. This is a huge subject , nowadays people use neural nets and other complicated devices. Remember that a game is an illusion and all we need to do is create the illusion of AI. I always remember a review of Paradroid saying how the messenger robots sped off to report the position of the player to the guard droids. This was all an illusion, they just ran away, but illustrates that if you make things act as though they are intelligent then the player reads a lot more into it.

It is still a daunting problem. How do you make something act as if it is intelligent. The way I do it is to think about the possible main actions an  Artificial Intelligent Character (AIC) can take. For most of the games I have developed these are surprisingly similar and fisrt surfaced in "Avalon".  The most basic of choices is attack or flee.  Stupid AIC's or clever ones that know they can beat you will usually attack. If they think they can be beaten they are not so keen and may stay their distance , retire or flee in blind panic. This can be simulated by coding several primitive actions and having a way of choosing between them.  Suggested primary actions are
Move Towards Player Recklessly.
Move Toward player slow and steady.
Maintain a distance to player ie shadow their moves.
Move at 90deg to player  ie dodge sideways
Move away from player in controlled fashion.
Move away from player recklessly
Move randomly.
Stop.
Do the same as last time

By changing how often you make the decision you can make things look nervous or steadfast.
An easy way of working these into a more complicated patterns is for each to have a set of probabilities of each primitive. This can be a simple set of descending numbers. Then you get a random number and compare it to the list in sequence until it is greater than the chance number.

These macro patterns can then be put in a table. You can index into the table using things like the relative strength, morale friendliness etc.


Another trick is to have predetermined sequences or patterns in a particular situation. Take for example a ship wanted to do a bomb run. First of all they keep their distance ,look for an opportunity then close to launch range, release their bombs the retire. The different components of this are again the primitives we discussed above with the addition of some kind of shall I attach decision which could be something like "am I behind player".


AI navigation of complex game scenes can take a lot of processing so is best done be adding things like waypoints or patrol paths. This was the method Paradroid used to give its effect of intelligent movement. In Ranarama and Bushido I used a game map that had special data on it. The player left arrows rather like footprints to tell the AIC go this way. There were also arrows pointing to the doorways so the AIC don't have to keep bumping into walls.   For a multi height game like Uridium a contour map could be used so the AIC fly at the correct height.

I like to add touches so AIC's react to the situation. In Avalon when high magic was used certain AIC's went into panic mode. I added a room fear variable so mass slaughter could cause AIC's to retreat or panic. I just added the room fear the  AIC own fear. The room fear gradually subsided.
Its the little touches that bring a game to life. Early meanies were usually really dumb and just had a set pattern. You only have to add some kind of a reaction to the players move to change this and it can be done quite simply without complex code. I usually add a bit of randomness so things are never totally predictable. It is good to have risk and surprise in games. That is one of the secrets of the playability of my games.



Tuesday, 1 November 2016

Part 19 How to get from Here To Eternity.

Graftgold Memories.

I read on Twitter that Gary Foreman signed a letter to convert Ranarama to the C64 30 years ago.  Gary worked from home at first just contracted for the one conversion. The results impressed Andrew and I so when Graftgold had the opportunity to expand Gary was offered an in house job.  Financed by Telecomsoft, Graftgold moved to its first office in Witham. It was a couple of rooms above a greengrocers, now a flower shop opposite the George public house.  The rooms had exposed oak beams and with a bit of paint and a new carpet it was quite cosy. The entrance was via a rear metal set of stairs , we had fun trying to get to Iron Man arcade game up the stairs.  We had to dismantle it as much as possible.  Later on we moved to a larger room at the other end of the building and the office by the stairs was converted into a vegetable store that we had to pass through to get to our office. The floor of  the building was sloped in places where the oak frame had distorted and the front of the building was lower than the back.  There was a burger shop downstairs and the aroma of burger and chips used to float through the open window in summer making us feel very hungry.
\\The original team outside the old office.: Daivid OConnor,Gary Foreman,Dominic Robinson,me,John Cummings and Andrew Braybrook,

It was great fun setting up the new office. I ordered new L shaped desks for everyone and PC compatibles with twin floppies and Hercules monitors. Hard drives were small and expensive, our first one was on a big Atari used for 16 bit development. We ordered a PDS development system for each programmer but its floppy disk routines did not work. They gave us updated software after a while. We had agreed to finish a Flying Shark Spectrum version in 6 weeks so we were really up against it for a while.  It was a relief when we could finally save our work using  PDS. It was a step forward having a proper development system that could assemble  then down load and debug from PC to Spectrum. We eventually put the Spectrum/C64 PDS boot software on a cartridge  to eliminate tape loading.




Deepest Blue Progress.

Long range scan.
When players explore a new sector I needed a way to help them find things rather than just roaming around at random. I decided to add a long range scanner that looked a bit like a submarine sonor or old fashioned radar. I decided to put it as a head up display sweeping the space in a cone in front of the players ship. As the scan goes round blips can be representing features a long way ahead of the players ship. This allows players to locate things without knowing what they are until they get closer.

Semi Transparent Graphics
I needed a semi transparent graphic and realised I needed an easy way of generating an alpha channel from the rgb values in my graphics utility. This meant I could simply make darker areas of a sprite more transparent. I then drew a rough test sprite for the scan that was like a line from the centre of the scanner that faded out as if it was leaving a glow on the screen.  I could use the same principle to make some of the other HUD displays semi transparent. I have radar marker lines that were meant to fade at the ends and now these worked a treat.  

I use a lot of lines to generate HUD displays . Their colour is defined by texture coordinates, which allows me to make textured or animated of faded lines. I imported a RGB square graphic so I had lots of fades to choose from. My HUD was just using random textures and this simple change  immediately looked a lot better.


Last month I was deeply embroiled in rethinking the design so I could code the AI routines to control the game world. I made slow headway and slowly came to realise I needed to refactor some of the main game code to simplify the relationships between structures. This came to a head when I started adding AI path finding routines. I wanted the routes in the game to be discoverable by players and shared by members of an alliance. That meant that each alliance needed its own view of the game world. Its ships could only used paths that it new about.

This affected my core network routines that had no facility to hide and reveal parts of the network.
As space is so big I had a 3 tiered network with system jumps, sector jumps and local paths. Nodes in each of the networks were attached to matching objects representing a star system, a sector within a system and a feature within a sector. This was all rather complicated.

"I then had a brainwave"
I was working on a method of marking routes between nodes by recording the best node to get to from A to B and the distance. It was like one of those triangular mileage charts. I then had a brainwave. Instead of having a complicated Network organisation with nodes linked to each other via link objects I could just have the route triangle.  Nodes directly connected just list each other as the next best node. It meant I could dispense with a whole load of structures. Effectively the system /sector or Feature object became the node instead of having to have a pointer to a node structure.

I sketched out the new organisation and finally took the plunge. It was quite a far reaching change with a large impact on the existing code. I wrote the new network routines first trying to keep them compatible but eventually decided I may as well simplify the interface as some functions became redundant. Its not a good idea to change interfaces with existing code unless you have a really good reason. Working by myself meant that the impact was minimised  but would need a big bang approach to implement in the game. It took over a week to code and clean compile, but code was significantly simplified leaving me with a good feeling that I had made the right choice.

Multiple linked lists and pointer lists
While I was in the mood for change I decided to simplify my organisation between main game structures. My save and load of data catered for networks, pointer lists and heirachies of linked lists.
It could only have one linked list and pointer list in any one structure. If an object needed more lists it had to have a pointer to an external list object. This added an extra level of addressing. So I added the facility of having multiple linked lists and pointer lists, a tricky change. Each list needed to know which sort of sub object it contained so it could automatically find them and add them to the correct list.


So the next step is to get all this debugged so I can see the game running again. Then I can debug my boot code for the star systems population. I put in five home factions representing power blocs on Earth and a few alien nations. They each should have a home base and a space ship factory. I have coded  a crate pioneer routine which is the first part of the AI. The pioneers will find warp gates and explore new sectors, claiming resources for their alliances. When this is working I will code the base creation process so the alliances can mine and process resources.


Programming Tips

Debugging

I have given some tips about debugging before but here are some more ideas.

I like to get to the debugging stage. I have done so much in my programming career that I can almost do it on remote so its like a downhill stage in development of new code.

Debugging actually starts way before I pen any code.  I like to consider how I am going to get a new routine working especially if its complicated.

I like to include identification  data in each structure such as a short name so it is easy to identify the data when looking at it with the debugger. I sometimes will put an if debug around this data so it is eliminated in a final build, if it is in a memory sensitive structure.  It is really useful to be able to see which object you are dealing with when you have hundreds of similar objects.


For objects that are complicated such as my networks I like to write a simple test bed that can try each routine in a controlled and systematic manner. For my network for example I would create a network, add some nodes connect some, find the best routes navigate between them, add more connections, recalculate the best routes, tear the system down.  As well as check the things that should work I like to test the things that shouldn't.  For example trying to navigate between unconnected nodes or trying to remove a node twice. Routines should fail in a desired manner. Then when other things go wrong your routines do not compound problems and just tell you something is wrong.

I like to trace all code, it forces you to read it in the sequence the computer executes the code. I often spot things that are not quite right while doing that before they cause a problem. Its faster to find an issue early on rather than responding to a crash. I look for dangerous code that has a chance of failing catastrophically if there is bad data or a bug. I add safety checks or change method to increase the safety. Simple things like Nulling out a freed pointer can prevent future errors

I try to catch errors at the start of each routine by checking the input values to be sensible. These checks would be removed in the live version.

I like to keep each routine as standalone as possible so it is a separate entity that can be tested on its own or with minimal code support. Then I can call them at the start of the program to quickly get to the code under test.

For complex sets of structures I will write a Check routine that will write a report listing all the objects and important fields and the relationships between them.

As a last resort while debugging I add lines to write values to a report. It is useful to pen a DEBUG macro that can easily write a line to a file if in debug node.

I like to use the memory display to display a dump of a structure especially an iteration of structures, then watch as the memory changes as I trace.  Any memory copying or changing  operation is best looked at in this way to check limits and content.





Tuesday, 20 September 2016

Part 18 How to Design A Game.

Graftgold Memories.

Summer used to be a very busy time getting things ready for the big game shows. The office could get very hot. We used to work flexitime at Graftgold. Some of the early morning  starters used to open up all the windows to try to get the office cooled down enough for another sweltering day. I can remember it even being hot at night. Sometimes I used to work through to the early hours and it just didn't seem to cool down.  Programming can be very addictive especially if you are trying to get something to work. I had several all hot summer night sessions trying to get the PlayStation linked game working for MotoX. It was so frustrating it would work on their little test program sending one small packet of data between two machines but would freeze up as soon as I started the game. The system used interrupts so it was almost impossible to trace with the debugger. I did get it working went home in triumph but could not repeat it next morning. I knew my code must be ok if it worked once but could not see why it did not work. I logged loads of messages to prove I was doing everything the manual said.  The manual was more like trying to read a dictionary, it told you the call parameters to each routine but did not have much information on how to use several calls together. It also had the habit of saying things like "never set this bit" when it meant "this bit must always be set". So it ended up a game of trial and error with many permutations.  Sony technical support could not help and in the end the Japanese publisher Coconuts said to leave the link game out was sure it was something wrong with the Sony interrupts conflicting as it worked if I only ran the link system without any other interrupts.  As soon as I did things like poll the keypad it would just stop receiving or sending the data. There was no way to monitor  the data actually sent down the cable. That was the only time I can remember being defeated by a bug.

Deepest Blue Progress.

Running The Universe.

I had spent weeks thinking about the game and knew it was time to sort out the Artificial Intelligence running the game universe. It was pretty daunting. I just did not have time to design loads of scenarios or locations so had to get the computer to do all this programmatically.  I wanted an organic world that could grow from minimal data all on its own using the same rules as when the player is playing. The game world had to react to the players actions, that is important as then there is a point to doing things.  I wanted the Earth factions to have interesting interactions with a growing space economy. This would then be under attack from the Seiddab whenever the two major sides met.

The whole thing needed to work with a single player, linked players or net hosted games with loads of players. That flexibility puts huge demands on the design. The topology of the game universe had to be designed to suit these modes of play. That meant a space that could be divided into local sectors that could be run on different machines if need be. It meant that I had to consider what parts of the game would be run on a game server and what parts on the local client. I realised that I needed to change my player control system to send a linked machine any ship control the player had made via the interactive ship console along with any keyboard or device controls. The controls needed to be sync'd on all machines  as I wanted to duplicate processing on each machine with a ship in a sector.

Server Data
The next thing I needed was a system where the server could send game events to any connected machines to update any local copies of data owned by the server.  Local copies would be needed of data needed instantly during action gameplay. Other data such as market prices could be kept entirely on the server and accessed via a standard client/server  query and update mechanism. I had spent the last ten years designing and implementing client/server systems for insurance systems and that experience has come in very handy.

Mission Display System
I needed a system for the various factions to supply things for the player to do. I decided that factions will update a mission database which the player could access to find out what things were wanted in different sectors graded by danger and type of mission. The same mechanism could also be used to orchestrate fleet actions. Ai players and human players would both use the same data to apply for missions. Later when the human players had enough money they could post their own missions effectively becoming their own faction.

I wrote a mission query screen and a mission display screen using my standard window form system. I linked this to the sector display form so you can see what missions are available in a particular sector.

Route Finding
The Ai ships needed a way of finding their way around the network of sectors within a network of star systems. This of data can get very big exponentially as you need to consider all the permutations of start and finish points. I decided to use grid of start/finish and for each entry put in the distance and the best node to go to for the next step of the journey. By reading this at each node you can find the best route a step at a time.  Each faction only knows of locations it has found (or traded data) and some routes may be too dangerous. So each faction needed its own view of this and it needed updating when new routes are found. The whole thing needed to be worked out by the computer to save weeks of typing in data.


Sector and System Data
I had Sector and System structures in the game for ages but realised the factions needed some private data about their ships and bases within each so they could make game decisions. They needed somewhere to record if an enemy had been sighted, if resources had been found and to control there interactions within the sector. As the game progresses  SectorAi and System Ai structures are added to the Faction's data along with ship and base lists.

Faction Ai
Now I had the basic elements to model the game universe and the faction AI.  I needed a process to deal with each faction in turn over time so they continually assess the situation of their territory and construct missions to explore ,defend, attack or exploit a sector. This is what I am writing at the moment. Along with the boot code to create the primary factions. Its an exciting time, the game will be broken for a while but then will be a living world with ships going about their business and the player able to join in wherever they please.


Programming Tips:  How To Design A Game

Before I left work to become a games programmer I worked for a couple of years as a Systems Analyst/Programmer. A Systems Analyst  works out what a system needs to do and what is needed to achieve this. I was trained for business processes but the art of systems analysis is generic and can be applied to any problem. It is useful to know the basic steps of design. At first it seems back to front but that is because you need to know where you are going to decide the way to get there. The same process works designing a huge system or a small part of a game or business system.

1. What are you developing?
 Pin down the scope of what you are doing. If its big break it down into parts and follow the design process for each part. Have a clear idea of the goals of the process rather than the mechanism that comes later. In business this often consisted of recording what an existing process did and what changes were needed. With a game imagine a review summarising the gameplay and player experience. 

2. What are the outputs?
For static screens outputs can be the data the system is collecting and processing. A game as a whole tends only to have intermediary data  outputs but these need identifying and detailing down to field level. A games main outputs are audio and visual experiences for the player and these need at least categorising and listing so the following steps can be applied to each sort of data. For example you could list each special effect on the screen as an output.

3. What inputs are needed to create the outputs?
Input data for a game may be read in from data files, input by the player ,. It may even be outputs from some subsystem or pre-processor.  Any field of data in an output file has to come from somewhere. There is a mapping of input data to output data. Once this is clear the processing often just falls out.

4. What processes are needed the  create the outputs from the inputs?
A process only exists because it produces one of the outputs. That's why we look at outputs first. Some processes will be so big they need considering iteratively from stage 1 so they break down into sub processes with their own outputs and input data.


Wednesday, 10 August 2016

Part 17 What do I do Next?

Graftgold Memories.


There is nothing like going in a shop and seeing your own game on the shelf. When I first saw 3d Space Wars in Woolworth's I was very proud. It suddenly all felt very real instead of being a pipe dream. I used to get a similar feeling seeing advertisements for my games in the mags and reading the first reviews. On the whole reviews were very kind about my games but for some I felt the reviewer hadn't really got into the game. I used to write games that didn't fit in a standard genre. I was inventing new genres not trying to fit into expectations.  I liked being able to meet a reviewer to discuss the game. Then at least I knew the reviewer knew what was in the game. My games often had hidden depths that you might not find with a cursory play.  I believed in making a game simple at the start so new players could play it, but then to introduce new features so the game unfolded as it was being played.    Perhaps my biggest disappointment was Astroclone. I had written a brand new graphic engine to increase frame rate and get rid of flickering graphics. To show the new system off I added a front end to the adventure that was inspired by Defender. Then to tie all this together I added a strategic element. I balanced the gameplay between these elements and thought it was a masterpiece but it jut was not what anyone expected. The people who liked my action adventures couldn't get on with the shoot em up bit, The game didn't fit in any genre it was treading new ground. After that game I retreated to a much more conservative design style and developed Quazatron relying heavily on Andrew's Paradroid.  Reviews really got inside my head. When you have put your heart and soul into something only 100% is good enough. I always came back fighting though thinking I will show them with the next game.


Deepest Blue Progress.

If I had a publisher it would be now I would have to explain why progress has slowed to a crawl. Here are my excuses;
1. The meerkats keep enticing me to use my Meerkat movie tokens. Wednesday PM is now movie afternoon.
2. The weather is so hot and I cant see my laptop screen in the sun. Did manage some work under the sun shade but it gets so sleepy. Well I am retired.
3. Have to keep watering the garden.
4. My new e drum kit sounds fabulous. I combined it with my old kit so its a monster. I want to get really good to record the music for the game.

When I think about it I have done a fair bit of programming this month. I take my laptop twice a week to my mother in laws. We stay the night so it gives me a couple of days to program. She is a bit loud though so its hard to concentrate. She has the tele on max so it all vibrates. Sometimes I put ear plugs in. She thinks I am going deaf as I don't respond when I am deep in thought.

Adding The Galaxy.
I found a data file modelling the dust in the Milky Way and thought it would be cool to add that into the game as my 120000 stars were centred on the sun so looked more like a globular cluster than the spirals of the Milky Way. When I added the 40,000 dust clouds the display slowed down so I had to reduce the size. Now they look more like stars so Ill have to rethink. It does look more like the galaxy but not the look I want. I could copy a picture of the Milky Way and use that as a backdrop. It has got to look much more sexy. I played around with an on line shader engine, maybe I can write a shader that emulates the galaxy. I added a dynamic fly into the galaxy so you get an impression of where you are.

Playing With Shaders.
I found a dramatic warp hole effect on a web site. I tried installing it in my shader editor but its a bit too big and complicated. So I thought I would try something simpler. I tried distorting the uv coordinates of the models texture and got some nice effects. I think I will make the Sieddab ships alive.  I also tried an effect whereby a ship is hit by a lasor and heats up and melts. I just love the effects you can get. I need to try lots more and really get on top of the way of thinking. The processing has to be from the each pixels point of view  as each may be processed by a different graphics PU.  Its such a different way of thinking. What I like though is that is pure creative programming reminding me of painting pixels on the first machines I programmed.

Dynamic screens

I wanted to make the in game systems seem like a big futuristic computer system. I designed a fairly standard logon screen to create this illusion and started on the design. I wanted a really dynamic way to select and display screens. I had written a routine to print a screen onto a texture rather than the background. I write a supporting object I called Thumbnail to manage these. I then hooked up a series of Thumbnails with a pre-existing Carousel object that displays a 3d selection to choose from. WIth this combination I can whirl screenshots around in 3d space, select one and make it zoom to the foreground become the current screen, This is real rock and roll, its all my systems talking to each other, I had a few crashes when screens fired up in an untested order to try it all out. I even had each screen running in realtime on the thumbnails but I think that is going too far, they were not designed to run alongside each other so I am surprised I did not have more problems. I tried adding a screen to my spaceship console as if its a computer screen. I added the whole carousel to the console. It works but for the zoom effect its better if the carousel is big. I can now see how all the bits are going to fit together.

Power System.
A couple of months ago I installed a super duper power control system. I only put in one of the 6 I needed so thought I better finish it off.  The design was quite difficult as it had to cater for user built ships with highly different capabilities. So I decoded to make all the meters run on a fractional basis.
Its starting to look a bit like my sound mixer. I added slider controls so you can adjust the percentage of power into each of 6 power groups. You can overdrive each group to get better performance for a while but the temperature rises and eventually causes damage. You can switch on an auto adjust if you want the computer to balance the power. It gives a nice feeling as the ship powers up and all the meters spring into life. Ill have to add some sound soon. You can underpower your engines for fine manouvering, its working well. I tried flying round and blowing up asteroids but crashed the collision system, Happily the crash was a test I put in to check the data. I forgot to add to a count.
Killing asteroids, all GFX are just placeholders.

Programming Tip.

I recently dug out some old coding folders to scan some examples to take to the Revival event. I was quiet surprised at how messy my work was. I used to write in pencil and rub out and correct, these were the days before text editors. However the whole thing although superficially messy was well organised. The data was all in strict formats with systemic labelling and cross referencing.

When you write a big program you get to the stage when you just cannot fit it all in your head. The best way to organise a program is right from the start. If you set out a shape to the project you remember where to find anything. Its like organising anything. Group similar things together by splitting up the whole thing into meaningful subsets.

The converse of this is to keep different things separate. I like to split a program into several libraries.
I keep the reusable core routines separate so to start another program you can just include these. These are built into a linkable library.

I like to have a module for each major "object" in the game rather like object oriented programming.
Sometimes a module will have a couple of closely related objects. My Window object and Window Manager share the same module but their routines are kept separate in case one day it gets too big and I then want to split it.  I like a header file for each C file strictly containing any structures and external references.I keep internal references in the C module so they are effectively private.

My memory is not what it used to be. One of my methods is to use rules to create names of things. It is then much easier to guess the name and intellisense does the rest. I always put the object name first, so my Window routines are named things like WindowInit, WindowTerm WindowPlot then they appear together in alphabetic lists. I always try to use the same name for the same thing. If a name becomes ambiguous I will consider renaming using find and replace. It really pays to be systematic. I only use abbreviations when words are very long the I always use the same ones, such as Init for Initialisation.

I used to use hungarian notation for years but with intellisense find it mostly unnecessary hieraglyphics.  Occasionally I still use it when playing around with types to distinguish several versions of the same data and for pointers and pointers to pointers as it helps with understanding what is going on.  

Thursday, 7 July 2016

Part 16. Mapping The heavens, reviewing the design.

Graftgold Memories.

I have been reading Hints and Tips For Video Game Pioneers and it brings back a lot of nostalgic memories and I recommend it. It really captures the feel of what it was like and also a feel of what you need to be able to sustain a business in the games industry.  It was my dream to leave work and start a business so when the computer game market took off I was quick to chuck in a well paid job to write my own games. I can remember I saved up £12000 which was my annual salary. I then knew I had a years buffer if things didn't go as planned.

The game That Never Was.
I wanted to write a real time strategy fantasy  war game on the Spectrum. I wanted to do what I had done to adventure games to the strategy game. I wanted a huge playing area where you could build defences and march armies around. I started the design and drew up some test graphics. I tried several presentations but just could not get something that looked impressive and was the right scale to get lots of little men on. The Spectrum resolution meant that the soldiers just could not be tiny. I tried graphics representing a whole troop of men  which almost worked. I was going for tilted map approach which I wanted to scroll around. I started experimenting with a landscape built out of blocks which showed promise but did not work at the scale I wanted. In the end I admitted defeat and shelved the idea. It was later resurrected as Realms on the PC and 16 bit machines. The Spectrum graphics engine evolved into the landscape for Quazatron. It is important when designing to do what a machine is good at and I realised that it would not of worked on the Spectrum.


Deepest Blue Progress.

I keep thinking that one of these days I will come up with a real catchy name for the game. I fancy getting the word "Retro" in the title. There has already been a RetroThruster. I would also like a reference to 3D Space Wars and I also like the word Cosmos. This leaves me with something like Retro Cosmos Wars which just doesn't have the ring I want. I used to come up with names by joining two words or sub words together to form a new word such as Quasar and Tron. I've still got tons of coding to go so I'm sure Ill come up with something. Deepest Blue is the name of a song I wrote. Titles can be a right pain, especially when you think you have a good one and you realise it has already been used.

This month my goal was to program the AI of the actual game to drive the game world. I started doing this and realised that in order to debug this I really needed to write the player/world system interface. I had imagined a web like screen system that would present the world information to the player and give the illusion of a real world.

It was at this point I had to remind myself of my aims. I did not want the game to be a long winded detailed simulation strategy game. I wanted the game world to be able to create scenarios that would be fast and full of action. Thus the player has the best of both worlds. The main game play would be more like a first person shooter but the results of the fighting would impact on the world situation.

"A game is an illusion of reality"
In designing a game it is juts as important to decide what to leave out as to what to put in.  A game is an illusion of reality and it is up to the designer to include the things that maintain the illusion without acting as baggage to the player.

I wanted a cool way of presenting screen data so decided to tweak my game engine to allow any graphics to be printed on another surface rather than the screen surface. This allows say a page to be pre-printed as a texture then manipulated onto the real screen surface in fancy ways. It could be scaled rotated wrapped around 3d shapes distorted, bent etc. Doing something technical is also a way of putting off decisions I still want to chew over. The coding went pretty well and I had this worked into my engine with only a few coding changes. I was pleased with that, it is a sign that your basic design is sound if it can cope with an upgrade without major shuffling.

"Just for fun I added a thrust on the camera so you can drive through the starts in defiance of Einstein's speed limit. "
When I started the game I imported a star catalogue, I liked the effect of flying at impossible speeds  through the galactic star field. In the game the stars are used as a sky box, there are 120,000 of them in their correct places so I didn't want to have to draw them every cycle. So I thought I would use the original dynamic star field as a map showing were you were in the galaxy. Showing star names would show that they were real stars in the correct locations.Just for fun I added a thrust on the camera so you can drive through the starts in defiance of Einstein's speed limit. I needed to show how various stars were linked with warp paths.  Each star system has a number of interconnected sectors  again connected by warp paths. So I needed to be able to zoom in on a chosen system and show the sectors. I the decided to allow you to focus in again on any sector to see the various things in a sector.

"Space is huge"
That should have been pretty easy but it was the first time a lot of code was being used. I had  code that automatically connected near stars with warp paths and generated linked sectors. It was a 3 tiered network, 1 for the star systems, 1 for the sectors and 1 for the waypoints in a sector. I cursed myself for making it so complicated and almost combined the levels. Then I remembered why I had designed it like that. Space is huge and you just cannot use the same numbering system for the whole of space.
Floating point numbers cannot be huge and accurate so are only good within a certain range.
Having Sectors interconnected with warp paths was essential to maintain the scale but to have each scenario  with its own coordinate system. It also meant it was easy for the game to just run in detail the current sector and do a background low detail update of the other sectors. This gives the illusion they are all working in the same detail as the viewed sector. For an internet hosted game I could get different servers to host different star systems or even sectors if need be.


"This is a one man show so I have to get the computer to do as much work as I can."
The game background processing is firming up in my head, I don't want to start till I can imagine it all working. First I will write the other information screens the game needs. The game world will present the player a dynamic list of missions or opportunities to choose from. It will also provide info about alliances and trading. I am tempted to key in a periodic table and have a detailed trading game and have to stop myself.  I want the trading to be the backdrop for the conflict not to take over so only a few representative classes of resource are enough. I have to keep telling myself the game world is there to spontaneously generate dynamic scenarions rather than a fixed list that gets boring once you have got to the end. This also has the benefit of not having to type in data for loads of scenarios. This is a one man show so I have to get the computer to do as much work as I can.


Programming Tip

I am always surprised when I put a major bug in some code. It is important to remind yourself that you are human and should expect to make mistakes, that is the best way to eliminate them. I once had a nurse friend who said If they made as many mistakes as programmers all their patients would be dead. The truth is they are human too and make just as many mistakes, they just do not have a computer that shows them up so clearly. To avoid mistakes recognise you will make them. Then introduce practices to minimise the amount of errors and to find them when they occur.

Sometimes it is hard to distinguish between a design error and an implementation error. Say you come up with a new formula to calculate the trajectory of a bullet so it hits the opponent. You try it and it doesn't hit.  It could be the design ie the formula was incorrect or that you made a mistake encoding it. It is all too easy to give up on a design because it is not implanted correctly. 

For formulas or mathematical routines  I often test them in a spreadsheet to validate them before programming. You can also use the results to spot test the coding.  Spreadsheets can give you a good feel for how an equation works with different values. Simple things like deceleration so you stop at a particular point can be a lot more difficult to code than you expect especially if you want to limit deceleration of a game object to its abilities.

For more complicated algorithms such as the City growth curves in Realms we started of by programming them in BASIC and printing out tables of results. It was a chaotic algorithm involving positive and negative feedback. We needed to tune it so it responded to the various parameters such as food, population, wealth , health. When we had the right degree of stableness and variability we recoded it as assembler coding.

I always try to think of how I am going to prove that a piece of code works . Sometimes that means a bit of extra data to aid debugging. You can always add some #ifs  to remove it in the live version. If you have many items to process you very often are only interested in debugging one of them. So you need to be able to clearly identify them when looking at data dumps. You can also add a temporary
if statement to execute only on your selected object. I like to give objects names in their data structures while I am debugging, its far easier to see what you are looking at.

                                            _______________________________