Tuesday, 26 June 2007

Flash isn't as mature a development environment as Adobe would have us believe

There is a Holy Grail in software development, an ideal that many good developers strive to achieve but often fall short of. This ideal is the seperation of content and code into different 'tiers'. This is the model I'm attempting to create using Flash 8 and Actionscript 2.

To do this, I have attempted to make all my resources external to the actual engine. This is equivalent to seperating presentation from business logic and helps to make software reusable. This causes some problems in Flash itself, because its primary commands for duplicating assets (DuplicateMovieClip and AttachMovie) do not work with external assets, only assets that are part of the movie itself. The way around this is to load entities in multiple times if you need to use them more than once, using the MovieClipLoader class and because downloads are cached this should work fine.

However, this is where I hit a bug in Flash. If you are loading assets from inside the cache, sometimes onLoadInit (the event that is fired when an external resource has loaded) doesn't fire at all, making this whole technique useless. Way to go Adobe.

I ran into this problem when working out my collision detection code. I started with asteroids, as these are a lot easier to program than enemy ships and moved onto splitting apart larger asteroids into smaller ones and it was at this point I hit the wall.

It looks like the Holy Grail is going to stay just that way with this project because of this. I will have to include some resources inside the flash file because I have no choice - something I'm not very happy about.

Tuesday, 19 June 2007

To infinity and beyond!

I have been looking at doing some work on blowing things up now that I have laser fire in the Freeform Space engine. In order for the player to blow things up, I first have to create some collision detection code in order to detect when something has collided with something else. I figured that the easiest way to do this would be to create a test case with an asteroid field - after all, asteroids don't require all the clever AI that enemy star ships do.

Thinking about asteroids led me to improving the planet that I had got in the online demo because I wanted my asteroids to spin and not be static. The planets also would look better if they rotated (and I don't mean the standard rotation in flash along the middle of the bitmap, rather, the centre of the sphere as planets are spheres). To create a believable 3D effect involved some clever actionscript, a class that replicates an infinite background (in the same way as the parralax starfields work) but using a circular mask that is created at runtime. Finally, to give the illusion of 3D, a radial gradiant masked black image is put on top, so the edges of the planet taper off into darkness.

All of this has been more difficult to program than I initially thought, mostly because the engine is frame rate independent. This means that if the frame drops, the speed of things does not. For example, the speed of the ship is constant whether you are running at 1FPS or 100FPS, but at 100FPS you get a much nicer, smoother display. This is what you normally get from a 3D engine and its fun (although time consuming) to add it to a 2D one.

The current online demo features a single asteroid and some pixel perfect collision. You can test this by flying the ship close to the asteroid, when it gets really close the shield will dim slightly (this is the radial distance check collision which is really fast to do) but when you get even close the shield will dim a lot (this is when the pixel perfect testing has picked up a real collision between pixels). You will notice that when the radial detection is triggered, the frame rate will drop as the expensive pixel perfect collision detection is switched on. In general, engines will approximate as much as they can for speed reasons and if you monitor the frame rate you will see why I have taken this approach.

I still have lots of issues to sort out, such as getting the laser shots into the collision detection tracking so that the asteroid could be destroyed. I've also been bug fixing an issue that could cause the X and Y coordinates to become infinite on a long load time but it seems I still have some inconsistencies in there - sometimes the planet shadow on the current demo is incorrectly place and a refresh of the page is required. Lots of fun.

Wednesday, 6 June 2007

A complex engine

I started to learn Actionscript in January, having messed around in Flash to make the odd banner advert or fading alpha image from time to time and have really got to grips with AS2. I'm hoping to move ahead with AS3 at some point soon but as my AS2 compiles under Flash CS3's AS3 mode anyhow, there is no rush at this point.

Anyway I'm digressing somewhat. I was recently wanting to create an online story based roleplaying game and so converted my conversation engine from Lingo (Director) to Actionscript (Flash) as a nice class based little bit of kit. Flash has problems reading files that Director doesn't, however, so I figured I would hold the conversation engine data in a database online and expose it to Flash through an ASP file that it's LoadVars command could communicate with. This worked a treat and I was able to convert my code, create the database and admin forms, in just a few days.

I will be using this code within Freeform Space to generate menus and conversations. The aim is to get some missions in there and have some form of negotiating (like the original Freeform, but more complex, like in Frontier), so this wasn't by any means wasted effort even though I've switched my focus to totally different game idea.

This backend technology is used throughout the existing Freeform Space Flash engine, even the online demo uses it. The FSF engine itself contains Actionscript coding, a vapour trail symbol and a laser shot symbol - everything else is external. The engine queries a database through an ASP page to get a list of everything it needs to import then begins to download each item in the list. You can see it doing this in the demo, the loading sequence begins with a database query and then it proceeds to inform you of each item it is downloading.

The only exception to this is the sound effect, which so far is loaded in as required and not before hand. I may try experimenting with putting it into the database as a download list to get rid of the slight lag the first time the lasers are fired, but its come about because to my knowledge you cannot import a sound file and just play it through code without manually going in through Flash and ticking an "export for Actionscript" box which obviously cannot be done if the sound is not yet inside the movie and is loaded at run time.

I have some other limitations from Flash to content with too. It would seem that you cannot duplicate a movie clip that is downloaded at run time. This could be problematic later on. If I need ten of the same ship, will I have to download the same graphic ten times? Presumably the browser cache will really help me out here if this is the case.

The engine is already quite complex and there is a lot more to do yet. Time will tell if I have to change my approach, but for now, I'll keep trying to achieve the Holy Grail of seperating code from content.

Radar added and bug fixed

I've been ill the past few days and spent them away from work recovering and so spent some time doing more development on the Freeform Space project in Flash. I've created a new blog here (which you may already be reading, but I'm echoing all Freeform Space information on Spectre Software too so there are two ways of getting to it). The upshot of this is the development of the radar system, firing and playing of sound files from within the engine.

The radar system wasn't half as tricky to implement as for previous projects (such as the original Freeform). This is because, using a top down approach to the main flight engine, the radar is itself another 2D representation of the same thing. The fact that it is circular meant I had to use some really basic trigonometry to check if a blip should be drawn on there or was out of the bounds of the display. Because this was so easy to develop I expanded on it a bit - if you load up the demo here and fly far enough away from the planet, you will see that the planet blip itself will shrink and then eventually "lock" against the edge of the radar when it is no longer in range of the radar - to give you an idea of the general direction you would have to go in to get to the planet.

I've also now get a firing routine in there (clicking the mouse fires the lasers on each wing of the fighter vessel) and of course a laser noise which is triggered at the same time. The noise is an external MP3 to the flash movie (actually, almost all of the assets are external, except for the vapour trail and laser) or generated dynamically (such as the star fields), which means that the first time the laser is fired there is a slight delay on the laser sound playing until it is downloaded by the player. I'm not sure what to do about this as I'm trying to avoid embedding any assets into the flash movie unless I absolutely have to. I may tie the laser graphical response in with the sound loaded event so there is a delay on both happening the first time and not just a delay on the sound. Subsequent firing seems much better. For reference, the laser sound is an MP3 file 16kb in size.

Any feedback on any of this would be appreciated.

Online Freeform Space project

A while ago I had an idea to make a 2D version of Elite that ran in a web browser through Macromedia Flash. Elite as you may know is the basis of Freeform, one of our most successful projects and one I always wished to create a sequel to (called Freeform Space).

Recent discussions with work colleagues about procedural generation led me to explain how David Braben had managed to store eight galaxies, each with hundreds of star systems in them, in only 32k of RAM on a Sinclair Spectrum. A few days later, at the weekend, all of this added up to me making a start on a new engine in Flash. I had recently converted my conversation engine to Actionscript from Lingo because I wanted to create an adventure game engine in Flash and I could use this in this project for such things as menus and missions.

So here is what I have so far. It's very basic stuff, is class driven in AS 2 and demos an idea for the control system:

http://www.spectresoftware.com/db/oae/public/fs.aspx