There’s a reason the last post was on killing creatures, because this is where we get to the other end of the spectrum: the Yin to Deaths Yang. Yes, Death has a Yang. The internet demands it!
For your safety and the safety of others, I redirected that link to TVTropes. Qu should be ashamed of himself. Besides, everyone knows Death is a girl.
With the new-fangled Creature Queue we went on and on and on and on about in the last post, adding new creatures is easy. But so far, the only type of “new creatures” we can add are randomly generated, like these guys:
Having creatures give birth to completely different randomly-generated creatures is closer to what certain anti-evolutionists believe evolution proposes *cough* crocoduck *cough*, than it is to what evolution actually proposes, so this would require some modification.
The first task is fairly simple, albeit time consuming: initialising all the Creature variables to match those of the parent creature, thus creating an exact clone of them.
Now if computers were built along the same lines as biology, then this copying process would naturally be far from perfect. Unfortunately, they’re not (and by unfortunately, I of course mean fortunately. The lack of similarities between machines and biology will likely prevent the machine war and the subsumption of humanity for at least another decade). Machines check and re-check and check all over again any data they take copies of. Biological systems do not. So in order to achieve what biological systems do naturally, I have to manually apply random mutation.
Now, when I say random I mean it. If I was Dawkins then sooner or later an antievolutionist would claim that I implemented mutation locking or guided evolution or something equally stupid (I mean seriously, who would waste time doing this when it’s so much easier to just implement ordinary selection?). So, to answer those hypothetical claims, here’s a bit of source code…
shoulderWidth += ((float)rand.NextDouble() * 2f - 1f) * 0.2f;
The basis to this, and to every floating-point mutation in the game, is the
((float)rand.NextDouble() * 2f - 1f). What that does is generate a random number between -1 and 1. It goes up and down with equal frequency. No locking, no guidance, just randomly random goodness of randomness. (I swear I will shoot the first person to mention that computer algorithms are actually only pseudorandom. It’s based off a DateTime seed! It’s close enough!).
Now, you may have noticed… wow, I’m on a tangent-spree today… that I specified “floating-point” mutations above. Not everything in Species is a floating point mutation, with a continuous spectrum of variables between them. There are a finite number of meshes for headType, for example, so it is stored as an integer: 1 for a spherical head, 2 for an overbite, 3 for an underbite, etc.
These sort of mutations are still random, but they also have to be limited. We can’t jump from a light-sensing patch to a fully formed eye: there need to be intermediates. That’s where we get to the need for a Mutation Map.
But we’re already further off topic than Columbus ended up when he went sailing for the East Indies, and a mutation map is something I’ve still yet to properly implement. Returning to the original point: with creatures able to be born from other creatures, and creatures able to die, we have the start and end in place for a working ecosystem. So what still needs to be implemented is the bit in the middle: under what conditions is a creature born, and under what conditions does a creature die?
Which I think is a nice segue for next week’s topic. See you then!
Little known fact: Columbus’ first words upon setting foot on New World soil were “wait… what were we talking about?”