



So the colonist would rotate towards a vertex, and only once that was finished would it start to walk towards the vertex.

Saving Coroutine Progress

There's no immediate problems with that, until it comes time to save and load.

How do you save in some external file that a colonist has finished the first part of a coroutine and is now somewhere in the middle? And then how do you load that from a file and resume it appropriately?

I played around with a few ideas, but all of them were overly complicated. I could, for example, create coroutines with some sort of lookup and then save them by their unique key and identify them later when loading.

This also makes no mention of the trouble of saving and loading variables that were declared within the coroutine method.

Limiting Coroutines

I didn't have any good ideas for saving coroutines, so I decided that I would never use coroutines in any colonist AI actions. After all, actions are supposed to be the most basic unit of colonist action.

(Nested coroutines are allegedly bad for performance too)

I still needed a way to wait for a frame, though, so I created a specific action that would wait for single frame, called Action_WaitForFrame. This is the only action that currently has a coroutine.

As an interesting result, the current action of all colonists when saving is always WaitForFrame, because all other actions are performed immediately.

Restructuring Everything

I then had the fun task of breaking up all of the various coroutines in different actions and creating a bunch of new actions out of them.

The RotateTowards coroutine became its own action called RotateTowardsVertex, where a TargetVertex is passed.

In general, these coroutines became states that resembled the following pattern:

Do something Wait for frame Success finish

In case you were worrying, we can optionally pass in a max wait time, so that actions will fail if they take too long. The state GoToObject, for example, will fail if the colonist has to wait at a vertex for too long (this could happen if there's a traffic jam or if a door is broken).

Coroutines Aren't Evil

We could technically still use coroutines in actions. It's only the nested coroutines and local variables that are actually an issue. Actually, it's really only the local variables that are an issue.

For example, the RotateTowards could easily look something like: