Member-only story

Unity-like coroutines in plain old C

David Delassus
11 min readJul 13, 2024

--

Let’s just begin with this: Coroutines are great!

For those who don’t know what coroutines are, let me explain:

Coroutines allow a function to be paused and resumed. This is often used to allow the concurrent execution of multiple functions (and is often what is used to implement async / await in most programming languages), but in Game Development, they are also used to spread a long running function over multiple frames.

In the above screencast, clicking on the button “DAMAGE” sets the red bar (representing health) to a specific value, and triggers a coroutine that changes the value of the orange bar progressively over time.

In this article, we’ll see how to implement this in C.

In-depth explanation of coroutines

At its core, a coroutine can be modeled as a state machine:

typedef enum {
CORO_SUSPENDED,
CORO_COMPLETED
} coro_state;

coro_state my_coroutine(void) {
static int state = 0;

switch (state) {
case 0:
printf("Step 1\n");
state = 1;
return CORO_SUSPENDED;

case 1:
printf("Step 2\n");
state = 2;
return CORO_SUSPENDED;

case 2:
default:
return CORO_COMPLETED;
}
}

int main(void) {
while (my_coroutine() != CORO_COMPLETED) {}

return 0;
}

There are 2 kinds of coroutines:

  • stackful: each coroutine has its own call stack independent from the main thread
  • stackless: each coroutine shares its call stack with the main thread

NB: The above example is a stackless coroutine.

The main advantage of stackful coroutines is that they can easily handle more complex control flows like recursion…

--

--

David Delassus
David Delassus

Written by David Delassus

CEO & Co-Founder at Link Society

No responses yet

Write a response