[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Lua in a gaming environment
- From: David Morris-Oliveros <david.morrisoliveros@...>
- Date: Wed, 01 Mar 2006 09:38:54 +1100
Paul Du Bois wrote:
In our game, the dispatcher is written in C++. I handle both a
Preemptive and Cooperative multitasking within the same script. For
Cooperative, i have functions bound that call lua_yield on the
coroutine, and can either yield for X seconds or N frames (at a later
date, also yield until X condition). For preemptive, i use lua_hooks. I
break into C++ every N instructions, check to see if the quantum is up,
and yield if it is.
Is it possible to re-enter a script with a prior context so that the lua_State of
one function can be used as the lua_State of another?
Yes; read up on coroutines. For example, this is what we do in our
engine right now:
local fn = rawget(self, 'current_statefunc')
if fn then
local bSuccess, result = coroutine.resume(fn, self, dt)
if not bSuccess then
Tracef("Error running state '%s':\n%s", self.current_state, result)
if coroutine.status(fn) == "dead" then
self.current_statefunc = nil
onTick gets called every frame/update/whatever. Often, anyway. An
object can call self:setState() on itself, which among other things,
sets up a particular function to be resumed every tick. The function
runs to completion or until it yields. The net effect is a system
where every object can pretend it has its own thread of execution.
Almost all of our object/script system is implemented in lua at the
moment (a switch from Psychonauts, which did stack manipulation and a
bunch of other stuff). This is very nice, as it allows you to play
with various semantics and implementation strategies. When you have
something you like, you can "freeze" it into C/C++ if you like, and if
it's worth it.
I can switch between both runmodels in the same script, so, for example,
if block of script needs to execute atomically (as in, on the same
frame), i change the runmodel to cooperative, and then change it back to
An advantage of having this system is that I can pause a script, make it
start again, reload it, and kill it without a problem.
Also, an implementation note: in the cooperative runmodel, i also use
lua_Hook to make sure that the script doesn't do infinite loops and
freeze the game. If it executes without yielding for more than X time,
assert and then pause the script.
The concept of this was inspired by Matthew Harmon, from eV Interactive
Corporation, and was featured in Game Programming Gems 5.
Hope this helps.
// David Morris-Oliveros
// Camera & Lua Coder