Posts Tagged Development
Want more details about features and fixes in the upcoming sub-release? (I’ll try to get it out in a week or two)
0.4.1 Development Thread.
Want more details on the plans for the next big release? (might take a bit longer)
0.5.0 Development Thread
Details about known bugs in the game, and their status (fixed, not fixed, etc).
(Note: Instructions on how to use the Mod Maker coming soon!)
Not everything in Species has gone the way of the behavioural system, getting simpler and simpler over time. Some things, like lifespan, have actually been becoming more complex over time, slowly integrating themselves with more and more systems in the game. (Don’t worry, I’m like 80% certain none of them are about to become Skynet)
As already mentioned in previous posts, lifespan initially wasn’t included. Once reproduction was put in place, however, we needed to ensure there existed ways to die beyond “brutally murdered by the developer”, which up until then was the only cause of death.
This was something I hadn’t designed from the start: how lifespan should be handled simply hadn’t occurred to me. So to start with, I did the simplest thing and just killed the creatures the moment they hit a certain age. From memory it was 2 minutes simulation time.
This was a pretty blatant instance of placeholder abuse. The lifespan was artificial and arbitrary, but I told myself it was just a placeholder so it didn’t matter and moved on with other things.
As it turned out this self-serving assumption was both true and false. True, it didn’t matter at the time I implemented it: at that point energy leaks and AI bugs made balancing the game a futile endeavour. But it did come to matter later, because as it turns out, 2 minutes isn’t enough time to find food and reproduce. Who’d a thought?
The next iteration (after upping the lifespan variable to compensate several times) was to turn lifespan into an inheritable value.
This turned out to be an interesting solution. Creatures with a longer lifespan would spend longer in childhood, unable to breed. This meant that creatures would have to find the right balance.
Unfortunately, it was impossible to guess a creature’s lifespan from visual cues. It was the same problem I was having with the behavioural system: you couldn’t see lifespan evolution happening, at least not directly. I needed to tie lifespan to something physical.
The third step was to tie lifespan to size. Larger creatures live longer than smaller creatures, right?
This was a lot better, and it made it possible to see the effects lifespan was having on natural selection. It still felt a bit arbitrary (it was possible to put a countdown-to-death timer on top of every creature based purely on their size), but it wasn’t a bad system.
But at this point I realised something else that was bothering me about all these systems: they were instantaneous. Age and lifespan had absolutely no effect on a creature until suddenly and without warning they exploded into mounds of delicious meat. This doesn’t normally happen in real life (well, except that one time I mixed up the nitroglycerine and the cat food, but that was totally* an accident).
The energy system at the time also meant that creatures dying of old age had far more meat on their bones than creatures killed by attacks or starvation, because their energy and health bars were often still full when they died, so they got converted to meat. This side-effect was unexpected, and unless you understood the system behind it, didn’t make much sense.
The fourth implementation (or possibly the 3.5th) was an adaptation of the previous version, where rather than just getting insta-gibbed, creatures past their use-by date would gain a new energy cost, similar to the cost of growing out of childhood. This “dying” cost would deplete their energy and health bars, resulting in a much more natural-seeming death.
But I still wasn’t happy with it. It was theoretically possible for a creature to eat enough to offset the dying cost and live forever, and increasing the age cost enough to counter that possibility simply made it look like I was insta-killing them again. It wasn’t that big of a problem, but I still wasn’t happy with the system. It just didn’t feel right.
And so I finally got around to giving the problem the attention it deserved in the first place. How does lifespan work in real life? (Morbid discussions on the nature of mortality! That’s what this blog needs more of!)
In real life, the damage from age is gradual and increases over time. We don’t suddenly hit a certain age and keel over, we just slowly take more and more damage until our body can no longer keep running. We can offset this with a healthy diet, exercise, and homeopathic remedies… pfff no I’m kidding. Stick with the healthy diet and exercise, at least they do stuff. Anyway, we can offset the damage significantly, but we can’t offset it forever, because it accelerates as we age. It was relatively easy for humanity to get our average lifespan up to 80, but now we’re struggling for every extra year, even with the incredible advances in medical technology we’re seeing in recent times.
So how does this translate to Species? Fifth implementation: aging doesn’t suddenly kick in at the end of the creatures lifespan, instead starting slowly and accelerating over time. Young creatures just out of childhood spend very little energy on keeping their body running, while older creatures spend ever-increasing amounts. This ensures that no matter how quickly a creature can gather energy, it’ll never be able to stave off death indefinitely.
Of course, I still want longer and shorter lived creatures correlated with size, without just handing an indisputable advantage to the largest creatures on the map. A bit of further thought/research on the subject revealed something interesting: smaller, shorter lived creatures in real life tend not to show signs of aging until the very end, while larger creatures die more slowly. This gave me an idea: a variable energy loss curve.
As you can see, small creatures (x3) have the advantage early in their life: more energy to spend on moving, eating and reproduction, but then their energy loss accelerates sharply towards the end of their life. Large creatures (c*x) lose the early advantage in favour of a much higher staying power. In-between creatures lerp (linearly interpolate) between these two graphs.
An interesting point about all this extra complexity in lifespan determination: it doesn’t obscure the in-game evolution the way the complexity in the behavioural system did. The ‘mutable lifespan’ I had way back in step 2 was a lot simpler than this, but also a lot harder to spot in action. I assume that’s because this system matches what we intuitively know about the world: larger creatures live longer, smaller creatures are more energetic (ask any dog owner). The complexity here just gives the system more nuance, making it feel more natural.
So I guess the take-home message is: complexity is not the enemy of intuition. A familiar but complex system is preferable to a simple but alien system.
I’m totally deep!
*footnote: For the record, whenever I use the word “totally” in this context, I am, like, totally being ironic. I don’t generally speak like a high schooler from the 90’s. Dude.
“The neighbour’s cat was probably lucky it was only nitroglycerine. He stores mutagenic nanobacteria on the next shelf down.”
Yay! Another video! And another set of comments about said video that I was too lazy to put into the original video itself! Yay!
There’s three major ones visible in the video: levitating creatures, which is caused by a minor bug with how the creature finds ground level, the Species Average Thumbnail not working, which I threw a textual tantrum over, and a bug with how Stamina is calculated (did you spot it?). I managed to fix all three of these in between recording and uploading this video.
Of everything in the UI, the real-time energy graph is the most obviously placeholderish. With a bit more work it will look a lot more professional, with current-moment positive and negative effects and their magnitudes (things like metabolism, walking, eating) shown, and icons applied to sudden drops and jumps (like the ones caused by reproducing in the video).
The genetic code you see in the video is genuine: it really is a representation of the creatures genetics, and I have already built the function that allows the player to clone creatures from it.
But with that said, it’s sadly not completely analagous to a real organisms genetic code. It has some beguiling similarities, like codons and genes, but it’s a ‘code’ in every sense of the word: it represents the creatures actual genes, which are a list of numbers. This means it’s possible (albeit difficult: it’s quite robust, and only going to get more so) to ‘break’ the code and make it impossible to compile. Biological DNA is not at all like that: it always codes for something, no matter how much you change it, because it’s “compiler” is a physical process.
This difference was implemented for several reasons, but the biggest is probably performance: I doubt I’d be able to run a quarter of the number of creatures I currently can if I was actually using the genestring itself for calculations. It also makes balancing mutation rates easier: eye sizes should mutate a lot faster than overall sizes, for example.
I won’t explain the system here and spoil it for any cryoptographers who are interested in trying to decode it, but it’s not a particularly complex code.
This is one of the player-oriented gameplay elements planned for later versions of the game. A lot of thought has been given to how the player will interact with the simulation without completely taking over the ecosystem and directing everything on Gaia, and artificial-selection and genetic manipulation are the two primary elements of this. There will not be a Spore-style creature editor. Don’t get me wrong, I thought the creature editor in Spore was brilliant (it might have been the only thing that was), but I’m pretty certain it would take all the fun out of Species if you could just customise ‘your’ Species exactly the way you wanted it right from the start.
Hell yes indeed! I now have a personal deadline to meet, a list of things to achieve, and I have officially made the announcement like we’re some sort of proper indie studio or something (fingers crossed nobody figures out we’re just some random guy with a laptop and a few friends helping out occasionally). So bar anything catastophic, an Alpha Release (Species 0.4.0) is on the horison and slowly getting bigger.
Yep. I’m following a slight mutation of the Minecraft
get-rich-quick scheme marketing strategy (my plan is probably closer to Kerbal Space Program, which is awesome by the way), which seems to have become something of a de-facto standard for indie game releases. So all the alpha releases (however many of them there are) will be free, while the Beta releases will cost something, and the full releases will cost a bit more, but buying a beta release or preordering during the alpha stage will get you the full version anyway for less money than what you’d pay if you bought later, and the alpha releases will always be free-to-download even after the beta and full versions are- HOW DID SOMETHING THIS COMPLICATED BECOME SO POPULAR?
I might set up donate/pre-order button when I release the first Alpha. I’d feel like a jerk if I took any money without giving you guys something first. 🙂
Hmm… I’m pretty sure that’s everything I wanted to cover here.
Thanks for reading!
“No snark today. Too tired from spending all night editing his stupid video for him. Lazy sod.”
Presenting the unholy lovechild of Fraps, Species and Premiere, whose birth heralds the riding of the horsemen and the coming of the prophesied end times… or would do, if October 21st wasn’t 4 days ago…
… Hmm. I don’t really have much to add here. I think I put far too much information into the annotations this time around.
I stuffed them up again. It’s hard finding a format that works: the first video’s annotations were distracting, this video’s annotations are unreadable without taking your eyes off the video. Plus they’re really fast, because I tried to put too much information into them.
I’m still reluctant to actually narrate because I sound like a nerd.
The game in it’s current state generally stops responding somewhere between 15 and 25 minutes in due to a SystemOutOfMemory error. This is annoying, but I’m fairly sure I know at least one way to reduce the memory footprint. It might also be related to running fraps at the same time: I’ll have to investigate that.
Looks nice, doesn’t it? I ‘borrowed’ a few images from google. It’s amazing the difference a good texture makes. But since I don’t know whether they’re under copyright or not, they’re still just placeholders. I’ll make my own trees eventually.
As you can see, a stable population of creatures tends to keep the vegetation from growing back. This is annoying, because the trees add a lot to the visual design. I’d like to work out some way of keeping a decent number of trees around even when there’s a moderate population amongst them: maybe rather than shrinking/growing, trees could transition between a ‘dead’ texture and a ‘live’ texture? Not sure, but mulling it over.
For the programmers amongst us who find this sort of thing interesting, here’s the colour key for some of the larger debug timer bars:
Blue: Update Call. Creature AI, Behaviours, Movement, Interaction: I've managed to reduce this one by a lot by messing around with the implementation. It's quite a compact routine now, though the code needs a major clean up.
Green: Species/Population Tracking. This should be almost entirely taken up by comparing creature genetics to search for speciation. Unfortunately, it's not: that's actually surprisingly fast. What really takes up the time in this routine is drawing the population graph. Render Targets hate me: the entire population graph may have to be re-written to fix this.
Magenta: Prepare Draw. Updating the animations, bone sizes and positions. This is where most of the Skinning is done. Lots and lots of matrix operations. It's been optimised, but it's still a fairly heavy routine. But not as heavy as...
Blue (2): Draw Call. Thanks to the 'every creature is unique' nature of Species I can't use mesh instancing, so drawing 1000+ creatures takes an utterly unholy amount of time. I am using State Batching where possible (so, for example, I draw all the torso's in one loop, all the necks in the next loop, and so on), and that helps, but mostly it's just a blow I have to take.
There’s any number of things that need improvement visible in the video, mostly related to entertainment value more than accuracy. Some, like homogeneity and being able to tell which species is which, are general behaviours that require a subtle solution. Other’s, like implementing a proper vision system for creatures, are specific and obvious. It’s probably simplest to focus on the specifics for now, since they’ll likely have massive effects on the overall behaviour of the simulation. A lot of work to do yet!
The Next Video
… I realise this video was kinda boring overall, so the next one will be about showing off potential creature variety and the effect different shapes and body-parts have on stats. Much more interesting! But there’s a lot I want to implement before doing that, and if this video was anything to go I happen to be absolutely terrible at getting these up at the time I want, so don’t expect it for a while, okay?
Huh. Guess I did have more to add. That was unexpected.
Oh well, it keeps me entertained. Not much else to do in the EMP cannons prison block. Thank goodness they have internet access, that’s all I can say. Very forward thinking of me, putting internet access in my own prison cells- DAMMIT WHY HASN’T ANYBODY LET ME OUT OF HERE YET?!!
(UPDATE) At 5:53 EST the insect-man army broke our defenses and overran the Orbital EMP Cannon. We were all taken hostage by the geneticist Overlord and mouthpiece for the bio-scientist hivemind, a rather pleasant bearded fellow.
Thankfully, after we locked Qu in one of the cells to shut him up, I was able to convince the Overlord to spare our lives. He even let us keep the cannon, though he took the firing mechanism (for our own safety, of course).
It’s been several hours, and everything has returned back to normal. Seems remarkably quiet, though. Strange, though. I can’t shake the feeling I’m forgetting something, but for the life of me I can’t remember what it is…
IT’S ME YOU BLOODY SASQUATCH! LET ME OUT!
… nup, can’t think what I might be forgetting. Oh well, I’m sure it’s nothing important.
I WILL WREAK VENGEANCE UPON YOUR PATHETIC FORGETFUL SOUL! YOU HEAR ME?!
I fail at blogging. It’s Tuesday night and I still haven’t put anything up here. Who wants to administer the mandatory kick in the pants?
So, moving on again…
With the leg-and-torso system in place I was up and running, adding more possibilities and developing the creature AI and visualisation. Colours! Necks and tails! FSM’s!
… yes, FSM’s. No, not Flying Spaghetti Monsters: That’s what I thought when I first came across the acronym too, but here I’m talking about “Finite State Machines.” If that sounds like a doomsday device to you, awesome. Keep believing that, because a doomsday device would be so much cooler than an actual Finite State Machine.
Long story short, a finite state machine is a term in AI programming that refers to a list of simple, mutually exclusive states that an entity (an enemy, an NPC, a creature, etc) can be in, along with a set of rules as to which states can go to which other states. A typical example for an FPS enemy would be as follows:
As you can see in the above example, an enemy has to be startled before they’ll start attacking. This might give you a chance to play a ‘jump’ animation (for example, the grunts in Halo), or to get them to shout for help, before they target the player.
Be separating the code into mutually exclusive segments like this, it becomes easier to debug, easier to change and actually has better performance: I don’t have to check for cover, see whether the enemy can shoot, or run any collision or movement AI for an enemy marked as “Idle”, since he would just stand around. It also makes the enemies easier to read and predict, which is an essential element for many games.
Back to Species: the FSM for Species is a lot less regimented, and a lot more complex because creatures can go from one state to almost any another pretty much at any point, with “moving” used as a hub. By using “moving” in this fashion, a creature has to turn and walk towards it’s target before it starts eating/attacking/mating with it, meaning that under most circumstances creatures will be facing the object they are interacting with as they interact with it.
Dead is the exception: if I tell a creature to die, it dies immediately, no matter what state it’s in.
*footnote: This is actually an idea I had while drawing this diagram. Currently, “playing” is an utterly useless behavior, and creatures jump between Moving and Mating freely, but if it serves as an entry point to mating then sexual selection becomes much easier to implement.
Now, at this stage in the chronological saga, I’ve implemented Idle and Moving, and am now adding Eating (which, because I considered this need when making my Vegetation System, isn’t too much of a problem), but I want to discuss the FSM as a whole and nobody can stop me, so I’m going to, temporal paradoxes be damned!
Something you’ll notice about this FSM is that a creature can’t actually decide what they’re going to do with an object until they reach it. If they see another creature but aren’t close enough to perform an action, they have to go to “moving” until they reach it. Even if they are close enough, they still have to pass through moving to get to the correct state. They can’t just go to “attack”, or to “mate”, because there’s no “moving” code in those states: they’d just stand there staring longingly at the creature they want to attack or mate with (or worse, they’d try to damage or impregnate the other creature from a distance, with no physical contact. Hmm… note to self: develop a device to do that in real life).
This directly affected the eventual structure of the behavioral system, which has undergone more iterations and revisions than Doctor Who canon: I couldn’t just give a creature a high aggression and expect it to attack. Predators need to combine a high curiosity level with a high aggression, so that they seek out other creatures and then choose to attack them.
Okay, now returning to chronology.
With the structure of an FSM set up, my randomly generated protoCreature wanders the world, going to each plant, eating it, and moving onto the next. Given a couple years, she might be able to eat the entire map (or those parts of it she can get to, anyway).
Oh heck… NON-SEQITOR SCREENSHOT LIST!
Because why not? (because I couldn’t come up with a friggin segue, that’s why not. Bah! Humbug)
Picking up where I left off…But for the other states in the finite state machine, I would need to implement a lot more than I had done. Attacking requires other creatures and a health system. Mating requires other creatures and a reproduction system, which in turn required a mutation system. Even eating was far from complete, being purely herbivorous and lacking an energy system entirely. And we’d need a system for dying when creatures ran out of health, and a system for tying physiological differences to survival traits like speed and stamina, and a per-creature-perception system, and a behavioral modification system, and a…
Wow. When you actually list them out like that, it sounds like a much larger endeavor than I thought it was at the time.
A common thread through all of these systems is that they are purely environmental: they control the universe in which the creatures live, not the survival of the creatures themselves. The creatures ability to reproduce, and thus any evolution stemming from natural selection, are emergent, not inbuilt.
Anyway, the next system on the agenda is preparing the ubervirus for release on an unsuspecting populace. If we can get a large enough infection rate in the first few days we can turn 90% of them into ravenous undead monsters by the end of- wait. Wrong agenda. Which agenda was I talking about? Oh, right, the one involving interior decoration and making everything look faaaabulous- no, not that one either?
Dammit, someone give me the secret agenda I’m supposed to be reading from! Geez!
Alright, it says here that the next system on the agenda is making large populations of randomly generated creatures, to pave the way for creature interactions.
for(int i = 0; i < 500; i++)
Well that was easy. No point doing a whole post about that. Tell you what, I’ll go move ahead and schedule something more interesting for next time.
Man I’m all over the place today! Is it possible to internally generate alchohol? Cause I think I’m doing it. God I suck so much at blogging.
Administering mandatory kick in the pants in 3… 2… 1…
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.
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:
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.
Prototyping in coding means, roughly, “the process of writing bad code that pre-empts the process of writing good code.” In other words, it’s taking best practices and shoving them where the sun don’t shine (that’s that little place up near Lancre, isn’t it?) so you can rapidly code something that almost works, independant of all other variables. Usual procedure would then be to use what you’ve learned from the prototyping exercise to re-code the thing that almost works so that it actually does work. You know, decently.
As terrible and haphazard as the code behind the prototype will be, the finished product will be polished and professional, a triumph of well-organised project management and good coding practices, and there’s a good chance that the time you spent coding the prototype will pay for itself by allowing you to avoid all the pitholes the second time around. It’s like driving a really crappy car off the cliff so you can find out if you’ll survive when you do it again in your $200,000 Maserati. Only not like that at all. I may have screwed up that analogy. Whoops.
So when working in Species, it’s obvious that I made that most sensible decision of all time ever and chose not to prototype. Coding it twice? That sounds like more work! Screw that!
All those pitfalls? I ran headlong into each and every one of them.
But this did have one noticable advantage: the game served as it’s own prototype. Rather than being mapped from the start, it evolved by trial and error. My first vegetation system failed, so I rebuilt another on top of its decaying carcass, theifing the good and commenting out the bad. It was a process of revision and improvement over design, trial and error trumping any actual organisational skills on my part.
In a weird way, the process of evolution itself was what produced this game. And I’m going to pretend that’s what I was aiming for, because that allows me to continue in the blissful delusion that I’m a halfway-competant programmer for a little while longer. Besides which, it’s quite obviously the same approach the “intelligent designer” took when he was designing the human reproductive system, so at least I’m in good company.
But for the rest of you programmers out there, a bit of advice: PROTOTYPE! It’s worth it.
In his defence, he’s not as godawful a programmer or as insane a human being as he likes to portray himself as. He just enjoys participating in self-depricating humour… why isn’t my Maserati in the garage?
… Oh hell no.