[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: RE: Game oriented usage of Lua?
- From: Bret Mogilefsky <mogul@...>
- Date: Thu, 27 May 1999 12:19:16 -0700
See comments below...
> -----Original Message-----
> From: Jeroen Janssen [mailto:email@example.com]
> Sent: Thursday, May 27, 1999 12:20 AM
> To: Multiple recipients of list
> Subject: RE: Game oriented usage of Lua?
> We currently have C++ classes that implemented a Run() and a
> HandleEvent(..) function. Lua is (at the moment) used to "setup" the
> synchronisation between gfx effects & music ( to construct CTasks &
> CEffects and call AddEvent functions). So our "main demo-code" is
> implemented in C++ and not in Lua (but that is mainly because of
> performance issues and the fact that we haven't got that much
> with lua & creating gfx effects yet - since I implemented my
> "iterate task"
> function in Lua I can also construct Tasks & Effects from Lua
> (providing a
> Run function)).
> Can I assume you use a similar form of Run & HandleEvent for
> your kind of
Not sure... We really don't do anything with callbacks other than get
changes in the state of the controls, and handle collisions. Yes, Lua is
responding to the controls on any given frame, but everything else that
happens is either called in that callback function or is taking place in one
of several cooperative tasks running next to it (most likely originally
spawned in BOOT()).
> When using lua this way, do you modify the state & properties
> (x,y,z pos,
> etc) of actors & objects directly from Lua, or do you add
> them in a list
> and have the renderer first update the world from the list?
> (or another
> way?) I'm trying to figure out what consequences it has if you take
> different approaches.
There are functions to get and set pretty much every attribute for an actor,
but generally you would call a WalkActorTo() function with a destination.
Before displaying the next frame, the engine plots a path to that point that
doesn't take the actor through walls, and sets some flags indicating that he
should be interpolating along that path toward his destination. The engine
keeps updating his position incrementally each frame until he either hits
his destination or StopActor() is called from Lua. However, there's nothing
preventing us from implementing this exact same behavior (updating his
position each frame) in Lua using the set/get functions... We just wanted
the scripters to not have to deal with such mundane details when possible.
There are also functions to set what animation an actor should fade to when
he walks forward, backward, etc.
> Does this also mean you have different kind of scripts?
> scripts bound to an
> Actor, or that load a new room,etc?
Yes, but they're called by Lua. For example, Lua might check to see if a
specific Actor has a function for doing a certain thing, and if he doesn't,
it won't call anything. For other more generic actor functions, we let the
"inheritance" handle things... We have a parent actor that all the other
actors point to, and that parent has default values for his talking color,
he walk speed, etc. as well as a few stub functions for common actor traits
and default implementations of walk(), etc. These can then be "overridden"
in the child actor, which we use quite frequently for going into the
inventory screens, etc. where your controls change entirely but it's still
valid to think of "walking" or similar movement keys. There's a default
implementation of say_line() that basically calls into the engine, but I
overrode it in a few places, particularly where Glottis sings the Rusty
Anchor song. In that case, the voice audio had been mixed in the music
audio file, so there were no corresponding voice files... In the case of no
audio files, the engine displays text on the screen. But in this case, I
wanted no text unless the user specified it in the preferences because the
audio was there, just coming from another place. I made a specific say_line
function for him, overriding the default he inherited, that does nothing in
the case that text subtitles were turned off, and otherwise puts up the text
for the line currently happening in the song (referenced by a table of
milliseconds vs. line). It was a big hack to get around this one place
where the lines were screwy, but thanks to the inheritance mechanism it
still felt natural to do it that way. (Now the lip-synching there, on the
other hand, was a much uglier task...) So the long and short of it is: Yes,
each *character* was a table in Lua with various functions of his own that
made sense in the game, as well as a handle to a generic unnamed *actor*
placeholder in the engine that would interpolate along paths, wear costumes,
and play animations. The engine couldn't tell who was Manny, Glottis, or
Meche (knowing them only at actor 1, actor 3, and actor 5) but the scripts
referred to them only by their names... Code that looked vaguely like this:
manny:say_line("Hijole! I'm gonna miss the poisoning!")
...was pretty commonplace, where shut_eyes() and slap_forehead() would be
Lua scripts telling the engine to flip the bitmap for his eyes and play the
animation for the slap, and default() just tells the engine to put that
actor's costume in it's default state. wait_for_actor() wraps one of those
cooperative tasking primitives, sleep(). As for changing rooms, there was a
script running in the background we called Cameraman that basically checked
each frame whether the selected character had crossed into camera box X, and
if that was the case would call the engine and tell it to change the render
to the view from camera X.
I hope people don't mind that this was so specific... I realize that many
people on this list are not interested in adventure game engine internals
and certainly haven't played Grim Fandango. But I'd like to hear how other
people have used Lua as well!