Eating in C3 critters is a special state which allows them to keep living, and is a multi-step process beginning with low energy triggering the search, searching for food, finding food and hunting for food.
The normal logic flow in the timer script
Typically, getting food is switched on by OV00 (State) being 1, and it is the first step in the normal logic flow in the timer of most C3 critters - which typically follows this pattern:
- increase age
- decrease energy
- if old enough, increase sex drive
- drown in water - lose energy rapidly
- if low on energy (sometimes also OR if too old) flag for death
- if hungry flag to get food
- if sex drive high, flag to mate
- obstacle checking - sometimes also water-shyness
- if flagged for death go to die subroutine
- if flagged to get food, get food
- if flagged to mate, mate
- if flagged to roam, roam
The logic flow in the timer script being arranged around two phases - first flagging, then checking the flags - is an example of a behaviour tree. This has the benefits of avoiding conflicts in behaviour, creating a predictable flow, allowing for lifelike complexity (flagging for multiple behaviours allows the system to choose between them with DOIF logic), while being performance friendly.
The gfod
Subroutine: Your Critter’s Inner Forager
When it’s time to eat, the gfod
(get food) subroutine takes over. It’s more than a simple “go to food” instruction—gfod
is a nest of smaller routines: find
, hunt
, vect
, anim
, and move
, all working together to give your critter a believable foraging pattern, while avoiding the common coding error of repeating yourself.
Let’s walk through the full food-finding journey:
Step 0.5: The Critter Gets Hungry
Every time the timer runs, the critter’s energy (OV02
) drops by 1. If it falls below the hunger threshold (typically stored in another variable, OV73
), the critter flags itself as needing food—and gfod
is called into action.
Step 1: gfod
— Search Phase Begins
This is where the critter starts searching for food:
-
Temporary variables (
VA47
,VA48
,VA49
) define what kind of food it’s looking for—based on family, genus, and species. A0
means “any”. -
If there’s already a food target saved in
OV16
, the critter jumps straight to hunting it withhunt
. -
Otherwise, it calls the
find
subroutine to scout for the nearest edible object.
Bonus: Some critters, like hedgehogs, have varied diets—gfod
can be expanded to look for secondary food types if the favourite isn’t found. (Just be careful they don’t accidentally target themselves if the critter is looking for its own genus in general.)
Step 2: find
— Locating the Nearest Snack
In this subroutine, the critter:
-
First sets up a temporary variable to hold a massive number (
VA99 = 99999999
) and then changes that to be the shortest distance found from a target food item (VA58)
. -
Scans nearby objects using
esee
, filtering by the desired food types. -
Calculates the squared distance to each object with the Pythagorean theorem.
-
If something closer is found, it updates the new, closer target (
VA58
) and setsOV16
accordingly. -
If nothing is found, the critter gives up—for now—and sets the target to null before changing its direction.
Step 3: hunt
— Move to Target and Eat
Once a target is locked in, the critter enters hunting mode:
-
It checks that the target (
OV16
) is still valid and hasn't disappeared. -
It figures out the direction to move by comparing its own coordinates with the target’s, adjusting movement vectors (
OV10
andOV11
) accordingly. -
When it reaches the target—touching it—the critter switches its state to the next one in the main logic's behaviour tree and tells the food it’s been eaten (
mesg writ OV16 12)
and adjusts its own energy. (targ ownr subv ov02 ov72)
Ants behave a bit differently here: instead of eating on the spot, they pick up the food (OV18
tracks the carried food) and head back to the nest, with a message (mesg writ OV16 4
) sent to the food to signal collection.
Step 4. Return to roaming
The critter reuses a little roaming behaviour after it has been hungry, got food, found food, and hunted food successfully to randomly change direction and start moving - and the behaviour tree will continue on with other activities.
Conclusion: A Background Mechanic With Quiet Complexity
While critters eating is a simple background function in Creatures 3, it's a surprisingly intricate part of what keeps critters behaving believably. From hunger detection to food targeting and pursuit, the eating system is built with clear logic, modular structure, and enough flexibility to support varied diets, differences between critters, and environmental challenges.
It’s not flashy, and it rarely calls attention to itself if it's done well—but it quietly supports the broader simulation and creates a vibrant world for creatures to live in. By using a behaviour tree model, flag-based decisions, and reusable subroutines, the developers created a system for critters that’s both efficient and extensible.
Understanding how critters eat offers a window into how even the “invisible” mechanics in Creatures 3 are carefully crafted. It’s a reminder that beneath the surface of every lifelike action is a system designed to keep the world moving.
Moving on
- For a practical coding tutorial for beginners on this topic, see Ghosthande's Hungry Critter Tutorial.
No comments:
Post a Comment