AI

This article is about the technical workings of the game. Readers without a technical background may not understand what is being said

In Banished the NPCs in the game have to do all manner of tasks. They’d live in houses, walk to their jobs, do the work, cut down a tree, go eat lunch, collect firewood, and go get a new shirt from the market.

All the things an AI can do is broken into simple core tasks, which are called ‘Actions’. These are tasks such as moving to a location, picking up an object, storing or retrieving something out of inventory, creating new objects, or playing animations.

The AI then maintains a queue of actions to complete. Lets say you want to get an AI to collect food from storage and bring it to their home. The code would look something like this:

// head to the storage facility or market
ai.AddAction(MoveTo(storageLocation, Animation_Walk));

// get something out of inventory and display it.
ai.AddAction(PlayAnimation(Animation_BendDown));
ai.AddAction(RetrieveFromStorage(storageLocation, foodType));
ai.AddAction(PlayAnimation(Animation_StandUp));

// go home
ai.AddAction(MoveTo(homeLocation, Animation_Walk));

// drop inventory
ai.AddAction(PlayAnimation(Animation_BendDown));
ai.AddAction(DepositInventory(homeLocation));
ai.AddAction(PlayAnimation(Animation_StandUp));

Each item in the queue is executed until it finishes - MoveTo completes when the AI gets to the target. PlayAnimation completes once the animation finishes. Other actions like DepositInventory execute immediately and the next action is run.

These chains of execution are called ‘Behaviors’. The game has a lot of different behaviors, from how to hunt animals, to how to work at a building and use one resource to make another resource. Adding new behaviors and actions is easy. You could make two people walk toward each other, play an animation and play audio that shows they’re talking to each other, then go about their business with just a few lines of code. (But I’d have to make the animation and audio first….)

AI Task Assignment

Each AI has a set of needs that may or many not be urgent. They might need to stock their home with food or firewood. They might be sick and need a doctor. They might be cold and need to go home and warm up, or hungry and need to eat. They might have low health and decide to visit an herbalist. They AI might be a child and depend on parents for keeping the home stocked.

In the best case all needs are met and the AI should just do some work so the town can prosper – if they have a specific profession and workplace this is easy – but if there is no work available they need to help around town with general labor.

The game employs state machines to assign tasks to the NPCs. There are different states of working versus attaining needs, and there are different versions of each of those for when an AI is a child, student or adult. Each time the action queue is empty, it signals the AI to make a new choice or change states based on needs.

The needs are prioritized based on severity – freezing to death is more important to take care of compared to getting a new tool. Deciding what job to work on is handled simply by ranking jobs based on urgency and distance from the AI.

Each state is simple. Here’s what the normal and attain needs states looks like:

void State_AdultWorking()
{
  // check to see if the ai is doing something
  if (IsBusy())
    return;

  // do more work, idle, or change state
  if (AreNeedsMet())
  {
    if (!GetNewTask())
      ChangeState(AdultIdle);
  }
  else
    ChangeState(AdultAttainNeeds);
}

void State_AdultAttainNeeds()
{
  if (IsBusy())
    return;

  if (AreNeedsMet())
    ChangeState(AdultWorking);
  else if (IsFreezing() && CanAttainWarmth())
    ChangeState(State_AttainWarmth);
  else if (IsSick() && CanAttainDoctor())
    ChangeState(State_AttainDoctor));
  else if (IsHungry() && CanAttainFood())
    ChangeState(State_AttainFood);
  else if (IsUnhealthy() && CanAttainHealth())
    ChangeState(State_AttainHealth);
  else if (!HasClothing() && CanAttainClothing())
    ChangeState(State_AttainClothing);
  else if (!HasTools() && CanAttainTools())
    ChangeState(State_AttainTools);
  .... // lots more needs omitted.
  else
    GetNewTask(); // couldn't attain any needs! try doing work instead, will retry later
}

This may not be real AI – it’s a conglomeration of state machines, fifos, priority queues, and a few conditionals. But magically when hundreds of AI’s are running the state machine and executing behaviors, it looks awesome and the town is alive with activity.

This system could easily be extended to give the AI’s more personality. There could be different states for lazy workers that idle more often than not, or people that won’t work when their health is low or if they have to walk too far. But at the moment everyone in Banished is a well behaved, hard-working citizen.


Need wiki hosting?

Do you need a wiki for your Minecraft mod/gaming wiki? We'll host it for free! Contact us.

Other wikis

Indie-game wikis
Powered by Indie Wikis
Looking for a server?

Join Techworld - an amazing custom modpack server.