Starmancer is currently live on Kickstarter. If you want to pre-order the game or support development, you can do so here.
This blog is all about colonists and the basics of their A.I.
There won't be very many visuals, and it's only interesting if you want a technical understanding of how colonists work.
At the lowest level, we call the things that colonists do "actions". The term itself is somewhat arbitrary, but it's what we call them.
Actions have 2 results: success or fail. They can optionally have an action that is performed when they succeed or fail.
The chaining would look something like this.
Actions include things like: "Sit in Chair", "Pick up Resource", and "Wake Up".
By themselves, actions are largely useless.
A collection of actions is a "State" (again, these are just our own terms).
States include things like: "Go to Object", "Move Crates", and "Go to Bed"
Internally, states are actually actions, so a state could be composed of a number of substates.
The end goal is for modders to easily create their own states by using the existing actions.
Here is a simplified diagram of how colonists use the bathroom
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
- Stand Up
"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
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.
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).
- Job Normal
- Job Urgent
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.
To solve this issue, we use "categories".
The current categories are:
- Free Time
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 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).
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:
- Colonist goes to shelf
- Picks up wheat
- Goes to recycler
- Drops off wheat
Once again: Starmancer is currently live on Kickstarter. If you want to pre-order the game or support development, you can do so here.