Sunday, 4 May 2025

Hunger and Hunting in C3 Critters

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:

  1. increase age
  2. decrease energy
  3. if old enough, increase sex drive
  4. drown in water - lose energy rapidly
  5. if low on energy (sometimes also OR if too old) flag for death
  6. if hungry flag to get food
  7. if sex drive high, flag to mate
  8. obstacle checking - sometimes also water-shyness
  9. if flagged for death go to die subroutine
  10. if flagged to get food, get food
  11. if flagged to mate, mate
  12. 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. A 0 means “any”.

  • If there’s already a food target saved in OV16, the critter jumps straight to hunting it with hunt.

  • 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 sets OV16 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 and OV11) 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

No comments:

Post a Comment