When it comes to parallelism, most programmers immediately remember multithreading or asynchrony. But Lua has its own unique tool — coroutines. They allow you to write code as if you have multiple threads, while remaining inside a single execution thread.
Coroutines are light "streams", which can be paused and resumed manually.
Unlike conventional functions that are executed from start to finish, a coroutine can:
stop in the middle of the execution,
return control to the calling code,
and then continue working from the same place.
It's like a pause in the game 🎮: you saved the state, and then you calmly continued from the same moment.

Example of a coroutine in Lua
function worker()
for i = 1, 3 do
print("Step " .. i)
coroutine.yield() -- приостанавливаемся
end
end
co = coroutine.create(worker)
coroutine.resume(co) --> Шаг 1
coroutine.resume(co) --> Шаг 2
coroutine.resume(co) --> Шаг 3
Analysis:
coroutine.create— creates a coroutine.coroutine.resume— starts or continues it.coroutine.yield— pauses execution.
How do coroutines differ from streams?
Threads | Coroutines |
|---|---|
Managed by OS | Managed by Lua itself |
Can be performed in parallel | Performed only one after the other |
Difficult to debug | Simple and predictable |
Require data protection (mutex, lock) | Safe, as there is no real parallelism |
Where are coroutines useful?
Games and animations — step-by-step scripts without nested if and timers.
Asynchronous tasks — network requests, event processing.
Scripts — a simple description of the behavior of NPCs or bots.
A small example for the game
function npc()
print("NPC: I'm coming...")
coroutine.yield()
print("NPC: I stopped...")
coroutine.yield()
print("NPC: I'm coming again!")
end
co = coroutine.create(npc)
coroutine.resume(co) -- NPC: Я иду...
coroutine.resume(co) -- NPC: Я остановился...
coroutine.resume(co) -- NPC: Я снова иду!
Instead of complex logic, a simple script, as if you were writing a mini-theater for objects.
Total
Coroutines in Lua are not multithreading, but an easy way to simulate parallel execution. They are ideal for games, network applications, and scenarios where control over the order of actions is important.
If you are learning Lua, be sure to play with coroutines. This can greatly simplify your architecture. code interesting courses with Lua tasks.
And we also have an active Telegram channel, where we discuss cool ideas, share experiences and analyze tasks together — learning becomes not only useful, but also fun.
