Posts Tagged programming

Out Of Memory Exceptions

I learned something today: Out of Memory errors are not actually caused by being out of memory! What a silly I am for expecting error messages to make sense.

So, for everyone preparing to set your RAM on fire, stomp on it and throw it out the window before burying it in a deep dark hole and pouring concrete on top: don’t bother! You RAM is fine. Assuming you haven’t already set it on fire. If you have, your RAM is not fine. And you might want to put that out.

No if you’re out of RAM you’ll get performance issues caused by ‘thrashing’ (when a computer starts relying on the Hard Drive instead of RAM), but you won’t get Out Of Memory exceptions. So, what causes OoM exceptions?

32-bit Windows causes OoM exceptions.

Screw 32-bit Windows.

See, when Microsoft says “you are out of memory”, they actually mean “you are out of consecutive address space”.

You now have several options (it’s like a game!):
– For a “proper” explanation, go read the article I read that taught me all this: http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx
– For an “improper” explanation, go ahead and use your imagination (I’m sure it’s way more kinky than anything I can come up with).
– For an “incredibly-simplified and probably-wrong” explanation, continue reading…

When an object like a Creature or a Tree is assigned, it gets put in memory and Windows assigns it an address. And by ‘put in memory’, I don’t mean RAM. Forget RAM. RAM is a glorified performance optimisation. The memory we’re talking about here is your hard drive. And as you’re probably aware, your hard drive is huge. You’re not in any danger of running out of that unless you’ve packed the drive to it’s very limit.

Okay, so you’re not in danger of running out of Hard Drive space, and lack of RAM doesn’t cause exceptions, just performance issues. So the next place to look is at that address the object was assigned by Windows when it was put in memory.

This address is where windows get’s it’s 32/64 bit designation. The absurd oversimplification I’m about to make will likely make any computer-science types reading this swallow their hats, but it’s basically a number stating that object X can be found Y bits into the memory stream.

Always be prepared!

The cause of Out Of Memory exceptions is that “Y-bits into the memory stream”. See, even though the process has the entire hard drive to work with, a 32-bit address format can only store addresses up to ~4GB (and half of that is reserved by the operating system for other things). This is why 32-bit editions of Windows can’t make use of more than 2GB ram: the 32-bit format doesn’t have enough address space to map more than 2GB.

Okay, but surely that’s basically the same as a 2GB memory limit for the purposes of Out Of Memory exceptions?

Nope. See, to assign and map a new object, there needs to be an empty “hole” in address space for it to go into. If there isn’t a hole large enough, an Out Of Memory exception will be thrown. (finally!)

I’ll explain via metaphor. Imagine putting three baskets into your car, then filling in the area in between them with smaller items. Then you realise that you need a large esky instead, so you take out the baskets and try to put the esky in. Even though the three baskets combined took up more space than the esky, and even though they’ve been removed, the esky still won’t fit because the smaller infill items are blocking it.

That’s the problem with address space: if you fragment it with smaller items in between the big ones, the next time you need to allocate something big it’ll throw an Out Of Memory exception, even if you freed up the big ones and have plenty of cumulative space to use. *That* is what is causing the memory issues in Species.

I’m sure a decent Computer Science course would have covered all this but I’m self taught, so I get to learn by the slightly more direct route of sticking my hand in the fire and finding out what happens.

OH GOD IT BURNS! WHY WOULD YOU LET ME DO THAT?

So, on to the usual question: how do we fix this?

Well, the obvious solution is “compile to 64-bit.” A 64-bit address space can map about 4 billion times as much memory (no, literally), so chances are we wouldn’t be seeing fragmentation errors any time soon. Of course, it also means people using 32-bit windows wouldn’t be able to play the game.

I’d rather solve the error at the source and retain backwards compatibility, but “solve” is a relative term. Memory fragmentation on a 32 bit machine isn’t something that can be stopped. But it can be significantly reduced, and I’d prefer to do that for the sake of memory management *before* dropping the metaphorical world-killer asteroid that is a 64-bit compilation.

The “World Killing Asteroid” compile-time option is only included in the December 21 service-release of Visual Studio 2012.

So, on to the source. What, ultimately, causes memory errors in Species?

I’d done memory profiling in the past, but I hadn’t properly understood what it was telling me until now. They indicated I had two main memory draws: grass vertices, and tree instances. But these two memory hogs always appeared in different graphs: tree instances would appear in allocation, grass vertices in snapshots.

With what I know now, this makes sense. Grass vertices are created when the terrain is built, and held from then on out. This means that the grasses memory cost at any moment in time is huge: after all, it’s storing the position of every potential billboard vertex on the map. Imagine the map completely covered in the dense savanna grass: that’s what the grass memory cost is.

But relative to the hard drive, or even the RAM, it’s not that big: I think somewhere around the 200MB mark? Can’t remember exactly, but regardless, it’s also generally a static cost. The grass grabs up all that memory when the terrain is built and doesn’t release it until the terrain is destroyed. You might be able to force an OoM exception by repeatedly loading/generating worlds, and fragmenting the memory that way. Fixing it isn’t urgent, but probably worth doing: need to ensure the memory is allocated at startup, rather than on terrain-build.

The second cost is the Tree Instances array. This one confused me because it was barely noticable on the moment-to-moment memory, but was invariably a massive cost in terms of amount allocated. This was because the Tree Instances array was designed to grow organically with the vegetation: if the number of trees grew too large for the array, it would allocate a new array with an extra 500 slots for trees and copy the data to that (well okay it actually uses Array.Resize(), but that’s what Array.Resize() does internally).

Of course, frequently allocating a massive new tree array is a great method for fragmenting your address space, which is why large (>2) worlds were invariably hitting an OoM exception during the vegetation generation at startup. Since I didn’t realise this was a problem, the amount allocated in the memory profiler didn’t mean anything to me.

I’ve already applied a few simple optimisations to this method, which makes generating size-3 worlds possible again, but fixing it will be another matter entirely. Ultimately, the vegetation should probably be capped to a set level, but this is tricky because the array is fed directly into the graphics card when drawing the trees. This means that those 500 “excess” trees still incur a GPU cost, even though they’re invisible. In a size 3 world, this cost is enough to cap FPS to 12, even when there are no creatures.

To fix this one I’m going to need to adapt the InstancedModel DrawInstances() method to take the total number of trees as a parameter, and feed that to an overload of the DynamicVertexBuffer. This should allow me to submit the entire oversized array, but then lower the number of instances that are actually drawn each frame.

(Edit) Well that was surprisingly easy. A heap of address space is now set aside for trees, but only the actual trees themselves are sent to the graphics card. Assuming XNA isn’t doing something horrible with them beneath the hood, that should take care of most of the OoM exceptions in the game. Stability improvements ahoy!

Cheers,
Qu

, , , , , , , , ,

2 Comments

Proramming Stuff: Genome

It occurs to me I never really explained the horrible occult things I was doing to the poor innocent Genome class for 0.7.0, so why not? Hopefully the Guild of Evil Programmers won’t react too badly to me sharing their evil programming trade secrets. Of evil.

In 0.6.0, the Genome class was fairly simple: a list of floating point numbers and not much else. These floating point numbers were the ones you see in the .txt file when you export a creature: they represent every hereditable trait a creature has, plus a few “stop codons” (-1) which don’t really do anything at this stage. There’s 61 in total, plus 5 for every facial feature.

The thing is, though, the creature’s don’t use this list. They have their own values for Limb1Bicep and HeadType and Aggression, and they use those instead. The values in the genetic list are only really used for things like speciation and exporting and colour coding, where I need to be able to enumerate through the list. For everything else, theres mastercard local variables.

This is, to be blunt, a STUPID DUMBASS PINEAPPLE way of doing things. I need to actively keep the list and the local variables synchronised at all times. Forget to update a variable, and my computer could spontaniously explode in a shower of napalm and internets.

So for Genome Step 1, I’ve fixed that. There are no longer any hereditable local variables anywhere: everything references back to the same GeneticValues list. To avoid making the code unreadable, values are accessed through appropriately named public accessors:

public float Limb_1_Bicep
{
get { return GeneticValues[42]; }
set { GeneticValues[42] = value; }
}

There are a lot of these accessors, but now that they’re set up, I can use similar code to before, but only store and retrieve from one copy of each genetic value per creature. And the copy-genome-from-parent-to-child routine is literally a call to CopyTo().

It’s much cleaner than before.

Genome Step 2, which I’m currently working on, involves modularising this further. I’ve created a Gene base class, which contains hereditary data for a macrostructural feature like a limb. Well, okay that’s not quite accurate: it contains the indexers for the data, and a few basic items like number of values and start index. The aforementioned GeneticValues list contains the genetic data itself.

The goal of this system is to make the genome fully enumerable and extensible. Enumerability is great for outputting genetic values, along with data like their names, descriptions and formulae, to the UI. It also makes things like mutation easier to read: rather than 120-something lines of this sort of thing:

 ChestWidth += (float)(rand.NextDouble() - 0.5f) * 0.1f * mutationRate;
ChestWidth = MathHelper.Max(ChestWidth, 0.01f);
StomachWidth += (float)(rand.NextDouble() - 0.5f) * 0.1f * mutationRate;
StomachWidth = MathHelper.Max(StomachWidth, 0.01f);
HipWidth += (float)(rand.NextDouble() - 0.5f) * 0.1f * mutationRate;
HipWidth = MathHelper.Max(HipWidth, 0.01f);
ChestHeight += (float)(rand.NextDouble() - 0.5f) * 0.1f * mutationRate;
ChestHeight = MathHelper.Max(ChestHeight, 0.01f);
StomachHeight += (float)(rand.NextDouble() - 0.5f) * 0.1f * mutationRate;
StomachHeight = MathHelper.Max(StomachHeight, 0.01f);
HipHeight += (float)(rand.NextDouble() - 0.5f) * 0.1f * mutationRate;
HipHeight = MathHelper.Max(HipHeight, 0.01f);
//etc

(oh yeah, I renamed “shoulder” and “thigh” to “chest” and “hip” respectively. This is because… well, I’ll go into more detail below)

… rather than that, we end up with something more like this:

SkinGene.Mutate();
TorsoGene.Mutate();
foreach(Limb limb in limbGeneCollection)
    limb.Mutate();
//etc

or, if I take it another step further and add a virtual method to the Gene class, this:

foreach(Gene gene in GeneCollection)
    gene.Mutate()

So enumerability is a vera goot ting.

The other benefit will be extensibility. Previously (before step 1), if I wanted to add a new gene, I had to declare the local variable, ensure it was added to GeneticValues, ensure it was copied to the child/genetically-recombined/mutated in the various hereditability methods, and then implement how it was drawn and affected survival.

Step 1 removed the local variable and the need to manually copy data to the child, but it added a new problem: if I add it to the genome at any location other than the end, it will screw up every one of the accessors indexes after that and I’ll have to find and re-write all of them. Yeesh.

With step 2 in place, though, so long as each gene object has the right startIndex, the accessors can be built from there. Worst case scenario, that’s maybe 10 values to specify, rather than 60 something. But it’s better than that: since the startIndices aren’t hardcoded in the accessors, they can be built on the fly: with a small bit of extra code I should be able to literally just add gene objects willy-nilly and let the accessors sort themselves out!

It means a (hopefully tiny) performance hit in that the accessors are now adding two values together and pointing to the result, rather than going straight to a hardcoded location, but for the ability to add genes with a few lines, I’ll happily take that hit.

All of this will be immediately useful because, as mentioned above, for 0.7.0 we’re making a change to the way “Shoulders” and “Thighs” are represented. These elements will now be a part of the limbs genetic structure. You know those inevitable giant shoulderballs you sometimes see on creature’s with large but skinny legs? Those are what we’re calling shoulders now, and the extra gene for them will give them the extra versatility to be large or small. (As mentioned, the existing “shoulder” gene has been renamed to “chest”)

This change should give the creature’s slightly more variation in forms, as well as providing the potential for large, stick-legged creature’s to be even more insectoid and terrifying. Yay!

I’m actually quite happy with the way this is coming together. It feels like Species is finally moving from Rapid Prototype to fully armed and operational Game Engine.

Implementing future features should happen much faster than it would otherwise thanks to this update.

Cheers,
Qu

“We have 5 nuclear warheads, 2 laser bombs and some sort of giant squid robot inbound, and the Guild of Evil Programmers has unfriended us on Facebook. What did you do this time?”

, , , ,

2 Comments

Render Targets Are Evil

aka. Misadventures In Implementing a Real Time Tree of Life Graph. Note: this post is a logical sequel to the previous post, though it also doubles as a what-not-to-do tutorial of sorts when it comes to implementing real time graphs and render targets in XNA. Fair warning: It’ll probably be a bit incomprehensible if you’re not a programmer.

/tangential progress report: we’re about 40% of the way to the alpha release deadline and about 50% of the way through the “list of crap to do”. So we’re ahead of schedule, but not by much.

It’s probably worth noting that part of the reason I’m cutting it so fine is micro-feature-creep. A major advantage of programming on your own is the ability to indulge your inner ADHD-sufferer: getting distracted by something that sounds like fun and wandering off to code it. Some of my favorite features in Species have come about via ooh-shiney moments like this, but it slows down my progress on the stuff I’d planned out in advance.

Okay, back to the topic…

I not-so-briefly touched upon my very first tree of life graphing attempt in the previous post. This image…

… shows the end result.

Frankly, it’s ugly. It’s barely recognisable as what it’s supposed to represent, and it’s a performance hazard. Each one of those bars is a seperate sprite representing the life-time of a creature, which means I’m calling DrawSprite() a couple thousand times every frame. This would be manageable if I stopped drawing the simulation in the background (a tactic I’m may have to adopt when I get around to trying out the life-web I mentioned last post), but because I was rendering it as an overlay this wasn’t something I spent much time considering.

The idea behind this graph was that it would show the culmative effect of population changes by displaying all the creatures lives at an individual level. Admittedly, it manages this to some extent, but it does so extremely poorly. The rapid movement to the right, for example: that’s not natural selection, that’s just the logical result of measuring mutation from the starting location. If you start a value at 1, and your children are 0.9 and 1.1, it doesn’t matter that they are going in opposite directions: they will both appear at 0.1 on the graph.

But as far as first attempts go, it taught me quite a bit about what I was trying to achieve. That’s the whole point of prototyping: try something, learn, then try it again using the information you’ve learned. In this case what I learned was that showing individual creature lives was too microscopic to paint a good long term picture. I was going to have to summarize, and for that I’d need to use the species and speciation tranking system… which, despite post order, I hadn’t implemented at this stage. The above graph was generated entirely from random colour changes and the genetic distance algorithm.

So I went and I implemented species and speciation tracking while researching and considering my next move. Surprisingly, for such a simple concept, there are a whole variety of ways to implement a real-time graph. I’ll get to those in a moment, but first: what I decided I wanted to achieve was a population tracking graph that would show the relative size of each species and the effects of speciation, so you could see whether the splintering population was a single sterile creature, or a large segment. It would also need to be able to dynamically move and re-arrange population lines, to keep them from overlapping and under-representing the total population. This… turned out to be more ambitious than I expected.

I narrowed it down to a number of ways to do this:

1. Brute force sprites: draw a lot of sprites to form the shapes you want. This was the method I’d used for the previous version, and despite my complaints, for that version it was actually feasable: the number of sprites involved aren’t a negligable performance hit by any means, but they’re manageable and they’re easy. But to do this for a graph that shows changing population size on a per-frame/per-pixel basis? On a modern monitor we’re talking about 1080 sprites, multiplied by the number of species shown. Not viable.

2. Vertex List: dynamically changing geometry to represent the shapes you want. I didn’t spend much time looking into this option, but it has a number of things going for it: dynamically re-arranging Species Lines would be easy to do. The biggest problem with it is the bottleneck between the GPU and CPU: dropping that much vertex data on the GPU every frame can’t be a small performance hit.

3. Shader Trickery: sending the raw population data to the GPU and having it do all the work in the pixel shader by, essentially, drawing the graph on a transparent slide right in front of the camera. This is probably one of the best options here: it defers a lot of work to the GPU, is easy to implement, and allows the things I wanted to do, but… older shaders can only handle so many variables as parameters (255 for shader model 3.0), which is nowhere near enough. The CPU-GPU bottleneck issue still exists, but Shader Parameters are designed to be modified on the fly in a way that Vertices aren’t, so it’s not as bad. If I was targetting a later shader model this would probably be my preferred option, but as it stands… no.

4. Colour Arrays: generate an array of Color objects, modify it directly every frame, then save it to a texture and render that texture to the screen. Similar to option 3, except done entirely on the CPU rather than the GPU. I actually tried this one out: turns out that for full-screen textures it leaves a pretty massive footprint on your performance.

Yeah... note the frames per second counter, top left.

5. Render Targets: Oh god.

I hate render targets. I’ve had several dealings with them in the past, and every time they’ve given me a whole new bunch of reasons to hate them. Render targets are evil. /title drop

Don’t get me wrong, Render Targets are a vital and powerful aspect of the XNA framework, and there’s no doubt we’d miss them if they weren’t there. But they’re still evil. I still have nightmares about debugging Render Target issues. (okay I don’t really, that was hyperbole. My nightmares are more only have ordinary everyday things, like giant zombie demon spiders with flamethrowers held in their pincers. Also, the moth. Everybody has nightmares about the moth right?)

If not, you do now. You're welcome.

The basic concept behind this approach is to render only the ‘front’ pixels of the graph, then move the entire thing 1 pixel along next frame and render the next set of ‘front’ pixels. For a single line graph, this means you only have to draw 2 sprites: 1 for the line and another for the entire graph that was rendered last frame. This is a very efficient way of doing things, with the disadvantage is that what is drawn is drawn. I can’t modify the graph later if I want to move population lines to the left or right in response to population pressure.

But you can’t just do this straight onto the screen: I’m rendering everything else onto the screen, so I don’t want to be moving all that one pixel to the left every frame. Just the graph. And that means render targets, which are basically extra screens that you can activate, draw stuff on (without overwriting anything else) and return to later. Sounds easy, right?

A few points about render targets, for XNA users who are interested in avoiding the same horrible spiky pitfalls I fell into, climbed out of, then tripped and fell into again:

1. A render target has to be removed from the device before you can retrieve the texture from it. Failing to do so causes an exception. To remove it, call GraphicsDevice.SetRenderTarget(0, null);

2. Switching to a render target, then switching back, has an unfortionate tendency to clear your screen to a certain shade of purple. There are reasons for this (mostly because XNA is designed to work with the XBox, which has it’s share of quirks), but I didn’t know them at the time. All I knew was “suddenly purple WTF?”. To avoid this, it’s necessary to render to any Render Targets’s before you draw anything to the backbuffer.

3. A render target cannot render it’s own texture. In order to do what I said before (render a texture, then move it one pixel to the left and render again) you actually need to switch back and forth each frame between two render targets.

4. A render target cannot be used to render to multiple textures. You’d think you’d be able to render an object, then copy the result into a Texture2D and render a new object. This is what I wanted to do with the population lines so I could move them left and right: draw each one seperately and move their parent sprites. Turns out no: copying the result into a Texture2D only copies a reference to the Render Targets texture, so when you render the next thing in the list you overwrite the earlier Texture2D.

5. There is apparently a limit to the number of render targets you can have, so you’re not allowed to render multiple seperate objects that way, either. It’s nothing concrete, but somewhere between 40 and 60 targets the program will start to glitch out. For me, the sky went white, the game briefly lagged, and then it crashed out with an incomprehensible exception. I have no idea why these were the symptoms of too many rendertargets: I choose to believe I’d accidentally imported an identical anti-matter universe into the game and everything except the earth exploded at once. The few seconds of lag were just waiting for the shockwave to hit.

So how can you render an unknown number of seperate objects, like population lines, into seperate textures? There’s only one way: use a single render target, and perform a deep copy of the Texture2D before you move onto the next object so you copy all the information of the object and not just it’s reference. So how do you perform a deep copy? SetData() and GetData(), two of the slowest texture related functions in the framework! As it turns out, this performance hit for an almost-full-screen graph was almost as bad as option 1, way up there earlier in this post. So that’s out too.

(It’s probably worth noting that this method, can be possible for smaller images, like 256×256 thumbnails, where there’s less data to copy. I still don’t recommend doing it more than once per frame, however)

Eventually I gave up and left the population lines alone. The current system lets them stay where they are, overlapping.

No. No I do not forgive you just because you're working. I will forgive you only when the mental scarring goes away.

I’ll leave the fancy visual stuff to the proper phylogenetic tree, which won’t display population histories and will be implemented later WITHOUT RENDERTARGETS. SCREW RENDER TARGETS. (okay, maybe with one render target).

Hatethemhatethemhatethemhatethem…
Qu

Apparently he hates rendertargets almost as much as he hates multithreadin-“
NO. YOU DO NOT SPEAK THAT WORD IN THIS HOUSE.

, , , , , , ,

4 Comments

Bugs

I’m baaaack! And I’m sure everyone is glad to hear it, especially the small european countries my minions are secretly holding to ransom. Give the nice countries back to their leaders, minions.
“But…”
NOW! Seriously, have I taught you people nothing? We take over the world in one big sweeping dramatic move or not at all! I’ll have none of this logical behind-the-scenes war-of-attrition business.
“Can we at least keep Belgium?”
No!

Anyway, on with the farce! I mean show. (I actually mean farce)

Bugs (of the programatic coding variety, as opposed to the six-legged chitinous-exoskeleton variety) are a programming certainty. If you’re a programmer, and assuming you’re not some kind of savant, you will put bugs into your code. Debugging often takes up just as much if not more time than writing original code. So if you’re a coder, you will learn them, you will live them, you will love them (or not, as the case may be. I’m pretty sure that’d chafe like hell, and possibly electrocute you. Unless we’re talking about the six-legged chitinous-exoskeleton vari- WHAT THE HELL IS WRONG WITH MY BRAIN).

There are a number of different types of bugs. Now, the following isn’t official. I remember researching the “official” categories of programming bugs a few years back, for a Uni course I think, but my categories here are not official. If you use them around official people you’ll get weird looks. They’re about as far from official as it is possible to be while still living in a society that considers officiality to be a real thing. Even the most anarchial systems of government have deliberate exceptions for shit like this. They’re so unofficial they approach officiality from the other direction. Am I making myself clear here?

Compile Time Bugs

These bugs are the simplest: typos and mistakes that coding environment can detect, often before you even compile the program. If I tell the program to store a character string in a number, or to modify a value that hasn’t been assigned yet, or to access a class that isn’t even a part of this class, then this’ll happen. Effectively, it’s a mistake so blatently stupid that the computer itself is calling you out on it. They’re not even really a part of the debugging process, since you have to deal with them before you can test the program.

Exceptions

Simultaniously the best and worst of bugs, exceptions are what the program throws at you when it simply cannot do what you’ve told it to do. Remember “This program has performed an illegal operation and will be shut down”, and all it’s variants in Windows OS’s since then? Those are exceptions.

Exceptions are bad for obvious reasons: they stop the program instantly and you lose all your work. But they’re also excellent, because they’re things Visual Studio understands. An exception is by far the easiest type of bug to debug: running in debug mode, it will show you the exact line of code that threw the exception, give you an explanation as to why it threw that exception, and allow you to look into why that line of code threw that particular exception at that particular time. A program that has exceptions in anything more than the remotest reaches of obscurity is a program that hasn’t been debugged enough.

Unfortionately, a game like Species thrives in the remotest reaches of obscurity, so when I do release the alpha expect at least a few exceptions now and then. Thankfully, there will be an autosave function to neutralise the ‘lost data’ problem.

Logic Bugs

Logic bugs are bugs that don’t break the rules of the operating system or the compiler, but that do break the rules of the program. My energy cycle bugs are (were) logic bugs: things that do work, but that don’t work the way they should.

Logic bugs can be far, far more annoying than exceptions, because the program doesn’t know it’s doing anything wrong. It’s like the difference between a trained dog that knows not to come inside after it plays in the mud, and an untrained dog that bounds into your house with endless enthusiasm, smothering every available surface in material you’d rather not know about.

But they can also be a lot of fun. Out of the hundreds of bugs I’ve put into Species over the course of it’s development, a small number have been both coherent and hilarious. Like the time I put a divide into the vision calculations…

He See's All

… or the time I forgot to limit the ‘scale’ values to >0…

Just be glad Species graphics aren't more realistic, or this picture would be significantly... redder.

… or the mistake in the culmative ‘Species Average’ calculations…

THAR SHE BLOWS!

… or the time the creatures learned how to fly.

I *swear* I did not teach them that.

About that last one: I ended up putting in a placeholder fix and just amplifying gravity to Jupiter levels to make sure they’d stay on the ground. It was only several months later that I found out why they were flying and could put gravity back to normal levels.

For the most part, though, they’re annoying. Logic bugs are the reason deadlines are all but impossible to define. It can take anywhere from seconds to days to fix a particularly obscure logical bug. I mostly deal with them with a combination of analytical deduction and throwing code at it and seeing what sticks. Which brings me to my third category…

Debug Bugs

While debugging without knowing exactly where the bug is, I tend to put in small and temporary bits of code and re-run the program, watching to see if the bug’s cause or effect are influenced. When it is, it’s often easier to manipulate the temporary code to make it fix the bug, rather that re-writing to whole section with the bug in mind. Other times, it’s even possible to simply forget bits of debug code after fixing it, and leave them in there while we move on.

These sort of small, thrown-together segments of code are like cancerous tumours in a big project: often harmless on their own, but as more and more of them appear and grow they can start to conflict with original code and with other tumours. This can cause exceptions or logic bugs, and can often be harder than usual to debug because unlike original code, it’s easy to forget what purpose a tumour had when it was added.

If you’re a programer, check out the QuadTerrain class. There’s a segment in the comments in there that says something along the lines “I have no clue what this does, I can’t even remember writing it, but it stops working if I take it out.” That’s what I’m referring to. (Although to be fair, that particular case may have had less to do with debugging and more to do with coding while drunk).

Debug bugs are often a sign the original organisational design of a project is breaking down, and it’s time to rewrite a segment of code, consolidating all the bug fixes into an improved design. The Species project, because of it’s “evolving prototype” nature, has had it’s fair share of these.

Design Bugs

Sometimes, you’ll design something that simply won’t work. This happens. Nobodies perfect. A good example in Species is the Tree of Life graph: I wanted each different species on the screen to have an independant population line you could drag from left to right across the screen, putting them in the order you wanted, rather than a static graph. It wasn’t to be. Thanks to the way RenderTargets have to work and an unexpected limitation on how many you can have at once, (one day I will write a post on RenderTargets. It will consist entirely of the capital letter “A” repeated one thousand, three hundred and twenty-seven times) it’s not possible to draw each and every Species history in a seperate pass… at least, not with any sort of decent performance. (As it turned out, the memory bug that stopped Development Video #2 was directly related to this) So, after quite a few weeks working on it, that idea had to be scrapped. The species history is now a static graph.

Performance

Sometimes you’ll write some code and suddenly your frame-rate will plummet. Other times there will be no definate point at which you lose decent performance, it’ll just slowly decrease as you add more features. In either case, optimisation is needed.

This project is particularly prone to performance bugs, thanks to the sheer scale of what I’m trying to simulate. 1500+ completely mutable semi-sapient AI creatures interacting with each other is not exactly an easy thing to simulate. For quite some time I was scared that Species simply wouldn’t be able to run with enough creatures to make the simulation worthwhile.

As it turned out though, much of the update CPU work was caught up in one or two unecessary or simply inefficient methods, and could be negated. As it turns out, the largest necessary CPU cost isn’t the CPU at all: it’s the bottleneck between the CPU and the Graphics Card (strictly-speaking this is the CPU, but it’s related to how many times I send information to the Graphics Card in the Draw() method, not the actual simulation which happens in the Update() method. I’m losing people here, aren’t I?). And that’s even with aggressive per-creature level of detail (semi-relevant to Level Of Detail algorithms), something I’ll have to expound on in a future post. So in it’s current incarnation, Species will run at a significantly better FPS rate if you’re not actually looking at anything.

Thankfully, there are tools available for this sort of bug. NProf is what I use for tracking down where all my CPU time is going, mostly because I’m cheap and it’s free. There are lots of others, too. And if all else fails, code your own! The bars visible in Development Video #2 have been invaluable for performance debugging.

Hardware Quirks

Not a bug so much as an unexpected phenomena that you have to learn about and take into account if you’re going to make the most out of your program. Garbage Collection, mentioned in a previous post is this sort of thing. The parallel nature of the GPU, which I’m totally not using to it’s full potential BTW, is another. And multithreading and parallel cores, which I’m convinced were only invented because all hardware designers are secretly evil robots. Evil multithreaded robots. *shudder*

Being aware of these things, even if you don’t think you’re using them, is vital. Often you are using them without realising it, and it’s possible to lose a lot of time debugging and optimising in the wrong area if you’re not aware of what your code is doing under the hood.

So anyway, that’s how my brain breaks down software problems. It’s a purely subjective thing, of course. I don’t recommend anyone trying to use these categories in a school assignment or job interview. You’ll probably just fail or get turned away or have the police called to arrest the crazy person (if you manage all three at once, send pics!). But at least I had fun writing this post and subjecting you to the tortured organisational abilities of my gray matter cells. Both of them.

[after a proofread]… I’m starting to suspect there’s something seriously wrong with my brain. I mean, I barely remember typing half of that, and I’m sober. Seriously, how do I even get away with acting like this in the quasi-public forum of the blogosphere?

Oh yeah, orbital weaponry. I forgot.

Cheers!
Qu.

* * * * * *

“I… I don’t think I can possibly add anything to this post. There’s a lot I could subtract, but that’d be like desecrating a shrine. A shrine to some inconcievably terrible eldritch abomination with more tentacles than PZ Myers, admittedly, but a shrine none-the-less.”

, , , ,

4 Comments

Creature class and Leg Rendering

Oh hey look, the drawing tablet worskes too.

First things first: I got my computer back! AND IT WORSKES!

Also, I successfully got a post up! Sure it’s like half a week late or something, but I’ll take it. My fragile self-esteem needs all the help it can get.

So, scene setting: I’ve just finished the skinning system. I can render animated and deformed meshes anywhere I want in my environment. I’ve also modeled a few simple animated legs and a torso object.

Now, to be fair, I might be taking a few liberties with the chronology of things here. A lot of the following was worked out in parallel with the skinning system, but I’m presenting it as sequential because it sounds more organised. So don’t mind my temporally-unhinged antics here. I assure you that unless the cooling pump fails on the paradox diffuser the space-time continuum is in absolutely no danger of instantly ceasing to exist. And the chances of that happening are, like, 1 in 10. Or is that 10 to 1? Never mind, nobody cares anyway.

Moving on: there are two possible approaches to take when it comes to laying out a foundation for a class as central to the game as the “Creature” class.

The first is to lay out everything at the start. Take it all from the design document, set up every data structure I need, and then go about tying them together. So, I’d prepare an leg class with some genetically-defined variables for size, width and type, then set aside some ‘combination variables’, such as strength and speed. Then I could use occult magiks to force demonic slaves to write Mathematical Equations to derive the latter from the former, as so: strength = (bicepWidth + tricepWidth * 0.6) * sizeModifier, etc. Or I could do them myself, that works too.

OR… the other option is to wing it. We start by making the creature move at a constant rate, and then we go and set-up the leg rendering and animation code, and then we plumb the size of the legs into speed and then we actually make the size of the legs variable, and then some other things we made up on the spot and then we realise we can make the subjects into ravenous undead flesh-eaters to unleash on an unsuspecting populous and make an absolute killing selling shotguns, and then… you get the idea. Basically making it all up as we go along.

Now, given that both of these approaches are mutually exclusive, in a stroke of certifiable genius I went and enacted both of them at the same time.

… wait, did I say genius? I meant the other thing. Word. Starts with I.

I had a fairly good idea as to how I was going to structure the creature body parts: A torso object, with legs, arms, neck and tail objects attached to that, and head, tailtip, hands and feet, attached to those. I also knew a large quantity of genetic variables I wanted, so I went ahead and put them in so I could tie them all together later. But I also wanted to see it in action as soon as possible, so long before things like “speed” were set up I threw in placeholder values and started on the AI, so that the creature would do more than just stand around looking awesome.

And it worked. Okay, true, I ended up making changes to or deleting the majority of the genetic values, but knowing the basic structure of the class and it’s sub-classes was a great help when it came to prioritising work, and being able to see the effects of the changes I was making kept me enthused.

So, in the fine tradition of starting with the most time consuming thing possible, the very first thing I prioritised was leg and torso visualisation. The creatures aren’t actually held up by their legs in species: instead, I derive a torso-height based on their leg size, and the legs sort of dangle at just the right height to make it look like they’re standing on the ground. Okay, all well and goo: that’ll work fine for horisontally-aligned bipeds, but what about quadrupeds with differently-sized limbs? What about creatures that stand upright like humans, or creatures that drag themselves along with a set of huge legs up the front? Clearly I’d need to do more than just move the torso up.

This was solved by the addition of another, half-derived half-genetic variable called “torsoRotation”. torsoRotation determines the pitch at which the creature’s torso is orientated, from 0 at horisontal to 90 when upright (okay, the value is actually in radians, but who in their right mind says “Pi on 2” when they mean 90 degrees?).

torsoRotation is a genetic variable: creatures can pass it on to their offspring. But if the creature is a quadruped, or if they are overly unbalanced (for example, small legs at the very rear), then torsoRotation will be overwritten with a value derived from a whole bunch of rules depending on their leg sizes and positions. This allows creatures to “stand up” without making it arbitrary or nonsensical: a creature who’s back legs increase in size will automatically pitch forward unless they usually stand upright enough to compensate for it.

My handwriting is banned by at least 3 seperate clauses of the Geneva Convention

Fittingly for a game like Species, this all affects survival in various ways. Any creatures whose body touches the ground suffers a ‘dragging’ energy-loss penalty whenever they move. Upright creatures move more slowly, but use less energy to get around. And so on.

This system of rules, once it was finished, resulted in a large variety of potential body plans, even with nothing more than legs and a torso. And, thanks to the time already spent on the skinning system, I could take randomly generated test renders of them straight away:

Cheers,
Qu

Don’t worry everyone, I swapped his paradox machine for a coffee maker and replaced his timecube collection with fluffy dice. The worst he can do now is make a terribly tacky espresso.

, , , , , , , ,

Leave a comment

The Beginning of the Beginning

Early-Mid 2008

Enthusiastic innocence quickly gave way to confused curiosity as I realised that working with XNA wasn’t really anything like the amateur programming I had been doing before. It had similarities, sure, and it was still many saganhertz more user-friendly than working directly with DirectX, but it didn’t try to hide the skeletons underneath: instead, it encouraged me to dig them up and molest their remains as much and as often as I could.

Err… okay, that analogy got creepy fast. Moving on: what I was trying to say before my twisted subconscious got control of that sentence was that, rather than providing me with pre-built shaders, XNA provided me with one really basic shader and then encouraged me to learn HLSL (High Level Shader Language. Yeah, programmers aren’t paid to be inventive with names), so I could write my own. Rather than giving me an inbuilt animation system, XNA gave me a sample solution in which such a system was implemented, encouraging me to learn how and why it worked. And so on.

So even though it was more difficult and slower than working with my other engines and programs, XNA managed to hold my interest, and still does. And with that interest came the inevitable question “what am I going to make with it?”

It’d need to be something that I wouldn’t be afraid of screwing up: so anything with a complex story was right out. Something small enough it could be done by a team consisting of 1 mundane modeller, 1 poor programmer, 1 worse writer and 1 apathetic anal-retentive alliterative ass, and where I was all of those. Except the last one, ’cause I loathe alliteration with all my shrivelled black heart.

[awkward pause]

Say, didn’t I have an idea for an evolution simulator around here somewhere?

If “saganhertz” isn’t a real word it should be,
Qu

, , , , ,

Leave a comment