It's fairly straightforward.

Find Bathroom (if none were found, fail, and requeue later) Go to Bathroom (if colonist failed on the route, wait and then find a new bathroom) Sit in Toilet Urinate Stand Up Success

"Go to bathroom" is actually its own state that is used when colonists have to go someplace. Almost every state involves the colonists going somewhere in the station.

Almost every state shares the same pattern:

Find Closest Object Go There Do Something

Queues

A collection of states composes a "queue".

Colonists always have a bunch of things that they want to do. If a colonist stopped everything just to use the bathroom or get food, nothing would ever get done.

Internally, colonists add all states to a queue. The code is something like:

colonist.QueueState(state, Priority.Needs, Category.Work)

Whenever a state finishes, the colonist starts the next one in the queue.

The order of states is determined by 2 things: Priority and Category.

Priority

Colonists care about some states more than others. For example, eating food is much more important than using the bathroom.

To ensure that colonists promptly keep themselves alive we have a priority system (from least important to most important).

Lowest Want_Normal Want_Urgent Job Normal Job Urgent Need_Normal Need_Urgent Highest

The rationale is fairly easy to see--needs are handled first, then jobs, then wants.

There's nothing forcing us to queue a state like "Eat Food" with a priority of Need. We could easily queue "Eat Food" with a priority of Want_Normal if a colonist isn't very hungry.

One inherent flaw of this system is that a colonist will always selfishly worry about his own needs even when he should be working.

Categories

To solve this issue, we use "categories".

The current categories are:

Nourishment Work Sleep Free Time Scared Any

Colonists have a schedule (that you can change however you want).

Throughout the day they're allowed to do different things. You wouldn't want your colonist to stop working in the middle of the day just to use the bathroom or get some food.

When morale is low, colonists replace the work category with free time.

There is an exception to this system, of course, and that's the "Any" category. States queued here can be performed at any time, regardless of schedule. A starving colonist would queue the "Eat Food" state as Need Urgent in the Any category. Otherwise a colonist would wait all day to eat something, and possibly die.

States can also be started immediately, interrupting the current state. A colonist would do this if a room lost oxygen or if they were being shot by pirates (among other things.)

Needs

Needs don't directly have anything to do with the fundamentals of colonist A.I, but they are very important for queueing states, so I'll briefly discuss them here (I'll probably have a future blog about needs).

Needs are things that colonists must routinely satisfy, or they die. Needs are things like hunger and thirst.

All needs are in the range 100 to 0. When a need reaches 0, something bad happens. Usually it's just a health impact (or death). In the case of the urinate need, colonists pee their pants (this prevents you from recycling the water they drank).

As need levels decrease, we queue states with various priorities.

So when hunger is at 75 we queue "Eat Food" as Want_Normal in the Nourishment category. Once it's at 25, we queue it as Need_Urgent in the Any Category (I'm making up these exact values).

When the same state is queued multiple time, the lower priority one is removed from the queue. This prevents the colonist from eating multiple times (once as Need_Urgent and again as Want_Normal).

Summary

To summarize:

Colonists have a schedule throughout the day. They'll perform states that are relevant to their current category. They always perform the most important state first.

States are a chain of actions.

Actions are the simplest unit of "thing" that the colonists can do.

Here's an example: