Game Design, Programming and running a one-man games business…

Dealing with mice

Take a trip far back in time when dinosaurs ruled the earth and Directx 5 was the very latest cutting edge thing. Back then, the hip cool and trendy thing to do with mouse input was to use direct input. I have a pile of programming books on how to do it, and you can enjoy the handy tutorials on capturing mouse input using directinput in the directx9 (and later) SDKs.

But…

It turns out that this is not the way to do it. In fact, there are even articles online now where Microsoft quietly admits that if all you want to do is normal mouse input, you should avoid directinput altogether. To make things worse, there are a ton of features to do with mouse acceleration, button swapping, double click speeds blah blah, that are all missing and need to be implemented from scratch (as I was doing….mostly)  if you use directinput for the mouse. How come I missed the memo on this?

Like a trusty old coder, I’ve been re-using my engine for a while, and although I have a nice shiny new graphics engine I was still using directinput for the mouse, which explains the somewhat erratic and crap mouse support in GSB. But that changed today, when I finally got sick of it, and ripped it out. The next patch will switch GSB to the standard windows cursor, even in fullscreen, and it will all work much better.

One day I’ll find time to sort out the keyboard too…

A not so trivial change

When you think about adding a feature to an existing game, it often sounds much simpler than it will be. Here is an example from today.
After a lot of consideration, I decided to add new ‘carrier support’ modules to cruisers. These would act as mobile repair yards for fighters. If you gave fighetrs the ‘cautious’ order, when suitably damaged, they will seek out the closest cruiser with a carrier module, head there, dock, get repaired, and return to battle.

Now there is a lot of code associated with the AI for doing that, and the UI for displaying it etc, but that’s all the code you factor-in and expect to write, so that isn’t the problem. The extra work, comes from all the stuff you hadn’t considered.

I needed code to prevent docked ships shooting, being tractored, being affected by shock waves, or targeted by enemy ships. That’s all pretty reasonable. Then I needed code so that on docking, the fighters would choose the most sensible module for multi-bay carriers where one was damaged, or had a big queue of fighters, plus handle exploding carriers and damaged carrier modules.

But then I started looking at the visuals. The fighters were just flying on top of the cruisers, then vanishing whilst docked. Clearly this sucked, and it would look cooler if the fighters flew ‘under’ the cruisers and re-appeared there. This would look like they docked in hangers under the ship.

BUT! in GSB ALL the fighters fly over the top of cruisers. It’s a rendering optimisation, which nobody notices. So I had to code a newer system where fighters *could* fly under as well as over the cruisers. This just means putting them into two groups randomly, looks cool, and is still pretty fast. And this is where it gets interesting.

With this cunning new system, as a fighter approaches a cruiser I can just ‘force’ it to toggle to an ‘underneath’ group, and thus it will look cool. However, it may not already be an underneath one, and it *may* be on top of a cruiser at the point at which I realise I need to do that. So there is a danger it may suddenly ‘ping’ underneath a ship horribly as I’m watching.

I can set a flag that means the change is pending, and only do it when its offscreen, but that might not always be possible. At some point I need to either just risk it, or do a lot of intersection tests to ensure its ‘safe’ to jump underneath. Ideally I flag this as something to do in a frame where there is some CPU headroom (existing code in the game checks this, and does other similar tasks in those gaps)

And there is one final hiccup. Over time, as every fighter gets repaired, they will eventually all end up ‘underneath’ cruisers. Which will not look right. I need to tag fighters as ‘needing to toggle above’ when they are next offscreen, just like I did the other way around.

This is all the code people forget about, and is why game programmers suck so badly at putting together schedules :D

Fixing a few obscure, but nasty bugs

I’ve found a few big bugs that people don’t seem to have spotted, or at least, not in the numbers you would assume would have spotted them.
First is a bug relating to how bonuses are applied to modules. In code terms it was a fairly standard ‘doh’ mistake where you override virtual functions but forget to call the base function in the derived one. (obviously sometimes that’s legit, but here it was a mistake).
The upshot of this is that for some modules which had certain bonuses, such as shield modules, the base hull bonus got skipped. It was calculated ok on the design screen, but not in the battle. As a result, there are a lot of ships that are partially missing their hull bonuses, until now…

The second bug is less of a bug and more of an unintended consequence. Because of the way target priorities were calculated, they were biased in favour of targets that were just outside minimum range. because optimum range is nearer to maximum than minimum for most weapons, this meant a few sub-optimum targeting decisions were being made.

The good news is I’ve rewritten that entire section of code that makes target selection decisions. The bad news is I need to do some serious testing to ensure this is an improvement, and doesn’t break everything. I suspect that for the first time, I may need a few volunteers from the beta players to install a ‘trial 1.16 beta patch to see if it’s safe to roll out to everyone else. If I do that on Monday, I can aim to release the full 1.16 update a few days later, and then we are getting very close to starting work on a demo and an actual releasable final game.
Yay!

Repair Drones

It’s amazing how much extra effort had to go into this over the last 48 hours…

Repair drones have always looked a bit cool, but not been much help to the player. The problem is, their only tie to the core simulation was their quantity. Every repair module gave you a ‘swarm’ of repair drones, and once your ship took some damage, you would see them hovering around and looking like they were welding the ship back together. The problem was, they didn’t actually achieve anything froma  visual point of view.

Thios was worse than a visual bug, because it means that when you play against an enemy fleet that has lots of ships which make strong use of repair drones, you cannot tell if that enemy cruiser is on it’s last legs, or just cosmetically burned, yet at 100% hull integrity. Surely this had to be fixxored.

So now (behold the youtube vid below), those drones (as well as having nicer welding effects) do actually weld those damaged bits of your ship back together. To make it REALLY obvious in the vid, I built a ship with three repair modules, so until the repair supplies run out, it’s pretty nippy at welding stuff back together.

Let me know what you think. I reckon it not only looks better, but will make playing against repair-spammed ships much easier and more enjoyable. (in terms of learning from the battles. The simulation is unchanged)

Fixing the AI orders (again)

Some cunning GSB players noticed that the orders were not working correctly in terms of attacking certain classes of ship. If you deleted the ‘attack fighters’ order, the desired behaviour was that the ship ignored fighters until there were only fighters left.

This bit of code was broken and basically needed re-doing. Now you might think it’s an easy algorithm that goes like this:

Go through each intact enemy ship
Pick the optimum one out of the classes we should shoot at
If you still have no target...
Go through each intact enemy ship
Pick the optimum one ignoring class.

Leaving aside the inefficiency of parsing the 300 enemy ships twice each time, this isn’t as simple as it looks, because a lot of the time a ship will fail to find a target within range. Thats because all of the ships its ordered to fight are across the map. Ideally the ship trundles over and shoots them. So the criteria for actually picking a target differs from the criteria for establishing whether or not there are any valid targets. Plus, the idea that once all the frigates and cruisers are dead, that EVERY TIME I look for a target I have to do a dummy run through with invalid orders is just untidy and slooow slooow…

So I ended up coding a convoluted complex system which (as convoluted complex systems often are) is way faster than that. Basically Fleets keep track of if they have any ships of each class. Whenever new ships show up (survival mode) or a ship dies, the fleet recalculates that data. if the data has changed, it tells each intact ship in the fleet. Those ships then compare this against their orders, and deduce whether or not the orders still stand. If they don’t, they tell all their turret AI’s to ignore class-based orders from now on. This involves practically no overhead during a  typical target-acquisition call (which are very frequent)

That took a lot longer to code, debug and test than it did to type here :D

In other news, I fixed some dodgy server-side code that prevented challenges being deleted. I’m amazed more people did not whine at me that the ‘delete’ button on a challenge basically did sod all. It now works :D