Note: the following is written in-character by a different character than my usual in-character character because my usual in-character character was floating in space for a number of weeks. This also explains my recent absence both here and on the forums. I’m going to say the reason I was floating in space was because I required perfect isolation to hear the grim horrorwhispers of my eldritch masters, and not because I accidentally pressed the wrong button and vented the contents of my orbital lair into space. That would just be silly. Apropros of nothing, however, WHY DO WE EVEN HAVE THAT BUTTON?!
Moving on, this particular fictional in-character is May, my protégé, research assistant, unpaid minion and occasional test subject. My most sincere apologies for the lack of Cthulhu Mythos references and trendy internet colloquialisms. May considers memes to be frivolous and Lovecraft overrated. She is of course entitled to her opinions, just as I am entitled to extensively test the psychological effects of being buried in live octopuses while the top 100 most commonly used phrases on 4chan are shouted through a megaphone.
Hello all. We’ve had a minor… ‘incident’ involving your usual blogger, so I will be filling in on his behalf for a brief duration. I apologise for any differences in tone or content that may result from this, and thank you for your patience.
In the original design for the SeekFood routine it used a conventional Selector. Thus, a creature that prioritised Hunt would only fall back to an alternative, like Scavenge, if Hunt failed.
Due to a near-pathological failure on the part of the developer to think the consequences of their actions through, this design leads to a logical problem, briefly discussed in the previous post: there are cases where Hunt won’t actually fail, but is still an ineffective or illogical decision: for example, when a creature has a scavengable corpse in close proximity, but chooses instead to hunt a creature some distance away.
Solving this problem required a significant rewrite, and the complete removal of quite a large branch of the behavior tree: specifically, the FindClosestMatch routine mentioned in AI Rework – Behavior Tree Level 3.
As this removal effectively invalidates the last few blog posts of this series, I find it necessary to apologise to any reader who was expecting a coherent narrative to this series.
In the place of the FindClosestMatch routine, we were obliged to implement a different system, as shown below.
FindOptimalFoodSource ( Sequence ( ClearOptimalFoodSource(), PopulateLocalIEdibles(), CalculateOptimalityOfLocalIEdibles(), SortIEdibleListByOptimality(), StoreOptimalFoodSource() ) ) SeekFood ( Hunt(optimalFoodSource), Scavenge(optimalFoodSource), Browse(optimalFoodSource), Graze(optimalFoodSource), Wander(), )
This system involves some notable, complex changes, which I shall attempt to elucidate for your benefit. If you would prefer to avoid a somewhat technical discussion, feel free to skip to the conclusion.
IEdible is a C# Interface, a code constuct which serves to provide a ‘description’ of certain functionality within different classes that can be referenced in place of the objects themselves. Since both Creatures and TreeObjects are edible, they can both implement this interface, and can thus be stored in the same List object.
This allows us to sort all edible objects, rather than “all trees” or “all creatures”, and thus replace the type specific FindClosestTree and FindClosestCreature with a more generic FindClosestEdibleObject.
While an intriguing change, this isn’t exactly where we are headed with this rewrite. It’s merely an important middle-step before we implement the next major change.
This is the list of edible tree’s, corpses and creatures mentioned before. To prevent having to perform calculations on the entire list of them, it is populated when the creature requests it, filtering out the easily-eliminated options like objects that are too far away, creatures that are inactive and trees that are too large to reach.
This is the foundation of the new food seeking routine. Rather than simply looking at distance, creatures will attempt to logically determine what the most rational food source to approach is.
To sort the potential food sources from most-attractive to least-attractive, a creature generates an ‘optimality’ value for each. This value is measured in joules: it is literally a measure of how much energy a creature would gain from eating a particular food source, minus the energy cost of walking to the target and the damage cost of fighting it (if applicable).
These values are used relatively and are far from perfect, as the calculation doesn’t factor in the metabolism and climate costs associated with the time it takes to reach targets, that they may move, that the prey may flee rather than fight, that someone else might reach it first, or that it may be too much to eat in one sitting.
While it’s tempting to continue to develop the process until it acknowledges all the above factors, it’s easier on both the developer and the CPU to simply fudge the figures a little. This simply means the creature’s aren’t perfectly rational: much like biological organisms, they favor conclusions that can be reached rapidly: intuition over logic.
The end result of this process is that creatures will attempt to sate their hunger logically, by analysing their environment and selecting the food source that provides the best energy-to-cost ratio. This change should make the creatures far less prone to poor decisions than they were previously.
While there were a few haphazard starts involving the developer setting the sort order wrong (and thus creature’s attempting to make a meal out of the *worst* food source in their area, rather than the best), and the Movement Energy Cost being subtracted on a per-time basis rather than a per-distance one (a curious error that may well be affecting evolution in 0.7.0: since it means an increase in speed actually *reduces* the cost of travelling a set distance), these errors were merely due to the mechanical ineptitude of the developer, rather than any foundational design problem. After they were fixed, the solution was made to work.
It has a curious effect on the simulation, significantly reducing the percieved randomness of creature’s behavior and introducing noticable patterns of movement. Highly attractive food sources will draw in creatures from some distance away, like moths to a flame. In addition, creatures will opportunisitically hunt weakened members of the population. While children killing and eat their parents remains a problem with this new AI, the presense of sound logic behind this behavior (children are born hungry, and parents have a lot of biomass and are often weakened by pregnancy) makes it notably more interesting.
Thank you for continuing to read this blog despite, or perhaps because of, the demonstrable insanity of it’s author.
Holy crap those italics. Learn to close your tags May.
To make up for my absence, here is a highly-contagious mind-virus disguised as an extended Lovecraft reference.
That’s right. I know what my readers want.
“Uh, sir? I’m quite certain I don’t actually wish to know the answer, but… what exactly are you doing?”
“Wait, you’re not in the… aw crap. Have I been shouting 4chan memes at a tank full of octupi for 3 hours for nothing?”
“… yes. Yes, I believe you have.”