Posts Tagged Artifical Intelligence
“FYI, the first third of this post consists of Qu just typing randomly with no coherent subject as he tries to come up with a subject for todays post. I have no idea why he decided to include it. Padding, probably. Feel free to skip to the stuff actually worth reading further down (assuming any of this dreck is “actually worth reading”).” -i
Welp. I have no idea what to write. I generally just write these posts by typing out whatever bullpoppy pops into myhead, and then going back and inserting some rediculous analogies, a bit of hyperbole, replacing the swear words with crap like “bullpoppy”, then clicking submit. And then re-opening the post and editing out all the spelling mistakes and adding in the links and images I meant to include in the original. Proofreading and preview buttons are for wimps!
But at this very moment my brain is giving me no prompts whatsoever, hense the above pointless and time-wasting sentence. What on earth am I going to write about?
Well, at this point in the saga, I have a working (albeit basic and rather buggy), simulation. Ummm…
Dammit writers block.
Dammit I just called myself a writer because I blog. Next thing you know I’ll be printing out business cards with this URL on them and adding “blogger” to my resume.
Okay, okay, let’s get serious. The first thing to do from this point in the games development was to expand and balance the selection pressures. But since this process is extensive, (so extensive it’s still ongoing, and shows no sign of letting up), and since I did a fairly pretentious post on it last time, let’s move on. I’ll be coming back to that topic sooner or later, there’s pretty much no way to avoid it, so no point in rushing it. Let’s talk about something else.
Hmm… I could do a post on performance and optimisation, but it’d come out all technical and I doubt too many people are interested. We’ll save it for later too.
Redundancy? I’ve touched upon the things that changed from the original design in other posts… but that’s pretty broad subject, maybe something more specific…
Oh, I know! Behavioral evolution.
HAHA TAKE THAT WRITERS BLOCK I AM AWESOME.
“Stuff possibly worth reading starts here.” -i
The original design called for an unbelievably complex and mutable behavioral system, that could theoretically evolve to handle any situation. I’ll try to give a summary of it, but when I say “complex” I don’t mean “Pythagoras’ Theorum” complex, I mean “7th dimensional trigonomcalculus in a rotating reference-frame” complex, and I’m pretty sure that doesn’t even make sense.
The basic idea was that every creature could have a list of Perception Categories, based on visable data like “size” and “number of teeth”, so they could distinguish between predators and prey. Each perception category would also include an action (flee, approach, attack, mate), which based on the theory would, over time, evolve to become appropriate to it’s category.
Using this system, any action could be combined with any object. So Attack!Creature and Eat!Vegetation were possible, but so was Flee!Vegetation and Eat!Creature. (Note: creatures can only be eaten after they’re killed, so this did nothing except maybe annoying the creature being chewed on).
I actually implemented a placeholder version of this system, and discovered it’s flaw: it made creatures stupid. The earliest creatures picked actions at random, and would spend a good 90% of their time doing nonsensical things. The ones that survived were the lucky but random few who managed to realise they were supposed to eat their food, not copulate with it (not that there’s anything wrong with that (sorry, couldn’t help myself)).
At first I thought this was okay: creatures would naturally evolve to be smarter. But it quickly became apparent that the randomness cause by their own stupidity was the only selection pressure worth talking about in the game: it was overwhelming all the visible effects.
In addition, it was impossible to monitor. Getting statistics out of this system was like milking a tiger snake: not as hard as it sounds, but all you’ll get is poison. And there’s also the possiblity of being bitten by a pissed-off, venemous reptile, though I’m not certain the analogy streches that far. But it was very, very hard to tell the difference between “intelligent” and “brain-damaged algae” simply by looking at the perception categories. It was definately impossible to glean any useful information at a glance, which was the way I wanted to set the statistical elements of the game up.
And if that wasn’t enough, it evolved slowly. Increasing the behavioural mutation rate didn’t make it evolve faster, it just meant that the immediate descendants of an intelligent creature might well be back to running away from the scary food and trying to mate with the giant toothy predator twice it’s size. And decreasing it meant you could wait for hours before seeing anything.
And yet… if the only thing I was going for was accuracy, I might well have hung onto this system. It’s not too bad at replicating the way behavioural evolution in reality works: we recognise patterns and have instinctual reactions to those patterns. But evolution in real life doesn’t happen over the course of minutes, like in Species. It takes era’s. So this system, which is actually quite fast compared to real-world physiological evolution, is extremely inefficient compared with the simplified version found in Species.
What I had unrealisingly done was put a real-world system into a simplified simulation.
But I’m not “only” going for accuracy: the dual design goals for the simulation in Species are accuracy and intuitive… err… ness? Okay that word sounds ridiculous and probably isn’t an actual word, but you know what I mean. I want to be able to see evolution happening in Species, which is difficult to do with complex behaviors.
So that lead to the current, much-simplified system. It’s not quite as versatile as the ridiculously complex system detailed above, but it’s versatile enough to allow mutable behaviour while still allowing the user to see at a glance how the creature’s instincts govern it’s decisions. It makes the creatures understandable and (relatively) predictable, which is a good thing…
The system consists of four main genetic variables:
– Curiosity/Cowardice: Determines a creatures reaction to other creatures in its line of sight. A high curiosity will cause this creature to approach, while a low one will cause this creature to flee.
– Aggression/Sociability: Determines a creatures reaction to reaching another creature. An Aggressive creature will attack: a Social creature will either “Play” (an action which still has no real effect, but I’m planning on adding one. Sooner or later. When I can think of an effect it should have) or Mate. Which of those it does is determined by…
– Amorosity/Asexuality: Amorous creatures will attempt to *ahem* “share genetic material” when approached by other creatures of the same species, while asexual creatures don’t. Since creatures are perfectly capable of reproducing by Parthenogenesis (cloning), it will be interesting to see whether sexual or asexual behaviour is the most viable within Species, or even if it changes depending on environment.
– Interest In Tree’s/Lack Thereof: a behavioural variable that I may end up simply combining with the “diet” variable, because a) it’s redundant (Carnivores have no reason to approach trees), and b) it sounds silly. Interest In Tree’s causes creatures to prioritise vegetation over creatures (or vice versa for low values).
A few other variables, like “Scariness” and “Decoration”, provide modifiers to these: (scariness makes other creatures less curious, decoration makes them more amorous, etc).
And that’s it. This behavioural system theoretically provides support for predator and prey relationships, herding behaviour, and sexual selection, while being simple enough to understand at a glance and to not overwhelm the more interesting (debatably), visible selection pressures.
It’s not perfect though, and I’m always open to suggestions. E-mail me, or drop a line in the comments section below, if you’ve got an idea for this or any other system in the game. 🙂
Yeah, I’ve totally given up on making the random screenshots at all relevant.
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…