Wednesday, October 17, 2007

Taking it up a level

Quick entry today. Found a few hours to progress Solar Wars. Nothing visual to show really so I'll describe what I added. The level loader is now present, I can write an Nx8 byte array to control the layout of each level. Clearly some levels have more objects than others hence the ragged length N. The objects that can be defined are:
  • Standard mirrors (placement, orientation, ownership, starting condition)
  • Really Big mirrors (placement, orientation, size)
  • Blockers (placement, orientation, size)
  • Splitters (placement, ownership)
  • Prisms (placement, ownership)
Yep, I added big (fixed) mirrors, I think this will make the levels more challenging (read dangerous) on later levels.

Now I need to sketch a few. This won't be a big deal as they are really just a few hurdles to provide variation for the players. I imagine in the 2P mode there will be favourite levels that will be played repeatedly. At the moment I'm not sure whether to allow the player free selection of the levels or to unlock them progressively like in Spike's Circus.

I've also been pondering the AI off-line. To respond to cNp's query: it always depends on the game and what heuristics the programmer can devise. The Joust AI was really easy to write, even the skill levels of the various CPU opponents and their personalities. On Solar Wars it's a little harder since there are literally more dimensions to consider. I have figured a few methods for the CPU AI, but first I'm going to finish the 2P version and study how real humans play against each other (to get a bit more variety in style.) At Eurocon I'll do some 2P play testing and then add the AI ready for the full release shortly afterwards.

Monday, October 01, 2007

Putting the game together

A few more hours today, all went rather well. I'm pleased that the code let me add the odd test/branch here and there to begin shaping the game play. Today was really about behaviour and adding constraints to improve the player experience:
  • added energy bars to the solar emitters / players
  • added damage to the mirrors
  • added visual bars to show their status
  • switched the object indexing from integer to pointer based
  • enforced cursor switching
  • restricted moveable objects to those owned by each player
  • restricted moveable objects to those not being fried by a laser
  • restricted object movement to when the player has sufficient power
  • out of bounds collision detection for the cities
  • status of cities
  • mirror destruction
  • mirror spawning
  • All 4 buttons mapped and functioning.
The screen shot shows an energy bar for solar emitter and separately for the specific mirror at P1's cursor. Some of the P2 cities have been destroyed.

Oh, and I finally got around to moving the sun into ROM, freeing up about 100 bytes of RAM!

Next step: Designing Levels!

Wednesday, September 19, 2007

Smooth Times


This went pretty well. You can see from the video above the laser calculations are performed over several frames. However whilst this suits the Vectrex it's not accurate since it's not observing the speed of light!

The second video shows a close up of some debug counters. From top to bottom they show, frames taken to render, vectors rendered, beams processed. The good news is that they start counting but the laser doesn't appear until the end. (which is what we wanted.) The thresholds are all parametrised and the frame rate doesn't get affected when the beams are calculated. The only offset is that the sun needs to be a little higher in the sky for the beams to fire, and I think that's a nice side effect!


It all went smoothly today, which is lucky since there were several distractions. However I've firmed the code up for B1 to select object. B2 (held) enables J1 to move an object, or when released J1X rotates it. This has taken me to a junction to ponder on the game design. (I'll keep my ideas until next time though! ;)

Tuesday, September 18, 2007

Game play introduction


This video introduces a new concept and illustrates nicely what the sun is for! The weapons are solar powered and hence only activate when the sun is high in the respective player's hemisphere. Here we can see P1 and P2 weapons firing in turn as the sun moves. Note they are sharing components currently, but the results vary depending on the originating beam direction. Without moving components the effect would repeat so you can save bandwidth and simulate a successive "days" by hitting play again. Objects may be moved in real time independently of the turn based firing.

Incidentally the beams look very complication and only flash up for an instant. I suggest you use the blogger player pause button to examine the P1 and P2 laser configurations to see what's going on in a comfortable time frame. I will be using this object configuration to test the coding in step 2 below.

Tomorrow will be divided into 2 areas. 1) Removing the debug control mode and fixing the 1P and 2P controls. This will involve a little more design as I want to determine the features to permit a player to use. Currently my dilemma is whether to permit a free roving cursor for sabotaging enemy objects. My feeling is it will slow the pace down, we'll see what happens! The second area 2) Will be some reasonably hardcore code to spread the computation of the beam reflection calculations over multiple cycles so remove any display flicker. This will mean I need to freeze a computation status when time gets a little shy, and resume it on the next display cycle. It should be OK as I have used a lot of variables (bad me,) so saving the registers and adding a state engine should be all that's needed. Once that's in place the core engine will be complete, just needing improved collision detection (for which there will now be time if it is spread over multiple cycles) allowing me to concentrate on gameplay and making the game FUN!

Step 3 will probably be next week, which will be building the level engine so that difficulties and parameters such as object and their location may be controlled for each level.


Today's Progress

A good day today, first off I wanted to clear up the cities. My cycle counter showed that to draw 6 on screen at once I really had to trim things down. I liked Cecil's but it had too many vertices, so I took some inspiration from the cities in Patriots by the eminent JD. :) They're functional, look OK and are real quick to draw!

This first photo shows the cities nicely. Flipped for the 2P. Yep, this game is designed to primarily be a two player game. I'm pretty confident there will be a nice puzzle element for the 1P game option, but that will depend upon whether the 2P style can be maintained with some cool CPU AI. Note the second laser emitter too.

The huge square is a blocker, this will be one of the features to provide variety on different levels. These will essentially be laser-proof barriers. Some will be destructible some won't. They won't often be this large, but I just wanted to check the concept. you can see the laser just dies when it hits it.
I wanted to finish off the objects so I could move more toward the game play, hence I add the Splitter. This is a simple T piece. A laser hits the T vertical and is split into 2 beams perpendicular to the incident beam. In programming terms I kill the beam and spawn 2 new ones. This reduced beam wobble and gives me a chance to align both 2nd gen beams with each other more accurately. As you can see in this second photo, whilst the beam is indeed split to 90 degrees of the incident the spitter sprite is not currently rotated. I've no doubt I'll sort that out later, but for the moment I didn't want to waste the RAM. (Still need to reclaim the RAM spent on the sun, but I'll leave that for a dull day.) I'm pretty happy with the splitter, since my code was sufficiently modular that I was able to add it in only a few lines. In fact it was so easy I thought I'd add another object just for the fun of it. I hadn't planned to use it, so we'll see how it features in the final game, but I think it looks pretty cool.

This third picture shows the extra object.. the Prism. A nice refracting effect, and I think it will greatly increase the sophistication of game play strategies.

Visual alignment is not yet perfect, but that's because I wanted to get the code working rather than the cosmetics. It's a trivial thing once I determine how I want to sort the rotation. I'm thinking I may differentiate between the prism and the splitter, by only permitting rotation on the splitter.

The final pic looks rather busy, this is showing the game concept coming together nicely. Here we can see the original laser coming up from the bottom of the pic where it strikes the splitter. It branches left and right. The left beam simply hits a mirror and collides with city #1. The right beam hits a further prism which splits the laser into 3 beams. Nicely clipping cities #2 and #3. This would be a good result if it were being played for real here.

Saturday, September 15, 2007

Normal services resumes..(shortly)

Hi Guys,

Sorry for the pause in updates, you haven't missed anything, I've just been a little busy with my day job! :) There are scheduled coding days Tuesday and Wednesday this week, so you should be spoilt for updates! :)

Meanwhile here's a submission of a city graphic from Cecil C. inspired by Missile Command. (Thanks Cecil, all submissions are much appreciated and will always be shown in this blog.) I'll be exploring the options on this one, but the number of vertexes is still an issue since there will be 6 on screen simultaneously.

Wednesday, August 29, 2007

Pitcher's Duel

Just a quick video clip in case anyone's curious.
I wouldn't dare review it since I'm British and therefore know nothing of Baseball. :p



Note this is not a Vectorzoa game-
Just a clip of the recently released Pitcher's Duel title launched at CGE2007.

Tuesday, August 28, 2007

Quick update

Hi folks, No updates in while, been a combination of work commitments and holiday over the last few weeks, and then finally this weekend just as I was limbering up for a Vectrex day.. serious back probs! :( Hopefully be back in the saddle for next weekend. The Eurocon release is in no danger.

Meanwhile though, my Pitcher's Duel finally arrived. Thank's to Sean for the black one and (a no doubt reluctant) Mayhem for my greenie! ;)

P.S. Looks like Blogger are now supporting movies, so expect some clips as things develop.

Thursday, August 02, 2007

Day 7 - Improving Presentation

A productive session. Firstly as promised I improved the collision detection. The 3 frame pic above shows: (note the blazing sun!)
  1. how bad it was
  2. overzealous detection
  3. just right
I added the parabolic reflector, I think it looks pretty cool. Note also how I have removed the collision clash zone boxes as I thought they were offending the eye. Of the two bars at the bottom the higher one shows "how hard" the Vectrex is working, clearly a good sign that we appear to be on about 60% remaining output at the moment




This final pic shows again the laser emitter and also three cities at the bottom, these will be Player One's lives. I'm not entirely happy with these at the moment so if anyone wants to offer a Vector sketch of a "missile command style" city then feel free to email me. I'm looking for something of less than 24 lines, preferably that can be drawn without taking your pen from the paper. :)


As you can see the cities have taken a fair bit of processing cycle to draw. (We're down to about 40% remaining.) I'll need to keep my eye on them.

Compiled code size 5785 bytes

Tuesday, July 31, 2007

Orbit

UPDATED. New Blogger hosted movie of the Solar Wars sun orbiting.



Thanks Blogger! ;)

Sunday, July 29, 2007

Modern or Classical Styling?









As you can see the graphics are coming along nicely! Well actually these aren't real screen shots (suprise!) but on the left is a real life solar power station in Spain, and on the right a standard radio telescope. I need a giant solar reflector to emit my game lasers, so I think I might use one of these as the basis. Clearly it will be in vectors, and therefore very rudimentary, so whilst I prefer the image on the left the one on the right might be more recognisable (and more animation compatible.) Please leave a comment to vote for the left or right images or suggest any other images/concepts that I can consider.

Day 6 - Sunrise!

It's been longer than I'd prefer, but I just grabbed another hour on the Vectrex. If you recall the next step was to add multiple lasers. Thankfully everything was implemented in structures, so I just added list wrappers around the structures and all seems in order. The pic shows two parallel lasers. I need to check out the memory constraints and extend the segment lengths, but I'm hoping we'll be good for up to 12 ideally. (Day time pics get background reflections, so I've blacked parts out to avoid distraction.)

Now it's time to start adding some context and game play. I tend to find sprites help with this, so it's time to do a little drawing. Since the game is called Solar Wars what better start than the sun! Of course this is a Vectrex so Vectors are the order of the day. It's not easy shading with Vectors, so I had to be a little cunning. I had thought I would need a lot of frames for this, but it turned out only 4 gave a nice effect. Bonus! Currently the sun in rendered in RAM, but when I have a moment, I'll run the data through my PC to get the ROM trails (to conserve precious RAM)
You can see the cycle line and the 033 look positively dull in comparison to the Sun! Oh by the way the sun also orbits the screen, but for this photo I froze it. Maybe I'll take a pic or two tonight when it's darker, and easier to take the shots.

At the last moment I think I discovered a bug with the second laser collision detection, so maybe it's time to evolve the CD a little more. I'll improve the resolution and iron out any bugs in that area.

Saturday, July 21, 2007

Day 5 - 2 mins very well spent!

Yes!!! Cooking on gas today! Literally spent 2 mins on this, (spent more time on the photos!) Even better I saved a byte on storage. As you can see the dark matter has cleared off and the beams travel as intended. The left pic shows a beam entering from top right, hits reflectors (numbered spiralling clockwise inward from bottom left) 4,3,2,1,4 in turn. (and yes I like using the same reflector twice.) Pic on the right is a little more complex. Beam hits (4,3,2,4,1,3,) Nice. (OK, I admit I'm chuffed! From now on we should be set. Not sure when I'll do the finer collision detection, it's no biggie. Next step will either be some sprites or a second beam. Have to see what mood I'm in. I doubt it will be long until my next session. (Thanks to J.K. Rowling's latest cash cow.)

And the hero of the day is the small dot you see in the top right of the second pic. This enabled me to realise what the bug was. It shows the screen edge detection was correct all along. (Drowning man, at the time.) So armed with this knowledge I was able to see I was only plotting the total number of segments that the last reflection required to hit the edge of the screen. Muppet! Thankfully a problem identified is a problem solved.

Actually I did spend more than 2 mins, I spent another few mins adding the ability to move each reflector. Remember we had selection and rotation in Day 4, so I added moving if B3 is held down and J1 tweaked. Beam direction has now shifted to J2.

Snuck a new pic in.. (Dark with ISO400)
Compiled code size 5266 bytes

Friday, July 20, 2007

Day 4 - Is the earth flat or doughnut shaped?

A few hours this evening. Nice to be back in 8 bit land. No interlude yet, it was a busy week at work with little time for side interests, so tonight's work was spent on the main game. You may remember Day 3 was a bit of a mess, so I rewound a little and added got things working a lot more simply this time. I'm still using the coarse collision detection as that's just tidying up which we can save until later. For the moment it's all about getting a 2nd generation reflection.. (beam enters facing left from top right.)

Success! ..But.. I get multiple reflections now, but strangely the beam stops prematurely. I have code to determine when the beam hits the edge of the screen, but somehow it also seems to hit something at other times. Either I've discover a dark matter detector, my world is a torus, or there's a mysterious bug in my code. I suspect the latter at the moment, but I'll update you. Most evidence seems to suggest it's when I cross the centre axis, i.e. as my "sign" changes. I'm using an ADDD with a BVS check which I need to ponder on whether it's the right choice. Usually naughtiness when you start bending signed and unsigned usage and checks (tut.) No doubt the solution will dawn on me shortly. Once this beam reliably hits the edge of the screen (or a consumer) I'll be moving on to improving the object handling. Oh that reminds me, you might have noticed a change to the layout. I added a 4th object (all 4 are now reflectors.) I removed the auto spin feature of the 2nd object and added an object select feature to allow me to rotate the reflectors independently for debugging (or maybe a more lasting reason..) You'll also note that one of the boxes appears brighter, this indicates which is selected for rotation (cycled with B1 & B2.)

Compiled code size 5182 bytes

Sunday, July 15, 2007

Day 3 - A Stolen Moment

Hmm, a 45 spare mins so I thought I'd do a little Vectrexing. It's never a good idea to spend a short period on the Vectrex IMHO, it takes a while to remember where I'm at and if I rush it, then I tend to go in the wrong direction. I'd say lesson learnt, but maybe this blog will record otherwise! Anyway at least it was fun. My pics tonight simply show some bugs, (one rather spectacular) resulting from tonight's dabbling. I have the concept of a Beam, having many segments, and many child beams. Segments in turn have many invisible test segments, but that's not important here (yet). Tonight I got a little carried away and created a new child for each reflection. I think on reflection (no pun intended, honest) that this might be unnecessary. I need to keep track of by absolute and relative positions, and my local origin. I think this might be better achieved using temporary variables and keeping the number of child beams to a minimum. If I use too many child beams, then it kinda defeats the object and it will both increase the memory I use and reduce the drawing speed when I choose to render the segments of each beam.
This pic is why I Vectrex.
So my next step will be to revisit my code between Day 2 and Day 3, and replicate the functionality whilst keeping my child beams to a minimum. I figure with the nature of my plots, I can aim for about 10 segments (possibly including 4 reflections before I need consider a beam will be "full" and a new child will be forced. This permits Vectrex Beam recalibration and will reduce wobble. Check out this second pic. I grabbed the camera as quick as I could as the screen was frying! You never get bugs so beautifully illustrated on any other games console! (and this is with a very low brightness setting and beam insensity set to $3F; about 25%.)

Not sure when the next session will be, as there may be an interlude as I try a new idea I've (just) had. I'll document that as I do it too, although I am sure I'll be back to continue this project within 7 days.

Monday, July 09, 2007

Day 2

Another day, and so soon, I'm blessed!
Last time I promised a little more visual output and the day has delivered. Still just over-engineered lines at this point, but much progress.
Today I was reminded of the triangle of Vectrex programming:

ROM Vs RAM Vs CPU (Speed)

You can pretty much do things in an infinite number of ways, but the quest is always to find the balance. Today my trig tables were in ROM, my rotated co-ordinates were in RAM and CPU did fairly well out of the deal (although I did a lot of 16 bit arithmetic rather than 8bit.)

So here's some photos of the day's progress:


First off, I was pretty comfy with the line we had on day one, so I wanted to introduce some obstacles. These boxes surround enlarged lines (my simple obstacles) The boxes are just for reference and will disappear later. The lines are also drawn at the navigation scale rather than the efficient fine detail scale they will eventually be drawn at. But they look nice and the geometry works for angle angle in vegrees.





Next a rather clumsy attempt at lo-res collision detection. I spent a little bit too much time on this, and eventually I decided that this method was too processor intensive and not accurate enough. Coarse collision detection is great, but it should never be less than generous!

Also if you look closely you will see the long line is in fact made of 3 shorter ones, this is because I wanted to draw them at a reasonable scale as very long lines can take an age to draw on the vectrex and look blurry. This way, I can keep sharpness without too much compromise. Each line is also sampled about 20 times en route to ensure it doesn't hit anything or fall off the screen. If a line matures to full length then it is drawn and the fractional checking disappears.

This shows a zoom on the second pass collision detection. The box is now very small, less than 1cm. The dot can be steered (for debug purposes) into the hi-res collision rectangle. When it "collides" the dot blinks (the photo won't show that! :) The blured effect is because the line is rotating at about 0.5Hz to test all collision eventualities. I had a little fuss making sure my bottom left didn't become my top right, but eventually I sorted that out. :)
I'm not using this hi-res rectangular collision detection yet, but I will as a second pass. The dots that trace the line we saw on day one, will be used as a third pass collision and will provide extremely accurate collision detection (CD) to make sure everything looks nice.



The final fruits of the day! An incident beam matching a very coarse collision detection and "bouncing" off at the correct angle. Not using the finer CD as mentioned, and note the box for debug purposes, in shows nicely why the CD thinks a collision has occurred. The beam and the obstacle may both be rotated on the joystick for debugging. I'm pleased with this solution, currently it looks very simple, but the engine under the hood will scale considerably (at least that's the intent.) I notice with a grimace that if the reflection strikes a second obstacle the Vectrex hangs; something for another day, but I'm confident it will be a minor tweak. After all the prep on the straight lines the bouncing angle was only 4 additional lines of code which fitted in nicely.

Compiled code size 5000 bytes

(Happens to be a round number by fluke! Note this is already 20% bigger than Star Sling's 4096 bytes, I guess you can see how the each of the 3 resources complete (ROM/RAM/CPU) Star Sling was imperative to be a fun, two player game with analogue controls that fitted in 4096 bytes. This game I will allow to go to the full 32K if necessary, but I will stick the the standard 880 bytes of RAM. At the moment, I suspect the constraint of this game will be the CPU, there are a lot of calculations to do depending on player events, so managing that will be interesting.)


Friday, July 06, 2007

Start coding!

Right, enough theory let's get typing! I've set up my trig tables for later and confirmed the algorithm for the bouncing light. Now I need to tie it together in Vectrex speak! As I said before this can be tricky since even simple maths can get tough without fractions or dividing..

However, setting an angle and drawing a vector is trivial, so that happened very quickly and was more a question of remembering my compiler flags! The line was simple, but as is often the case the collision detection might prove tricky. What I needed to do was to draw a line, but to know exactly where each point was along that line. So I did a lot more maths to determine how to work out each 'y' for each 'x', generally its easy to trot along the hypotenuse but a little more effort to pop along a single axis. Anyway I got that in place and now you can see a very unimpressive line with some dots next to it. (What you can't see is the line rotated when the joystick is moved. Also the dots are deliberately shifted to to the right so the are clearly visible, yet still aligned.) These are drawn to show I "know" each dot along the line. In a later version I may go back to my sin/cos pairs but in this example I tried the slightly more tricky tan based method in case I need it later. (As I type this the sin/cos seems to fit the requirement once, more.. I guess we'll see over time.)

This is one of the things about Vectrex coding, some things are really easy and some things are more challenging and there is often a fine line between the two. In this case I was really pleased with my dots, even though they won't be seen in the final game and are just for behind the scenes calculations. Any also they look inferior to a line which is easy to draw! :)

Not sure when my next chance to code will be (hopefully soon), but I'm sure there will be a lot more visual results at that time, since must of the planning (for this stage) is now done.

Compiled code size 3814bytes

Day 1 - Power up!


Having been away from Vectrex for 8 months, I thought it might be time to fire up the little beast and see what happens. So this morning I cleared my computer room, plugged in my Vectrex dev PC, rewired everything up and crossed my fingers. I ran into a few difficulties first this setup was much less elaborate than last years arrangement, for one I was only planning on using 1 monitor. In an amazingly inconvenient turn the EPROM simulaor software insisted on only "displaying" on the second monitor position, (which wasn't present any more) no amount of display setup config would stop it whizzing off the start bar and out of the screen! Eventually I managed to find the keyboard shortcut to move a window without the mouse. Alt-space, down, enter (eventually.) Not a pleasant start! Second problem was the EPROM simulator wasn't recognised by the vectrex, just constant Minestorm! Thankfully this was easily solved, I unplugged the sim and plugged my second one in instead. I'm assuming it was just a bad combination of Vectrex and cart edge, hopefully all these snags are behind me now!

More prep

OK, I've done some sketches and I've figured out how I want things to work and the math(s) behind it. Now the hard bit is to bend the math so that it fits Vectrex hardware. I guess I should point out what makes things tricky.
1 No floating point numbers (no fractions or numbers between 0 and 1)
2 No trigonometric functions
3 No divide! (although you can write your own)

My solutions.
1 I use two bytes for my numbers, I guess you could call them the ones and 1/256s columns (as opposed to 1s and 0.1s). I have my own routines that deal with signing, adding and multiplying these numbers. Multiplying fractions it especially useful when we get to (2)
2 I use pre-calculated lookup tables (normally produced in MS Excel) these lookups map angles in Vegrees (256 vegrees in a circle) to my byte fractions in 1/256s
3 Simple integer division I do manually with subtraction. Non integer division I try to avoid or multiply by reciprocals.

Since I use lookups for my trig I need to decide which ones to use. Normally Sin and Cos are all I need, and these tend to be in 2 bytes form. SSSS used only a 1 byte Arctan table. I figure the new game will need Sin, Cos and Tan. So I add to my existing Sin and Cos tables using Excel spreadsheet exported as CSV.

I figure it's about time I powered up the Vectrex to start coding!

Low tech and high tech

Remember I've still not gone near my Vectrex yet, and there's more yet to come before I do! I bet this one will comes as a shock.. I need to test the basic maths behind my game, it with involve reflection and as every schoolboy knows with regards to a reflection "the angle of incidence = the angle of reflection" - but I wasn't sure what this meant with regards to the maths in practice..

A few more scribbles and I had a theory, basically I wanted to know it terms of "absolute angles" (compass bearings) what angle a reflection came off at. My pen and paper scribbling came up with
r=2s-b
(where r is the angle of reflection, s is the reflective surface angle and b is the incident beam angle.) I thought it was right but wanted to test it. It's times like this I yearn for the convenient simplicity of an 8-bit microcomputer with integrated BASIC and simple video display commands, like a BBC Micro, sadly times have moved so I reached for the 2007 equivalent.. C# on the Xbox 360! :)

Actually the 360 this is a mixed blessing, for all the time I save with native floating point and trig support, I lose again turning off all the fancy 3D and the textures etc! Anyway about an hour later I had my test (I know an hour's a long time, but C# and the 360 are all new to me!) I took a photo or two:

The red beam is incident, the pink is reflection and the yellow is the reflective surface. The joystick spins the reflective surface and confirms my math to be correct.. I'm ready for the next step..