Sunday, 18 May 2025

Roaming in C3 critters

 Roaming in C3 critters is almost considered an 'else' state after everything else is handled - it is a normal state that critters return to as a default behaviour.  But roaming isn’t just filler—it’s an integral part of the critter's behaviour tree that ensures believable, conflict-free, and performance-friendly actions.

The normal logic flow in the timer script

 Typically, roaming is switched on by OV00 (State) being 0, and it is considered the last 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 

You’ll notice roaming comes last—it’s what a critter does when it’s not busy trying to survive, eat, mate, or die. Think of it as a "what now?" behaviour that kicks in when all else is calm.

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.

Before you move

Navigating the World: How Obstacle Checking Works

In a world full of walls, slopes, water, and other creatures, critters need a way to avoid running headfirst into trouble. That’s where obstacle checking comes into the timer's logic flow—just before the critter decides what to do next, and crucially, before it performs any roaming behaviour.

Obstacle checking happens between flagging and acting. This allows the critter to alter or cancel its next intended action if something is physically in the way, preventing it from trying to move through a wall.

Direction Memory: How Critters Know Where They're Going

It's also important to understand how a critter "remembers" which direction it's trying to go in. This is usually done using two object variables:

  • OV10 – Stores the left/right movement direction

  • OV11 – Stores the up/down movement direction

These values help the critter maintain consistent direction between ticks of the timer script—even if it gets distracted or interrupted (say, by a curious Norn picking it up). They’re essential to making movement look fluid and purposeful.

Roaming: More Than Just Wandering

The roaming subroutine itself is built on a layered system of nested subroutines, creating lifelike complexity without chaos. The main roaming call includes:

  • subr roam

    • subr vect – Picks a random direction

    • subr anim – Sets the correct walking animations based on direction

    • subr move – Applies motion using direction data

By nesting logic like this, developers avoid redundancy and reduce bugs—especially those caused by copy-pasting the same code across multiple scripts.

Interestingly, even “special” behaviours like eating or mating briefly use the roaming-related nested subroutines vect anim and move. This helps reset the critter’s motion naturally, allowing it to continue behaving in a believable way after completing a focused task.

1. subr roam: The Control Hub

At the top of the roaming behaviour stack is the roam subroutine. Think of this as the orchestrator—it's the entry point that decides whether and how the critter should move.

The roam subroutine typically does three things:

  • Runs a random chance check: This is used to occasionally trigger special roaming behaviours specific to a species. For instance:

    • A hedgehog might randomly decide to burrow.

    • A grasshopper might chirp.

    • Other critters might sniff, pause, or perform ambient animations.

    These special behaviours give each critter type its own personality and make idle time feel alive.

  • Changes direction occasionally: Using another random roll, the roam routine may decide to alter the creature's current path, which keeps its motion from looking too linear or mechanical. 

  • Calls the three nested subroutines: Once direction and behaviour have been decided, roam hands off control to the nested logic for handling movement:

    • subr vect

    • subr anim

    • subr move

2. subr vect: Choosing a Direction

The vect subroutine is where direction gets set. This subroutine simply:

  • Picks a new random direction for the critter to head toward.

Because this direction change happens at the end of a completed behaviour cycle (e.g., after eating, mating, or completing a wander loop), the shift in direction feels natural and not abrupt.

The randomness is constrained enough that it avoids chaotic zig-zagging but ensures that the critter won’t pace in a straight line until it hits a wall.

3. subr anim: Choosing the Right Animation

Now that we know where the critter wants to go, it’s time to make it look like it’s going there. That’s where anim comes in.

This subroutine:

  • Selects the correct walking or movement animation based on the current direction (OV10, OV11).

  • Ensures that the visual feedback matches the movement intent—a critter moving left plays a "walk left" animation, and so on.

Animations in Creatures 3 are not just eye candy—they’re essential for readability and believability.  anim ensures the visuals reflect the internal logic.

4. subr move: Making the Critter Move

Finally, move applies the logic that turns direction and intent into actual motion.

This subroutine:

  • Adjusts the values of OV10 and OV11, moderating the direction based on the new vector chosen in vect.

  • Calculates the velocity the critter should move at.

  • Applies motion by setting the velocity directly.

Where vect decides where to go, and anim decides how it looks, move is what actually causes the critter to move on-screen.

Together, these three nested subroutines called by roam allow each creature to wander its environment convincingly, which is why they are also called in the gfod and mate subroutines.

No comments:

Post a Comment