Sorry about the delay between posts, guys, but I did manage to get out a release last weekend. Here are the highlights:
Redesigned menu system
Although many of the menus should look familiar if you played 0.2, I completely reworked the underpinnings of the GUI as I had mentioned in the last dev update. I’ve finished coding the basic implementations for these, though I did leave handles for some more advanced features (read: drag and drop) which will make implementing drag-n-drop ship upgrades and a mission editor easier.
You can now visit the profiles menu and change your callsign and ship and see your stats such as accuracy, kill-death ratio, etc. This will become more important as I add features like ship upgrades and such.
Player Flyable Ships
There are 3 player-flyable ships included in 0.3. You can access these through the Profiles menus. Enjoy
The game now keeps track of your bullets fired and hit (and thus accuracy), kills, deaths, damage taken, and damage dealt. During the mission, you can keep track of your mission totals in the bottom right corner, and your overall totals are in your profile.
So that’s 0.3 in a nutshell. You’ll notice that missing from this list is any mention of new missions. Well, don’t worry, one of my friends has agreed to help with creating new missions that I will add as sub-releases of 0.3 asap, so expect a mission pack to come out as 0.3.1 soonish.
I also made two major changes to the game logic: recursive dimensional clustering and time-dependent physics. Both of these changes were basically optimizations to help the game run more smoothly and consistently among machines of differing power (ie, a netbook on an Atom processor vs a gaming pc with the latest quad-core processor).
Recursive Dimensional Clustering
Here is a basic description and comparison of RDC vs brute-force collision detection. The basic idea is that a brute-force approach to collision detection has O(n) ~= (n**2 – n) / 2. As you might imagine, this causes some problems when lots of bullets are flying around especially on lower end machines. So, I looked for a solution to get this down to a more manageable range…I think RDC is O(n) ~= n*log2(n).
Here’s the basic premise:
1. Divide the sprites into ‘clusters’ along a single axis such that each cluster contains overlapping sprites. So if A overlaps B but not C, and B overlaps A and C, then A, B, and C will cluster together, but sprites D and E, which overlap each other but not A, B, or C, will be in their own group.
2. For each of these groups, run the same clustering analysis on the other axis.
3. Continue recursively clustering, alternating between axes, until the “minimum group size” is reached for each group or the group can no longer be subdivided.
4. Now brute force collision detection can be performed within each group.
I think my implementation could be better in that I think my sorting algorithm might not be fully optimal, but I’ll continue working on it.
So before 0.3, the game ran at about 30fps. This is fine normally, but once bullets start flying, each frame might start taking longer than 33ms temporarily. For a single player game, it is probably OK to just go ahead and continue using fixed-step physics because it’s not like you need the game to run exactly the same on different machines. However, I would eventually like to have a networked co-op mode.
So I adjusted the physics stuff such that the game draws at one framerate (now 60fps) and updates physics assuming a separate framerate (20fps) is equivalent to one “step”. Now, that said, the game then measures the time in ms between physics updates and passes the fraction of a “step” (ie the number of ms since last update / number of ms per step) on to the physics engine, which then multiplies all rates by that fraction (usually 0.3). The nice thing about this is that when the game slows down due to excess bullets or whatever, the fraction of a step each frame will compensate for this and allow the game to still play at the same speed in real time, though a bit choppier.
I’ll save what I have planned for 0.4 for the next post, since I’ll need something to talk about next week.