Activities and the control of time

The three types of activities

From the developer's point of view, KuteEngine is all about activities. These are snippets of instructions that interface with the engine. Inside Unity they are currently C# scripts, though you'll be able to use visual scripting to create them in the future (similar to Blueprints in UE5).

Activities define what your character does over it's lifecycle. They can target specific body domains and thereby run in parallel. For example, one activity can handle the root domain, another the upper body and a third one the head.

Activities make extensive use of the engine API, which takes away much of the pain of creating complex, highly controllable interactive characters. They come in three main flavors.

Root and child activities

First up are root activities (RAs). These are generally tied to one of the core motives of a virtual being: patroling (for a guard), playing (for a dog), eating, socializing, exploring, and so on.

Root activities can have child activities (CAs), which in turn can have further children, and so on. Child activities of patrolling might for example define how to explore the surroundings, enter and inspect buildings, and more.

Service activities

When you look closely, you'll find that a lot of the things that virtual beings (and even real beings!) do fall into categories. This includes, in no particular order:

  • walking from A to B,

  • looking around,

  • breathing visibly,

  • expressing emotions,

  • blinking one's eyes,

  • talking,

  • gesturing while talking,

  • and much, much more.

Such behaviors can be abstracted out into service activities (SAs). We provide many SAs as part of the engine to make your life easier.

Activities as LEGO® bricks

KuteEngine uses SAs everywhere. In fact, whenever you want to get you character to actually 'do something' from within an RA or CA - like walking, looking, or grabbing things - you need to pass by a service activity. This illustrates a core design principle of the engine: composability.

"Composability is a software development concept describing the ability to combine components to create products and systems. Like legos stacked on top of each other to create new things from existing building blocks, software elements stack on top of each other to create new applications and uses." (Source)

This is best illustrated with a concrete example. Consider how RA Patrol from above might look like at runtime. In a very typical scenario, it would launch a few basic SAs such as Breathing, and then go on to run its CAs in sequence. Those would in turn launch more SAs, and optionally run their own sequence of children.

While CAs are often specific to their parent and therefore not very reusable, SAs are designed for flexible reuse in many different situations. They expose parameters and methods that allow their users to adapt them to their needs. And they're often composed from multiple SAs themselves.

Controlling time

The two types of time

We already mentioned the 12 principles of behavior. Here we want to take a closer look at four of them: behavior as sequenced (#5) and displaying patterned variation (#7) versus behavior as responsive (#3) and interruptible (#6). They pull in opposite directions, leading to two very different conceptions of time.

  1. Sequential time. A lot of what creatures do is ordered over time, from fancy behaviors like dancing to trivial ones such as brushing one's teeth. These arrangements require that many small actions are carried out in a certain order. Of course the sequence is never exactly the same and can include branching and other variations, but the overall patterns remains recognizable.

  2. Responsive time. On the other hand, some of the things creatures do are caused by things that happen to them, either external events (someone calls you and you turn around) or internal ones (you just remembered a joke and smile).

Activities are designed to handle both types of time elegantly. The primitives offered for that purpose are suspenders and monitors. Instead of explaining them in the abstract here, take a look at their engine-specific implementation in the sub-pages.

Last updated