Part 15: Asteroids and Formations

Graftgold Memories.

A question I get asked often is:  how do you come up with an idea for a game? I never was short of ideas. It took so long to finish a game there were always about 3 I wanted to write. When you get near the end of a game you have to stop putting new ideas in if you want to finish. I used to save them up for the next game. 

I usually left the scenario as late as possible in the development. That was because fads came and went. I found I could easily adapt game mechanics to a chosen scenario by adding appropriate graphics. My start point was usually the technical aspect of the code. How was I going to make the next game better than the last and anything else around? That usually meant playing around with the graphics routines to get faster drawing and a new presentation idea.  I would then look at the result and work out what kind of movement would fit in with that presentation and that would suggest game ideas.  For example the Avalon room presentation came about playing with the horizon of Lunattack and adding some corners to see if a room effect could be achieved.  I then drew some graphics on paper and cut out a screen on a big sheet. I moved the "screen" over the drawings to see what worked and what didn't. That was far easier than coding it up and changing it. That gave me the scale of the graphics and the design just fell out from there.

Deepest Blue Progress.

It as time to get the code working as a game. I could fly about, shoot up other ships and collide with them. I had ships trading with bases that produced products from raw materials. I needed to complete the loop by getting the raw materials in the game.

I had already written a random asteroid generator to provide 3d models of asteroids. So it was time to write the game code for the asteroids. They didn't need to do much, just sit there  moving and rotating at a constant speed until disturbed. They needed to react to collisions and split apart when fired upon. I gave each asteroid a percentage purity and a precious recourse and a background resource. The precious resource could be found by splitting the asteroid to find the nugget.

I soon found problems with the collision routine. As I was adding new classes of object I was getting more combinations of colliding objects. Each class had a collision event handler but that was leading to code in two places. I changed this to have a central collision handler that worked out if the combination of objects had collided then called each  class handler to deal with the result of the collision.

I needed a system to let the player know what was in an asteroid so wrote a simple scan routine.
I used a line shape that I modified during the scan to give an interesting pattern, representing a laser scan.

I couldn't make my mind up how to collect the goodies. I didn't want it to be tedious but wanted some skill. I thought I would sleep on that and am still deciding.

Scanning an asteroid

I thought I would finish off the flying AI I had started ages ago and left unfinished. This was loosely based on the algorithm I had used in Avalon and Dragontorc. The idea was to have a set of base movement routines, such as fly towards, fly away, keep to a distance, keep parallel to etc. Then more complex behaviour is built up by choosing from a chance table that has the chance of performing each of the primitives. Then you can have many complex behaviours that can be organised in a table and indexed with data such as ship type, pilot fear, pilot aggression etc. The beauty of it is that the heart is really simple but you can get realistic complexity. In Avalon if you did something frightening all the timid meanies panicked and tried to leave the room .

I already had a couple of routines I could use as primitives. I needed some specific ones for the ships that could fire broadsides and for ships relying on missiles. I built these from the existing routines. It is better to adapt than to write form scratch, you get there faster and the routines are written to a pattern that makes them easier to understand and change.

When I tried the enemy out I realised the formations were not flying very well, more like a swarm of drunken bees than a well drilled formation. So I decided to have a look at the formation code.
The more I tried to get it right the weirder the flight paths became.  When modelling things like flight paths it can be hard to distinguish between errors in design or errors in implementation. A simple bug can fool you into thinking you have the formula wrong.  My main problem was that the ships were just not settling down in their formation positions . They would fidget about till they lost the plot and flew off and back to realign themselves.  I realised they needed to steer towards their destinations but shouldn't really turn if they were too far forward. They should adjust their forward speed. That worked for moving formations but not for static formations. In the end I had to use a mixture of steering and directional thrusting.  To stabilise the steering I got them to steer towards a point ahead of their formation position. Its working pretty well now unless the leader does a tight turn. The ships on the edge of the formation have to either stop of go very fast to maintain their position. That's the trouble when you make things realistic, you meet the real problems that happen.

Next thing to do is to get this working as a game. I badly need to put in a futuristic web system to display all the ancillary data such as start maps, news, trade screens, pilot rostas etc so the player can see what is going on. This will interface to all the background data systems and let me see if they are working properly. I have already written a trading system but no user interface. I can just about see the light at the end of the tunnel but there is still a long way to go. Ive been distracted by the sunny weather and by my new Traps edrum kit but cant wait to get this playing as a game.

Programming Tip.

Fast floating point.
Floating point used to be so slow that you needed to minimise its use. Now its fast but you can still improve the speed by cutting out unnecessary float operations. I use macros or simple subroutines to do things that can be decided just by looking or manipulating the data.  These work by understanding the underlying storage format of the float.

//floating point acceleration
#define FP_EPSILON 0.00001f 
//is it zero
#define FP_IS_ZERO(f) ((f)<FP_EPSILON && (f) > -FP_EPSILON)
//is it positive includes 0
#define FP_IS_POS(f) ((*(UDWORD*)&(f)) < 0x80000000)
//is it negative
#define FP_IS_NEG(f)  ((*(UDWORD*)&(f)) >= 0x80000000)

#define FP_SQRT(f) (FP) pow((f), 0.5f);

(*(UDWORD*)&(f))   Is a bit of a mouthful. I hate C like that but its necessary.  In English it says working from right to left:
&(f) Take the address of the input argument F.
(*UDWORD) Consider the address pointing to a 32 bit integer.
* take the contents of this.

UDWORD is my custom definition of int 32.  I always use custom types rather than the native types. The reason is you never know if a C implementation will change the underlying type. I like to be in control. I can choose what the underlying type is for each of my types and adjust if necessary.


  1. Video games are electronic, interactive games known for their vibrant colors, sound effects, and complex graphics.
    Always old is gold checkout this arcademaverick Games
    cocktail arcade table pedestal


Post a Comment

Popular Posts