Posts Tagged Species
I’ve been working on applying torques to the creatures in a meaningful and well thought out manner (read: banging my head against the keyboard whilst trying to fix all the horrible signage errors). The original intention was to simply pass the torques on to the energy system and let natural selection weed out the unbalanced and physically impossible specimens. But I realised I have the perfect opportunity to overhaul a system that has bothered me since its inception: the quadruped system.
Logically, if a creature has slightly smaller front limbs than back limbs, it should lean forward in order to walk on them (unless it’s a pangolin, but they’re too awesome to be swayed by our petty logic).
Without something to enforce this, every creature in Species ALRE would be a biped, because every creature has at least a *slightly* different leg size.
The quadruped system governs how this is implemented. A hideously simplified description would be “if the torso rotation is less than 45 degrees, and it has fore or back legs, the creature will fall forward onto its front legs or chest. If it’s higher than 45 degrees, or it has mid-legs, it will remain bipedal.”
That “45 degrees” is completely arbitrary. It’s just a value I picked.
This system is why ‘head-down butt-up’ creatures, whose bodies hang forward from their back legs are so common: Any creature with large back legs and a small torso rotation will end up with this body plan.
That’s the old system. The new one is much more sophisticated.
It starts by completely eliminating the quadruped system: creatures will initially be created *exactly* as their genes would have them (ie. with only one pair of their legs reaching the ground). It then calculates the skeleton and torques as normal.
Once that’s done, it passes control to the droop system. This applies “droops” to every body part attached to the torso: limbs, neck and tail. Legs are bent upwards by the reaction force on their legs, neck and tail are bent downwards, and the torso droops based on the creature’s balance, all in direct proportion to the torque applied on the joints.
If a body part droops into the ground, it stops drooping and adds a ground contact point, which will take some of the creatures weight in the next step.
Then pass 2 starts, the body-plan is completely reinitialised: bones are regenerated, torques and forces are recalculated. The results of pass 2 are what the creature will ultimately use for most of it’s energy calculations, so as to take advantage of the creature new quadrupedal body plan. (physical droops will affect energy, but proportionally to how much they rotate rather than as a function of torque. Small drops onto legs will be a negligible cost)
This also has a noticeable effect on creature appearances. I haven’t adjusted the rotation genes at all in the following screenshot: these variations are entirely the result of torso, neck and tail thickness changes causing different torques in the creature’s body plan.
One particularly noticeable change is that the creatures tail now has an effect: increasing its mass is the only way to counter the torque produced by the head and neck in the second body plan. For bipeds with centrally situated legs (raptor-like creatures), a sizable tail will be the only way to maintain balance (other than having an upright torso rotation gene and incurring a large energy cost in droop).
I’m hoping this system will be realistic enough to promote life-like body plans in place of a real-time physics system, which would be far too CPU intensive to implement across thousands of creatures. More likely, it will be exploited ruthlessly in ways I can’t yet imagine. But hey, that’s what makes it fun!
“Anime references. There goes the neigbourhood”
I forgot to charge my laptop yesterday so used the forced break to practice my sketching, but I’m back in it today and development continues.
The Mutation Map tool now has the ability to view and edit both the overall map and the individual stats of each head. It can also do the same for Feet, and I’m working on getting the remaining mutation maps (Limbs, Coverings, Colour Patterns, Feature Models and Feature Textures) into the tool. Hope to be done by the end of the week and moving on to other things, though that may be a bit optimistic.
Also took some time to begin taking my Stat encapsulation to the next level. Currently we have 6 types of Stat:
- GeneticStats encapsulate a mutation rate, plus mutate, randomise and blank routines, for every gene.
- FloatingGeneticStat: A hereditable decimal number, like “torsoWidth” or “headSize”. Encapsulates an upper limit and lower limit in addition to the mutation rate.
- DiscreetGeneticStat: A hereditable integer number, like “numberOfFeatures”. Just encapsulates the mutation rate.
- BooleanGeneticStat: A hereditable yes/no value, like “hasTail” or “hasNeck”. Just the mutation rate again.
- MappedGeneticStat: A stat with a mutation map, like “headType” or “bodyCovering”. Encapsulates the entire mutation map structure.
- BasalStat: a non-hereditable stat which is imported from an external file, linked to a MappedGeneticStat. Like how HeadType determines Diet, or how LimbTipType determines BaseLimbDamage. These stats are rarely used directly: usually, they feed into formulas to determine other stats. (diet is an exception)
- UpdatableAttribute: a type of Stat I have encapsulated but haven’t derived from IStat yet: these are things like Health, Energy and Biomass, which change over the course of a creature’s life. Encapsulates a list of “Deltas”, making it possible to track the source of changes to these stats (you can see these deltas listed out on the energy page in creature details).
There’s only one major type of stat still missing, at least on a per-creature level:
- DerivedStat: Any stat which calculates itself from other stats. For instance, Speed takes into account LimbSize, LimbBaseSpeed, TorsoWidth, TorsoRotation, LimbTipBaseSpeed, and so on. DerivedStat will encapsulate all these stats, plus the formula used to combine them.
The method I’m using to encapsulate the formula uses something I haven’t spent much time with in the past: delegates. I’m storing it the entire formula as a delegate inside the DerivedStat instance. This means I get to define the formula in StatData, but still use the built-in accessors of the objects, so I get the same intellisense benefits and high performance as if I was defining the calculation over in Phenotype.
The result looks like this:
"Mass", //Printable Name
"Determines how much stuff there is in the thing", //Printable Description
delegate(Genome genome, BodyPlan bodyPlan, Phenotype phenotype) //boring code stuff
return bodyplan.Volume * genome.Skin.Density; //Formula
The relevant bit is the second-last line: that’s the only place that formula needs to be defined. All I have to do later is call Initialise, and the DerivedStat takes care of calculating itself on behalf of it’s parent creature, pulling other stats in and combining them, as well as throwing errors if stats haven’t been correctly initialised.
Yes yes, making with the boring and the code and the words and the stuff, so what? Why do we care?
Here’s why we care: every calculation, limit and mutation rate from the raw genes to attributes like speed and stamina is now stored in StatData. This one file is becoming the spinal column of a lot of the simulation’s behaviour, so tweaking mutation rates, adding limits, changing names and descriptions, and now adjusting stat formula will all be possible simply by changing the input data here.
And I intend to expose that input data to modding.
Cue the maniacal laughter,
Welp, we finally managed to track down the Black Ground bug, by means of Google research and an Ouija board. Turns out AMD cards can’t use a 2.0 vertex shader model in the same pass as a 3.0 pixel shader model, but rather than doing something sensible like, I dunno, telling me about it, instead it adopts the much more interesting approach of falling over randomly and not drawing anything.
Fixing this meant adjusting a whole bunch of shader files, and I lost track of which ones had been modified somewhere along the way, so to get the hotfix you’ll need to re-download the game. If you extract the files into your existing Species folder and merge/overwrite, you should be able to keep your save games and exported creatures.
Also made a few small tweaks and fixed one of the more common exceptions. Potentially-stable release ahoy!
– Fixed the Black Ground/Invisible Creatures issue people with AMD cards were experiencing.
– Fixed the ArgumentOutOfRangeException that was causing crashes after an unspecified period of time.
– Tweaked Body Pitch so creature’s don’t lean back as much as a result of growing legs
– Tweaked CalculateReach so creature’s can’t increase their reach by having a not-expressed neck length.
We’ve been busily hotfixing since the release, and 0.6.1 is now much more stable than when it was first released. We recommend downloading the entire thing again:
(Tip: if you extract the latest version directly over the top of the previous one, you won’t lose any of your saved worlds or exported creatures!).
… but if you’re an advanced user and don’t want to download the full 75MB again, you can download the patches. Make sure you apply them in order.
First, fixed an introduced bug that was giving canivores the ability to eat vegetation and removing herbivores ability to eat anything. A single missing “-” and herbivory stops being viable. Let’s hope that’s the last major error and the release is stable! (“Haaaaaahahahahahah!”)
Second, since I haven’t spotted any other bugs recently, I followed through on my
threat suggestion to include an Indirect Rover Control Mode, where the rover uses it’s AI to attempt to drive in the direction you point the camera. The result is every bit as broken and insane as you’d expect, and it. is. GLORIOUS.
Finally, Species has adopted a new, less minimalistic logo.
The clade diagram was planned from the start: the symbolism there is an obvious match for Species. I find it amusing how the game’s name correlates with a mass extinction, but then again I’m easily amused.
The cycad leaf was more a case of Throw It In: it was originally going to just be the middle arc, but that looked too much like a planet. While that wouldn’t have been a bad representation of the games’ scope, it’s too reminiscent of space and science fiction in general.
I was about to delete it when I threw some fronds on it on a whim, and liked the result. And the additional symbolism is nice: cycads are an ancient clade*, evocative of prehistory, nature and dinosaurs. All good evolutionary stuff.
We’re still on track to release 0.6.1 on February 1. 🙂
*footnote: if anyone uses the term “living fossil” I will personally inject live cockatoo’s into their bloodstream.** I generally don’t do this because it’s a bugger to find a syringe big enough, but I’ll make an exception.
**footnote: don’t worry, it doesn’t hurt the birds. It’s actually fairly close to how they reproduce in nature (they’re Australian).