Yes, it's been way too long since anything was posted on the blog, but the amount of blog activity is generally inversely proportional to how intensely I'm working on the game!
I'm pleased to report that a closed alpha testing session is currently taking place, which should help iron out any system-related issues. Things are looking good so far for the main game engine being stable over a variety of hardware configurations.
After a few iterations of testing and improvement there will be a general alpha release posted on this blog, so watch this space!
This is the blog of Brainworm Software, which currently concentrates on the development of the indie game Juggernaut.
Showing posts with label juggernaut. Show all posts
Showing posts with label juggernaut. Show all posts
Sunday, 30 October 2011
Sunday, 10 July 2011
Token post!
OK, I say I'll do more regular updates and then immediately fail to post anything for a week. Welcome to OppositeLand, population me.
Work is still ongoing, worry ye not, with the focus on improving the scripting system and I/O for the more complex objects within the world map. Also, within the main asset management system there's now an overall object dictionary that handles everything from physics objects to particle fountains, allowing them to be spawned easily in a unified way.
So yes, at the moment it's all core engine work, but this is all necessary (except for a few sidetracks) in order to achieve my current main goal of scriptable game objects.
Work is still ongoing, worry ye not, with the focus on improving the scripting system and I/O for the more complex objects within the world map. Also, within the main asset management system there's now an overall object dictionary that handles everything from physics objects to particle fountains, allowing them to be spawned easily in a unified way.
So yes, at the moment it's all core engine work, but this is all necessary (except for a few sidetracks) in order to achieve my current main goal of scriptable game objects.
Thursday, 30 June 2011
The start of a series of shorter updates.
Up until now I've tended to try and get out one decent-length blog post a week during development, but I think I may change that pattern to trying to post something short today to give a quick snapshot of what I'm working on at any given point.
The main thing I'm up to at the moment is working on the world scripting - my primary goal is to create an animated door that can open/close based on interaction with a world object. I've already gotten the main scripting up and running, such that interacting with a destroyed ship will update the amount of resources you have, give you a new ship component or start a given bit of narrative, but this push towards having a properly dynamic environment will make a lot of difference.
The custom scripting language and the asset management system are tightly integrated. Here's an example of the current scripting that is implemented and working:
"$Timer #3.0 $ZoneResource1 #OFF"
The $ prefix is used to reference an asset that exists in the global asset management framework, and the # is used to indicate a constant value. In this case, there is a special asset called 'Timer' that allows scripts to be called with a specific delay; the #3.0 indicates that the delay should be 3 seconds, and the rest of the parameters '$ZoneResource1 #OFF' are the script to execute once the timer period has completed. ZoneResource1 is another interaction zone, and the #OFF value indicates that it should be rendered inactive after the call. If the last two parameters were replaced by 'script:ExampleScript', the asset management system would check to see if the ExampleScript asset were already in memory and, if not, load it in from a specific default directory.
[Foreseeing potential questions on this issue]
Why didn't I use Python? Because BOLLOCKS, that's why.
Of course, any time you try to do X in development, you tend to find yourself doing Y, Z and occasionally α to support getting X to work, as well as tidying up other bits that you come across while doing Y and Z. As a result, the damage callback system has been given a bit of an overhaul in the last day or so.
Right now, I'm working on an object factory so that a wide variety of different object types may be simply loaded, allowing enemy spawners, physics objects, debris, animated objects etc. to be loaded by the same framework. This will then mean that dynamic components (such as the opening/closing door) will be automatically created and assigned to the right list, and then may be scripted (after a wee bit of work on animation).
[Edit: OK, so that didn't turn out to be so short].
The main thing I'm up to at the moment is working on the world scripting - my primary goal is to create an animated door that can open/close based on interaction with a world object. I've already gotten the main scripting up and running, such that interacting with a destroyed ship will update the amount of resources you have, give you a new ship component or start a given bit of narrative, but this push towards having a properly dynamic environment will make a lot of difference.
The custom scripting language and the asset management system are tightly integrated. Here's an example of the current scripting that is implemented and working:
"$Timer #3.0 $ZoneResource1 #OFF"
The $ prefix is used to reference an asset that exists in the global asset management framework, and the # is used to indicate a constant value. In this case, there is a special asset called 'Timer' that allows scripts to be called with a specific delay; the #3.0 indicates that the delay should be 3 seconds, and the rest of the parameters '$ZoneResource1 #OFF' are the script to execute once the timer period has completed. ZoneResource1 is another interaction zone, and the #OFF value indicates that it should be rendered inactive after the call. If the last two parameters were replaced by 'script:ExampleScript', the asset management system would check to see if the ExampleScript asset were already in memory and, if not, load it in from a specific default directory.
[Foreseeing potential questions on this issue]
Why didn't I use Python? Because BOLLOCKS, that's why.
Of course, any time you try to do X in development, you tend to find yourself doing Y, Z and occasionally α to support getting X to work, as well as tidying up other bits that you come across while doing Y and Z. As a result, the damage callback system has been given a bit of an overhaul in the last day or so.
Right now, I'm working on an object factory so that a wide variety of different object types may be simply loaded, allowing enemy spawners, physics objects, debris, animated objects etc. to be loaded by the same framework. This will then mean that dynamic components (such as the opening/closing door) will be automatically created and assigned to the right list, and then may be scripted (after a wee bit of work on animation).
[Edit: OK, so that didn't turn out to be so short].
Tuesday, 14 June 2011
Because banging can be fun, can't it?
OK, the title is a reference to this video (RIP Roy Skelton), which is marginally justified due to this post including physical collisions between convex objects.
Since the last post quite a few significant updates have been made, which are best expressed through the medium of bullet points.
Since the last post quite a few significant updates have been made, which are best expressed through the medium of bullet points.
- The convex object collision detection/physics is working well (huzzah!)
- Springs (currently massless) have been implemented in the physics engine, which will form the basis of the tractor beam with Juggernaut.
- The damage and destruction framework has been significantly upgraded to include penetration levels for both laser and projectile weapons. For example, in the video you will see that the laser weapon immediately terminates upon hitting the debris, but passes through several Scourge enemies before terminating. A larger penetration factor for a weapon will improve its effectiveness against multiple enemies, but not against single tougher enemies.
- Each object can now have a convex collision shape associated with it that will be intersected with by laser + arc weaponry. This replaces the bounding-circle based object/object collision.
- Upgrades the asset management framework that allows resource files containing multiple asset types to be loaded in transparently. Dull, but very handy ;)
Sunday, 5 June 2011
Environmental decoration: instanced cilia
As well as all the ongoing work on the physics engine (the convex polygon routines now work except in a couple of extreme cases that I'm fixing), I've taken a little time out to make things more pretty. In this case, I've added some animated 'cilia' that will be used to add dynamic motion to some of the infested areas. The initial version of this is shown in the video below, although I've already updated the actual graphics to add a small bright tip to each strand, stopping it from just looking like grass.
Although there may be thousands of cilia on-screen at any one time, all the work is done by the GPU using immutable buffers. A specialised vertex shader adds the sinusoidal animation based on a time value supplied via a shader variable, as well as adding a small size variation. Also, rather than manually defining the position/angle of each cilia in a level (which would be quite memory-hungry), areas of cilia are just defined by a straight line with a normal.
To further improve the effect, cilia further away from the camera have their colour dimmed in order to provide a depth cue.
Although there may be thousands of cilia on-screen at any one time, all the work is done by the GPU using immutable buffers. A specialised vertex shader adds the sinusoidal animation based on a time value supplied via a shader variable, as well as adding a small size variation. Also, rather than manually defining the position/angle of each cilia in a level (which would be quite memory-hungry), areas of cilia are just defined by a straight line with a normal.
To further improve the effect, cilia further away from the camera have their colour dimmed in order to provide a depth cue.
Sunday, 15 May 2011
Progress Update
Oops, it's been over a week since the last update! Time really does fly when you're coding away.
OK, the main things I've been working on over the last week or so are as follows:
There's still some tidying up and improvement to do on this aspect, but it's sufficient for now. Have a peek:
Anyway, something that's been niggling at me since I upgraded to using the physics engine is the old hierarchical collision detection, which used a binary tree in order to calculate collisions with each triangle in the world mesh.
However, in reality, using all the triangles was quite wasteful and pointless, as the only important bits are the lines that form the outline of the world itself, and the corresponding bounding circles/bounding boxes were much larger than they needed to be. Since the world is carved from an overall vector brush, though, this outline is directly available, and thus I've refactored the code to produce a collision tree from a set of lines rather than triangles, leading to an overall improvement in efficiency and niceness. This is one of those things that won't have any directly visible effect, but makes further development easier.
OK, the main things I've been working on over the last week or so are as follows:
Player/World collision
This is now basically done, along with player ship damage and particle effects at collision points. The particle effects are a mixture of sparks and rock being disturbed from the walls, which looks quite nice when scraping along the side. It also need a good corresponding sound effect!There's still some tidying up and improvement to do on this aspect, but it's sufficient for now. Have a peek:
Scripting zones
In order to make a game with an interesting and interactive world, there need to be scriptable zones within the world that can do a variety of things, from bringing up a certain story conversation, spawning some enemies, changing world states (e.g. opening/closing doors) and a lot of other things. The basic scripting capability now exists, and is embedded within the main global asset management system. At the moment its capabilities are pretty limited, but these will rapidly expand as I add more scripting interfaces.Upgraded collision detection
For anyone unfamiliar with collision detection, the basic problem is one of testing your game object's bounding shape (a circle, in the simple case) against all the objects in the world. Now, if you have 10000 primitives (e.g. lines/triangles) in your world, the easiest way is just to test directly against each of the 10000 objects, leading to 10000 geometry tests per object. However, using a hierarchical (tree-based) model you can achieve this in around Log2(10000) = 13 tests, allowing much greater efficiency. Even better, if you increase the number of primitives by a factor of 2, you'll only need one more test. This scaling allows testing against very complex world geometry in an efficient fashion.Anyway, something that's been niggling at me since I upgraded to using the physics engine is the old hierarchical collision detection, which used a binary tree in order to calculate collisions with each triangle in the world mesh.
However, in reality, using all the triangles was quite wasteful and pointless, as the only important bits are the lines that form the outline of the world itself, and the corresponding bounding circles/bounding boxes were much larger than they needed to be. Since the world is carved from an overall vector brush, though, this outline is directly available, and thus I've refactored the code to produce a collision tree from a set of lines rather than triangles, leading to an overall improvement in efficiency and niceness. This is one of those things that won't have any directly visible effect, but makes further development easier.
Monday, 2 May 2011
The ship editor in action:
This video demonstrates the initial drag/drop ship editor interface in action. It shows that each ship component has a number of slots that can be used to attach either other structural components or weapons.
This video starts after the two wing elements and one of the engines have already been added (due to FRAPS time restrictions) - you then see the addition of a couple of power generators, which provide increased power recharge rate and power maximum (which is consumed by firing weapons), a missile launcher and a couple of standard energy cannons.
The angle of any of these components may be changed by dragging with the right mouse button, so you can create rear-facing/side facing weaponry as desired. As development progresses, there will also be computer-controlled turrets that will auto-target enemies.
This video starts after the two wing elements and one of the engines have already been added (due to FRAPS time restrictions) - you then see the addition of a couple of power generators, which provide increased power recharge rate and power maximum (which is consumed by firing weapons), a missile launcher and a couple of standard energy cannons.
The angle of any of these components may be changed by dragging with the right mouse button, so you can create rear-facing/side facing weaponry as desired. As development progresses, there will also be computer-controlled turrets that will auto-target enemies.
Juggernaut Ship Editor Demo Video from Darren Myatt on Vimeo.
Sunday, 1 May 2011
Time for reflection...
OK, while I'm putting off a bit of particularly annoying refactoring, I thought it may be a good time to post a quick reflection on how far Juggernaut (and I) have come so far.
I quit my previous job (as a technical consultant at a defence subcontractor) on the very first day back this year, because I simply couldn't do it any more. Monetarily it was a pretty good job, which is how I can now afford to do this, but I got no satisfaction from it and the pressure nearly drove me crazy.
I'd been working on the code that became the Juggernaut engine for about a year in my spare time (including long periods of nothing) before then: it initially started out as the engine for a 3D game named Super Robot Harpsichord which, who knows, may one day still get made. However, it quickly became clear that attempting to create a full 3D game on my own was completely infeasible in terms of art assets, at which point I came up with the basic idea for Juggernaut, although it has evolved a lot since the initial conception.
MrMacguffin), but I am trying to keep to deadlines, and progress has been rapid.
My original plan was to make a first demo in May, and I think I'm still reasonably on target for that, although it's now going to be the end of May. It's certainly going to be an alpha release rather than a beta, but hopefully it should demonstrate enough of the concepts of the full game to get people interested.
I quit my previous job (as a technical consultant at a defence subcontractor) on the very first day back this year, because I simply couldn't do it any more. Monetarily it was a pretty good job, which is how I can now afford to do this, but I got no satisfaction from it and the pressure nearly drove me crazy.
I'd been working on the code that became the Juggernaut engine for about a year in my spare time (including long periods of nothing) before then: it initially started out as the engine for a 3D game named Super Robot Harpsichord which, who knows, may one day still get made. However, it quickly became clear that attempting to create a full 3D game on my own was completely infeasible in terms of art assets, at which point I came up with the basic idea for Juggernaut, although it has evolved a lot since the initial conception.
MrMacguffin), but I am trying to keep to deadlines, and progress has been rapid.
My original plan was to make a first demo in May, and I think I'm still reasonably on target for that, although it's now going to be the end of May. It's certainly going to be an alpha release rather than a beta, but hopefully it should demonstrate enough of the concepts of the full game to get people interested.
The first high quality Alpha video!
Yes, it's finally here, I've managed to make a video that doesn't look like arse! Alas, the free version of FRAPS only allows clips of 30 seconds, and this video doesn't necessarily show off anything to the best effect, and the sound is knackered, but it's at least a start. Now that I'm confident it produces good results, I'll upgrade so that I can record full videos.
The video demonstrates the laser weapons and the force-applying missiles with space-warping effect. There's also going to be a graphical explosion effect for the missiles, but that hasn't been implemented yet.
Also, note that the Scourge aren't bothering to attack the player in this video as the AI is just set to do a patrol loop. In the actual game they'll turn and start following/attacking the player once spotted.
Juggernaut Alpha Demo 1 from Darren Myatt on Vimeo.
The video demonstrates the laser weapons and the force-applying missiles with space-warping effect. There's also going to be a graphical explosion effect for the missiles, but that hasn't been implemented yet.
Also, note that the Scourge aren't bothering to attack the player in this video as the AI is just set to do a patrol loop. In the actual game they'll turn and start following/attacking the player once spotted.
Juggernaut Alpha Demo 1 from Darren Myatt on Vimeo.
FRAPS vs CamStudio - Fight!
Up until now I've been using CamStudio in order to produce videos, as I'd used it before on my Neuromantic post-doctoral project to produce tutorial videos. However, as you've seen, the results thus far have not been so great.
Luckily, my friend Mark reminded me of the existence of FRAPS recently, and having downloaded it and done a quick test I can confirm that FRAPS is much, *much* better, and can easily handle 30FPS capture without slowing the game down.
So, you can all expect some much higher quality Alpha videos soon! Huzzah!
Luckily, my friend Mark reminded me of the existence of FRAPS recently, and having downloaded it and done a quick test I can confirm that FRAPS is much, *much* better, and can easily handle 30FPS capture without slowing the game down.
So, you can all expect some much higher quality Alpha videos soon! Huzzah!
Saturday, 30 April 2011
Juggernaut Development Update.
My new keyboard arrived today that should help streamline the development of Juggernaut:
It'll be so much easier having the 1 key to the right of the 0, unlike standard keyboards. Also, the air-cooling will definitely reduce the level of key-melting that I usually experience.
It'll be so much easier having the 1 key to the right of the 0, unlike standard keyboards. Also, the air-cooling will definitely reduce the level of key-melting that I usually experience.
Post-Easter update
Since the 15th I have been exploring the vast and desolate wastelands of the North of England (while visiting my family over Easter), and only returned to Guildford a couple of days ago. Now, after going to the Reading Beer Festival yesterday I'm ready to start work properly again.
This is not to say that I haven't been working over the couple of weeks: things have actually come quite far. Before now, the main thing missing from the Juggernaut engine is any proper collision physics: rather than the player's ship bouncing off walls and taking damage (as you'd expect), damage was just applied while the ship was colliding with the main environment. This was just a temporary, but obviously incomplete, solution.
However, the advantage of being back in the North was that I only had my laptop with me, which lacks DirectX 10 hardware, and as a result there was no way that I could work on the main game engine. This forced me to do the necessary research in order to be able to implement a decent rigid body physics engine, which means that not only will the ship react well when colliding with walls, but it leaves a lot of room for interesting physics-based challenges, including pulling things around using a tractor beam. I'm currently just doing the refactoring necessary to integrate the physics engine with the main game engine, but in a few days I'm confident that this last major aspect of the game will be working well.
After that, it will be full steam ahead towards the creation of the first demo!
This is not to say that I haven't been working over the couple of weeks: things have actually come quite far. Before now, the main thing missing from the Juggernaut engine is any proper collision physics: rather than the player's ship bouncing off walls and taking damage (as you'd expect), damage was just applied while the ship was colliding with the main environment. This was just a temporary, but obviously incomplete, solution.
However, the advantage of being back in the North was that I only had my laptop with me, which lacks DirectX 10 hardware, and as a result there was no way that I could work on the main game engine. This forced me to do the necessary research in order to be able to implement a decent rigid body physics engine, which means that not only will the ship react well when colliding with walls, but it leaves a lot of room for interesting physics-based challenges, including pulling things around using a tractor beam. I'm currently just doing the refactoring necessary to integrate the physics engine with the main game engine, but in a few days I'm confident that this last major aspect of the game will be working well.
After that, it will be full steam ahead towards the creation of the first demo!
Friday, 8 April 2011
Missiles!
Since I last posted I've mainly been doing some improvements to the comic overlays and some general refactoring/improvements, as well as some changes to the game control interface (I may blog about the latter soon). Yesterday and today, though, I decided to add guided missiles to the array of weapons in Juggernaut.
The standard projectiles types have a very simple dynamics model, and simply move in a straight line until they collide with the main collision stencil (or their lifetime expires). This type of collision detection is performed on the GPU, and therefore is highly efficient, which is why it is a good choice when there may be thousands of collisions to determine. The downside to using GPU-based collision detection is the necessity of a GPU-stall before you can actual get the information back to the CPU. The stall is necessary as the GPU needs to finish its current queue of commands up to and including the collision detection operations before the results you want are available. At the moment on my GTX260 this stall is only at around 3ms, when 16ms is generally available per frame (assuming 60Hz), so this is not much of a problem. To avoid just losing this time, the GPU-based collision detection operations are queued, then the main CPU-based updates are performed before the stall is forced.
Anyway, the missiles are effectively treated as standard projectiles, but with more complex dynamics that allow them to select a target and then accelerate towards it. They will also spawn different (and larger) explosion types to the majority of projectiles and cause splash damage to other enemies. The larger explosions aren't properly implemented at the moment, though: that's today's task!
Here's a screenshot of the initial missile implementation, along with a nice blue vapour trail to add some visual variety.
The standard projectiles types have a very simple dynamics model, and simply move in a straight line until they collide with the main collision stencil (or their lifetime expires). This type of collision detection is performed on the GPU, and therefore is highly efficient, which is why it is a good choice when there may be thousands of collisions to determine. The downside to using GPU-based collision detection is the necessity of a GPU-stall before you can actual get the information back to the CPU. The stall is necessary as the GPU needs to finish its current queue of commands up to and including the collision detection operations before the results you want are available. At the moment on my GTX260 this stall is only at around 3ms, when 16ms is generally available per frame (assuming 60Hz), so this is not much of a problem. To avoid just losing this time, the GPU-based collision detection operations are queued, then the main CPU-based updates are performed before the stall is forced.
Anyway, the missiles are effectively treated as standard projectiles, but with more complex dynamics that allow them to select a target and then accelerate towards it. They will also spawn different (and larger) explosion types to the majority of projectiles and cause splash damage to other enemies. The larger explosions aren't properly implemented at the moment, though: that's today's task!
Here's a screenshot of the initial missile implementation, along with a nice blue vapour trail to add some visual variety.
Friday, 1 April 2011
Introducing ARIADNE
One of the problems with having an external 2D view of the player's ship is that, while the action may be fun, it's not very conducive to storytelling, as the ship does not portray any sort of character. As I wanted Juggernaut to be quite a story-based game, I needed some way of telling the story without a) requiring FMV or b) full voiceovers because c) my budget is tighter than a gnat's anus.
Of course, this only really leaves some kind of text-based approach, but I really didn't want to assail players with walls of dry text. Instead, I decided on a comic-based approach, where the story is conveyed by the main characters talking to each other. Each character is vector-based, and may be posed in a variety of ways to portray emotion, with comic speech bubbles (and the emphasis therein) used to get across additional character.
The two primary characters are the protagonist Captain P. Tenuous (cookie to anyone who manages to work out *that* reference), a space trader undergoing a midlife crisis, and his belligerent navigational computer ARIADNE, who assumes the role of the deuteragonist. Most of the dialogue within the game will be plot points and general banter between these two characters, and also serve to break up the action. There is also a human antagonist who will be involved in dialogue less frequently.
Anyway, as a first character to implement in this system ARIADNE is the ideal choice, because its basic facial structure is so simple that it may be hardcoded. In the game world, ARIADNE's model comes with a wide variety of different and engaging personalities, but since Tenuous was too cheap to upgrade he gets an annoying cynic with a face made of 16 triangles.
Each character is defined as a mesh with a neutral pose and a number of different sub-expressions that define delta vectors for a subset of the mesh vertices. For example, ARIADNE has sub-expressions to raise its eyebrows, as well as close its mouth vertically/horizontally and move its eyes etc. Larger expressions (such as happy/angry etc.) can then be generated as a linear blend of these sub-expressions.
On the current test implementation of ARIADNE, the results look like this:
Of course, this only really leaves some kind of text-based approach, but I really didn't want to assail players with walls of dry text. Instead, I decided on a comic-based approach, where the story is conveyed by the main characters talking to each other. Each character is vector-based, and may be posed in a variety of ways to portray emotion, with comic speech bubbles (and the emphasis therein) used to get across additional character.
The two primary characters are the protagonist Captain P. Tenuous (cookie to anyone who manages to work out *that* reference), a space trader undergoing a midlife crisis, and his belligerent navigational computer ARIADNE, who assumes the role of the deuteragonist. Most of the dialogue within the game will be plot points and general banter between these two characters, and also serve to break up the action. There is also a human antagonist who will be involved in dialogue less frequently.
Anyway, as a first character to implement in this system ARIADNE is the ideal choice, because its basic facial structure is so simple that it may be hardcoded. In the game world, ARIADNE's model comes with a wide variety of different and engaging personalities, but since Tenuous was too cheap to upgrade he gets an annoying cynic with a face made of 16 triangles.
Each character is defined as a mesh with a neutral pose and a number of different sub-expressions that define delta vectors for a subset of the mesh vertices. For example, ARIADNE has sub-expressions to raise its eyebrows, as well as close its mouth vertically/horizontally and move its eyes etc. Larger expressions (such as happy/angry etc.) can then be generated as a linear blend of these sub-expressions.
On the current test implementation of ARIADNE, the results look like this:
When Macros Invade Your Home
It's not very often I'd be inclined to post code bugs that I come across during development, but this one foxed me for sufficient time and the answer was face-palming enough that I thought I'd post it.
This is a little excerpt from some of the GUI handling code. When you click on a control, it iterates through any sub-controls in a recursive fashion and calls the same function on those:
Worked it out yet? If so, congratulate yourself on being a smug bastard.
The problem is that the max() function in C++ is defined as a macro, rather than a function, and this macro is (((a) > (b)) ? (a) : (b)). As a result,the mouseDown() method could get called twice per loop iteration, and as my button control was 3 levels down the GUI hierarchy, this meant 2^3 = 8 clicks rather than 1.
Bollocks.
Right, now back to programming rather than scratching my head!
This is a little excerpt from some of the GUI handling code. When you click on a control, it iterates through any sub-controls in a recursive fashion and calls the same function on those:
virtual int mouseDown(const Tuple2f& Position, const IBaseMouseEvents::mouseStateChange& State ) overrideThis seems pretty straightforward, but when I'd added a Next button to the GUI it was oddly getting clicked 8 times every time I pressed it, and I just couldn't work out what was happening for about 20 minutes.
{
int Result = -2;
//Check for intersecting with this control's layout
if ( Overlaps(Position) )
{
//
Result = -1;
//Call mouse down on subobjects
for( uint32 i=0; i<Objects(); i++)
{
//Update the final result
Result = max(Result, Object(i)->mouseDown( Position, State ) );
}
}
return Result;
}
Worked it out yet? If so, congratulate yourself on being a smug bastard.
The problem is that the max() function in C++ is defined as a macro, rather than a function, and this macro is (((a) > (b)) ? (a) : (b)). As a result,the mouseDown() method could get called twice per loop iteration, and as my button control was 3 levels down the GUI hierarchy, this meant 2^3 = 8 clicks rather than 1.
Bollocks.
Right, now back to programming rather than scratching my head!
Tuesday, 29 March 2011
Font woes
OK, the title is not quite accurate. What I'm currently having trouble with is finding a reasonably cost-efficient way of embedding a font into my game. I've found a font, and it is lovely and perfect but, unfortunately, it will cost a total of $300 to purchase a license such that I can legally embed it within my game. It's slightly irksome that this cost is basically 10x the fee for using the same font in unlimited commercial print media.
Arse.
Arse.
Sunday, 27 March 2011
More ship upgrades!
OK, I've gotten quite a bit further with the ship editor now, and have gone as far as implementing a couple of new ship components in order to increase the variety of test configurations available. One of the important things that's changed is the addition of a proper engine type. Up until now, the main weapon component also served as a thruster for simplicity's sake. There's also a new structural wing-type element (which looks much better than the old strut type), and I've redrawn the generator type to fit into the new graphic scheme more effectively.
The screenshots only show two weapons: the standard cannon and basic laser type. One of the things I need to do in the near future is create a proper ship weapon that implements the lightning weapon in a specified arc (rather than hitting absolutely everything as the test implementation did).
The screenshots only show two weapons: the standard cannon and basic laser type. One of the things I need to do in the near future is create a proper ship weapon that implements the lightning weapon in a specified arc (rather than hitting absolutely everything as the test implementation did).
![]() |
That laser effect still needs some sexing up. It's on my todo list. |
![]() |
After a bit of improvement of the spawning framework I have once again gotten the laser weapon to leave a set of custom explosions at the point where it intersects the environment. |
Thursday, 24 March 2011
Example Ship Configurations
Now that the ship editor is actually functional, I can post a couple of screenshots of example ship configurations. They're not particularly varied, as I've only bothered to make a minimal set of ship components at the moment, but it should be informative, at least.
The two weapons shown here are the basic energy cannon (which was the first weapon implemented) and the laser cannon (a straight line instant hit weapon). As work progresses, a lot of other weapons will be implemented, and upgrades will be generated for existing ones.
![]() |
This first configuration places two laser cannons on the back of the ship, thus providing some all round firepower. |
Wednesday, 23 March 2011
Video Test
This is a test video I made a while ago using CamStudio, but hadn't gotten around to uploading until now: the FPS isn't amazing, as my development machine does *not* like running the game at full FPS while simultaneously encoding, but it should give a first indication as to what the basic gameplay will be like. It only shows a couple of weapon types (standard projectile + lightning blast), but it does feature the newer particle effects, although it predates the recent improvements in environment decoration.
[OK, what the Blogger upload did there was take my already highly compressed video and then proceed to squash the Bejeesus out of it. Hopefully it still gives a bit of an idea, though].
When creating the main demo video in the next few months (as part of my Indie Fund application), I'm going to have to find some way of recording at full fps, which may involve adding the ability to specifically seed the random number generators and record player input, then play it back frame-by-frame so that processor power isn't an issue. Which will be a bit of an arse, but as the most important (and pretty much only) part to the Indie Fund application process, it's definitely worth the time.
Feeling all GUI.
So far this week I've been continuing work on the main GUI system, and have certainly now churned out enough code for a fair number of simpler games than Juggernaut. For example, if I ever need to do some kind of drag-and-drop 2D puzzle game I'm now pretty much set!
Although the GUI system is completely custom, I've based the layout fundamentals on Windows Presentation Foundation in terms of split panels/stack panels because, although I grew to hate WPF with a manic passion, the layout system was pretty good. It would have been easier just to hard code all the panel positions for the ship editor, but bothering to do a passable layout system will make subsequent GUIs (such as the main menu) much simpler.
Just for you, even though it's still early days, I thought I'd post a screenshot of the early version of the ship editor, since it's been a while and I know how much people prefer a picture:
Current Juggernaut code base size: 1.25 Megabytes. Great Expectations by Charles Dickens weighs in at about 1 Megabyte.
Although the GUI system is completely custom, I've based the layout fundamentals on Windows Presentation Foundation in terms of split panels/stack panels because, although I grew to hate WPF with a manic passion, the layout system was pretty good. It would have been easier just to hard code all the panel positions for the ship editor, but bothering to do a passable layout system will make subsequent GUIs (such as the main menu) much simpler.
Just for you, even though it's still early days, I thought I'd post a screenshot of the early version of the ship editor, since it's been a while and I know how much people prefer a picture:
Current Juggernaut code base size: 1.25 Megabytes. Great Expectations by Charles Dickens weighs in at about 1 Megabyte.
Subscribe to:
Posts (Atom)