Game oriented usage of Lua?

classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Game oriented usage of Lua?

Jeroen Janssen
I was wondering what the most/best used method of using Lua in a game
engine is/could be.

do you call several lua scripts & functions from C/C++ when entering a
specific gamestate?  (thus C/C++ contains you "main-game-loop")

or do you call a lua script that implements a "main-game-loop" (calling Lua
& C/C++ functions in the progress when entering a gamestate)

how far is lua being customized? :

do you use lua "out-of-the-box" or do you add specific features to lua not
available in the normal distributions 
(i.e. I know that Grim Fandanga adds some form of tasks to the lua language).

and how about maintaing different lua states? multithreading?

Best regards,

Jeroen Janssen



Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Luiz Henrique de Figueiredo
>From [hidden email] Wed May 26 12:12:28 1999
>
>Lua people: The docs say that functions are considered data, as integers
>for example. This means if I write something like:
>
>a={}
>a.b=function(a)
>  ...
>end
>
>and then write a.b=nil, will the function be garbage collected ?

Yes, definitely.
All constants (strings, other functions) used in that function will also be
collected.
--lhf

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Vincent PENQUERC'H
> do you call several lua scripts & functions from C/C++ when entering a
> specific gamestate?  (thus C/C++ contains you "main-game-loop")
> 
> or do you call a lua script that implements a 
> "main-game-loop" (calling Lua
> & C/C++ functions in the progress when entering a gamestate)


Personnaly (since I had an already working base), I have a C++ main
loop that calls Lua functions at defined times (when a character (in the
sense of a person) has to 'think' for example). The Lua function is
part of a table representing the character along with other functions
and data (like a C++ object). This tables has a few entry points: think,
call_me_when_someone_talks_to_me, call_me_when_i_am_attacked, etc.
These functions then have a set of C functions they can call as basic
blocks (find a path to there, say that to this person, etc...).
The only concern left is the problem of memory: This approach does not
use the nice 'I load a 'dialog' data file, search it to know what to
answer the player, then free it when it's over).

Lua people: The docs say that functions are considered data, as integers
for example. This means if I write something like:

a={}
a.b=function(a)
  ...
end

and then write a.b=nil, will the function be garbage collected ?


Vincent Penquerc'h

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
 >> Hope you enjoyed reading as much as I enjoyed sharing...

   At least as much!  :-)

   One of the design decisions I was wrestling with was "who keeps the main
'state' variable"?  In other words, should the host program try to maintain
state and call into Lua for specific discrete "events", or should every
frame update call into a more general Lua-based "director" routine and let
game-state be managed completely in Lua.  I was leaning towards the former,
you've taken the latter -- that at least opens up new "proven"
possibilities for me.  (will have to wait and see which is better for this
particular implementation)

   Some of that indecision may just be "cold feet" about entrusting TOO
much control to the scripting language.  However, I can actually foresee a
condition where I eventually prefer the Lua-side of things MORE than the
host-language engine stuff, so this balance may shift.  <grin>

   Again, thanks so much, very enlightening.  :)

   Cheers,

   Dave

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Bret Mogilefsky
In reply to this post by Jeroen Janssen
Yeah, I don't see a problem with directing control from Lua, though some
would argue that it makes it harder to debug the game as a whole.  The idea
that the engine is just a collection of functions and it takes Lua to make
them meaningful is very interesting to me.  I'd thought about what it would
take to make a Unix shell replacement out of the Lua interpreter, just for
laughs, and it didn't seem too far-fetched.  So the same way you'd run a
perl script, you could run a Lua script, only the interpreter contains all
of your custom primitives.  (Of course, this is really possible with any
language, particularly perl and python... But since I'm using Lua for the
actual game anyway...)  Then I thought about giving the engine itself the
same command-line semantics as the interpreter, opening up the possibility
of having one general-purpose body of code that gets compiled for the game,
but also gets used for writing batch processing tools to operate on the
data, all in Lua.  That seemed excessive in this case, but I can see even
much smaller cases where it might be useful to think of things that way.
It's not much different really from what the engine does now... It's just
that the specific file of Lua code and function to be called are arbitrary
and can be set from the command line, and are not expected to launch the
game into the main loop.  

Hokey smokes, Bullwinkle, if my BOOT() function actually did work instead of
spawning off sub-tasks, the engine would quit when BOOT returned and no
tasks were running and I'd have this functionality as is!  Crazy stuff...
Geez, maybe I should leak those cheats!

Bret
-----Original Message-----
From: Dave Bollinger [[hidden email]]
Sent: Wednesday, May 26, 1999 6:28 PM
To: Multiple recipients of list
Subject: RE: Game oriented usage of Lua?


 >> Hope you enjoyed reading as much as I enjoyed sharing...

   At least as much!  :-)

   One of the design decisions I was wrestling with was "who keeps the main
'state' variable"?  In other words, should the host program try to maintain
state and call into Lua for specific discrete "events", or should every
frame update call into a more general Lua-based "director" routine and let
game-state be managed completely in Lua.  I was leaning towards the former,
you've taken the latter -- that at least opens up new "proven"
possibilities for me.  (will have to wait and see which is better for this
particular implementation)

   Some of that indecision may just be "cold feet" about entrusting TOO
much control to the scripting language.  However, I can actually foresee a
condition where I eventually prefer the Lua-side of things MORE than the
host-language engine stuff, so this balance may shift.  <grin>

   Again, thanks so much, very enlightening.  :)

   Cheers,

   Dave

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
 >> though some would argue that it makes it harder to debug

   Yep, this potential drawback of all scripting languages was just pointed
out to me in another forum.  But that's OK, I had already planned to do
some of my own reinventing of the debugger wheel.  In fact, one of my
wishlist criteria for a scriplang was good debugging hooks and enough
"introspective" abilities to do something like a watch window.
   Perhaps the "patch at run time" ability also makes up for part of it.  I
had implemented the same type thing with a Scheme interpreter a while ago,
simply pop up an "Immediate" window and redefine the offending function
(cut/paste/modify/eval).  I'm looking forward to that ability with Lua as
well.

 >> but also gets used for writing batch processing tools to operate on the
data

   Have you perused the "Abuse" LISP source?  They're doing this kind of
wacky stuff:  like building the game engine with LISP scripts which are
interpreted by the game engine itself.  <grin>  It really blurs the lines
between shell and game.

 >> if my BOOT() function actually did work 

   Go on... take it to its logical extreme:  bind with something like tkLua
for the windowing functions, and your custom game routines, and you can
make Lua the "host" program!  That way you can turn your shell interpreter
into the game itself!  (Flipping the paradigm from "C as host, Lua as
extension" that us games types probably tend to think about, to the "Lua as
host, C as extension" model typical of shell programming.  More a trick of
perception than reality, though, since Lua is still "really" the embedded
language.)

 >> Geez, maybe I should leak those cheats!

   Er, you're trying to keep yourself from getting fired, remember?  ;-)


   Status report:  Finally bit the bullet and launched MSVC5.  (been
playing with Lua on AIX so far)  Awk'd and manually hacked together a quick
.def file for the main API and built myself a DLL.  Geesh, no problem at
all!  :->  Still have to try it with full errors/warnings on, and integrate
the optional libraries, and investigate that external state variable, but
the DLL works!  :->  Then, just to torture it, I wrote a minimal import
spec for Delphi (pascal) and called the DLL from there, made a little
expression evaluator via lua_dostring, and everything worked yet again! 
:->
   Ok, my cheeks are getting sore from smiling so much, I'm going to stop
now.

   Anyone here care to share any other already-known "gotchas" with the DLL
approach?


   Cheers,

   Dave


Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Jeroen Janssen
At 15:51 5/26/99 -0300, you wrote:
>screen the next day.  There was still something missing that we'd enjoyed in
>SCUMM however, and that was cooperative multitasking.  In an adventure game,
>it's very nice to have a separate script running that makes pigeons fly
>around, makes another character follow you, or that looks for opportunities
>to change the camera angle.  We could do all that via callbacks, but that

I've been working on a demosystem since 1997 and I also use a cooperative
multitasking system (since it was originally designed for dos and we had to
do the multitasking ourselves - we ported it to Windows in a sunday
afternoon since we used a lot of publicly available (portable) libraries
for both music & gfx). 

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 experience
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
scripts?

>function returns, the engine enters it's main loop:  Render the world, then
>call lua_updatetasks().  This was the API function I added that iterates

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.

>plays animations.  It only calls explicit Lua functions for a few things,
>notably changes in the state of the controls and when actors collide.  It

Does this also mean you have different kind of scripts? scripts bound to an
Actor, or that load a new room,etc?

>Hope you enjoyed reading as much as I enjoyed sharing... 


I did, actually I found it very interesting when I first heared that Lua
was used in GF. I had been experimenting with Lua a few months before and
now that I also heared about Baldur's Gate using Lua, I get the feeling
that Lua is becoming a 'general accepted game scripting language' and that
gives me confidence that I'll also be able to use it for my purposes.

Best regards,

Jeroen Janssen

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Jeroen Janssen
In reply to this post by Dave Bollinger
At 02:05 5/27/99 -0300, you wrote:
> >> Geez, maybe I should leak those cheats!
>
>   Er, you're trying to keep yourself from getting fired, remember?  ;-)

yeah, it's very nice to know that GF uses Lua, but to much details can
spoil things :)


>   Status report:  Finally bit the bullet and launched MSVC5.  (been
>playing with Lua on AIX so far)  Awk'd and manually hacked together a quick
>.def file for the main API and built myself a DLL.  Geesh, no problem at

ah... I edited the .H files and added :

#ifdef LUA_EXPORTS
#define LUA_API __declspec(dllexport)
#else
#define LUA_API __declspec(dllimport)
#endif

and then befor every function and external variable I added

LUA_API

Next I created a dl project and added the necessary source files and
compiled the thing.

>all!  :->  Still have to try it with full errors/warnings on, and integrate
>the optional libraries, and investigate that external state variable, but
>the DLL works!  :->  Then, just to torture it, I wrote a minimal import
>spec for Delphi (pascal) and called the DLL from there, made a little
>expression evaluator via lua_dostring, and everything worked yet again! 

are u using Delphi for a specific reason? 

>   Ok, my cheeks are getting sore from smiling so much, I'm going to stop
>now.

:)

>   Anyone here care to share any other already-known "gotchas" with the DLL
>approach?

well, what DLL approach do you mean? having Lua in a DLL or having plugins
in a DLL?

best regards,

Jeroen Janssen

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Bret Mogilefsky
In reply to this post by Jeroen Janssen
See comments below...

> -----Original Message-----
> From: Jeroen Janssen [[hidden email]]
> 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 
> experience
> 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
> scripts?

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!")
	manny:shut_eyes()
	manny:slap_forehead()
	wait_for_actor(manny)
	manny:default()

...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!

Bret

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
 >> but to much details can spoil things :)

   Oh, I'd love to have his cheat code that opened up a script interpreter
window for GF, just THINK of the trouble I could get myself into!  <grin> 
But I don't think it'd be wise for Bret to leak it.

 >> and then befor every function and external variable I added LUA_API

   I guess it's half-a-dozen of one, 6 of the other:  decl or def. 
Maintaining a .DEF can be some work, but modifying the source can be as
much.  I'd prefer not to modify the source _at all_ if I can get away with
it.  That way my work is greatly reduced if the official 3.2 is released
during my development.
   By the way, just for general reference, here's the hack awk script I
used to def the headers in case someone else can benefit from it:

   <-- cut here -->
   BEGIN { print "LIBRARY LUA\nEXPORTS" }
   /^(int|void|char|double|long|lua_)/ {
     gsub("\\\*","",$2)
     if ($2 ~ "\\\(") $2 = substr($2,0,match($2,"\\\(")-1)
     if ($2 != "") print "   " $2
     }
   <-- cut here -->

   (spaces inserted at head of lines to hopefully prevent any mail
mangling)

   I named it "h2def.awk" so my command-line was "awk -f h2def.awk *.h
>lua.def".  It is _not_ a general purpose tool, but it did work on the Lua
include files due to their consistent formatting.

 >> are u using Delphi for a specific reason? 

   Because I'm no good with MFC?  <grin>  Seriously, I consider myself a
capable C programmer, but I've never had much exposure to the MFC, and for
tools/utilities stuff that need a lot of user interface stuff I'm about 1K
times more productive with Delphi.  So if I'm to use Lua I'd like to be
able to use it EVERYWHERE!  :-)

 >> having Lua in a DLL or having plugins in a DLL?

   Having Lua in a DLL.  Specifically:  sometimes with wrapping something
up into a DLL you have to write a few custom initializing/finalizing type
things to get it all working right.  Or you have to write wrapper functions
to expose certain variables and such.  I haven't yet found any such
problems with Lua, but I'm still new to it, so was wondering if anyone else
had encountered anything like that.
   Does it work having _both_ Lua and library extensions in DLL's?  (not
that I'm likely to do that, probably just Lua in DLL extensions static in
host app, but I'm curious)

   Cheers,

   Dave

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Bret Mogilefsky
In reply to this post by Jeroen Janssen
> -----Original Message-----
> From: Dave Bollinger [[hidden email]]
> Sent: Thursday, May 27, 1999 6:08 PM
> To: Multiple recipients of list
> Subject: RE: Game oriented usage of Lua?
>    Does it work having _both_ Lua and library extensions in 
> DLL's?  (not
> that I'm likely to do that, probably just Lua in DLL 
> extensions static in
> host app, but I'm curious)

Yes, it works.  I put Lua in a .DLL, then link my C++ Builder app (Borland's
C++-instead-of-OOPascal Delphi), which is contained in a .DLL, to the
linking lib.  Then I link my main app (in MSVC) to the linking libs for both
of them.  Voila!  They all share the same process space so there's no danger
of two "instances" of Lua.  You can even load up the tool .DLL explicitly
rather than linking to it... I did that with our tools so I could take them
out at ship time.

Bret

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Jeroen Janssen
In reply to this post by Dave Bollinger
At 22:07 5/27/99 -0300, you wrote:
> >> having Lua in a DLL or having plugins in a DLL?
>
>   Having Lua in a DLL.  Specifically:  sometimes with wrapping something
>up into a DLL you have to write a few custom initializing/finalizing type
>things to get it all working right.  Or you have to write wrapper functions
>to expose certain variables and such.  I haven't yet found any such
>problems with Lua, but I'm still new to it, so was wondering if anyone else
>had encountered anything like that.

well, I think this probably would be a concern if you are using multiple
threads that access certain functions & variables, but if you have a single
thread (your main application) I don't think it should be a problem (I
haven't found any yet).

>   Does it work having _both_ Lua and library extensions in DLL's?  (not
>that I'm likely to do that, probably just Lua in DLL extensions static in
>host app, but I'm curious)

sure, there is a lua addon called loadlib that can load dll's from Lua. 

You could link a dll with the import lib of lua and then in the DllMain you
could set global lua functions,etc. This way a lua script can be used to
'configure' the extension to be loaded. I did some small tests and I have
got it working with a public available module player dll (MIDAS). I load
lmidas.dll from lua (lue glue for midas.dll) and lmidas.dll is linked with
the import dll of midas. After I load lmidas.dll from lua I have access to
several MIDAS functions that allow loading/unloading/playing/stopping of
modules from lua. Only problem I currently have is the things that could
happen if I wanted to unload lmidas.dll (the lua glue code for midas
wouldn't be available anymore,etc)

Jeroen

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Jeroen Janssen
In reply to this post by Jeroen Janssen
At 22:44 5/27/99 -0300, you wrote:
>of two "instances" of Lua.  You can even load up the tool .DLL explicitly
>rather than linking to it... I did that with our tools so I could take them
>out at ship time.

ah... you could also put all your cheat code in a seperate dll (and don't
ship it ofcourse)

well that's another advantage of using runtime loading of dlls. also the
fact that if you need to "fix" things you would be able to install a few
new dlls instead of having a 4 MB executable that needs to be distributed
(as in the Baldur's Gate patch).

btw... Bret, are you currently working on a game? (very offtopic I know)

Jeroen

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Jeroen Janssen
In reply to this post by Jeroen Janssen
At 16:21 5/27/99 -0300, you wrote:
>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()).

ah.. that's sort of having a Run() function of a task implemented in Lua
instead of in C/C++.

>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.

yeah.. I get it, it makes a lot of sence do to it that way if you're using
an animation engine :)

>actor's costume in it's default state.  wait_for_actor() wraps one of those
>cooperative tasking primitives, sleep().  

sort of a wait until animation is finished thing?

>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!

well, next to the fact that I loved GF and have a interest in adventure
game engine internals :) I think there are probably several things that are
also more game general things (specially the way the game engine and lua
interact with eachother is very interesting). 

I'll reread all the things said some more, I'm glad you shined a light on
the way you make use of Lua.

also, if you would be doing another game (doesn't matter what kind of game
at the moment) would you be concidering lua if you have a need for a
scripting language?

>Bret


Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Vincent PENQUERC'H
In reply to this post by Jeroen Janssen
> 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!

I'm new to Lua, and thus I may not have taken the best path, but
here is the way I used it:
I have several 'entities' in my game, most of them are items
or characters. Each of them, when created, creates a Lua table
representing it.
This table is composed of data and function fields. The only
data field known to C++ is set at the object construction, and
is the 'owner' field, initialized to the C++ pointer to the
object (a Lua userdata). All other data fields are left to the
use of Lua scipts.
The functions depend on the type of table. For a character, for
example, several functions are predefined and have special
meaning for the C++ game engine: 'onthink', 'ontalk', 'onhit',
'ondeath', etc... Whenever something happens which correspdonds
to one of those, the function is called (if defined).
This way, default behavior is executed if the function is not
defined in the table, and it can be overriden by defining the
function.
for example, 'onthink' is called regularly for a character to
determine which actions are to be taken by it.
The default behavior, if no 'onthink' function is defined in its
table, is to stay immobile, and to fight if attacked, etc. But
if the function is defined, the default behavior is not executed
(or it can be by being explicitely called by this override, as a
kind of inheritance) and the specific 'onthink' function is exevuted
in its place.
This set of predefined Lua table functions have at hand a set of
registered C functions that access everything's necessary
(examples include CharFindPathTo, CharFindPathAround, CharAttack,
CharSay, CharStopMoving, CharGetInventory, etc...). some of these
basic bricks are very low level (CharGetXPos) but my goal is to
write high level ones (CharScheduleActions(action1,action2...)
so that Lua functions has a broad range of powerful bricks to
use, thus making script writing quick and efficient.

Hope I did not put this in a too confuse way ;)
Like I said, I came with this after several days of thinking,
and it was tweaked three or four times before getting to this
final design, so it may or may not be a good way to do.



Vincent Penquerc'h

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
 >> I put Lua in a .DLL, then link my C++ Builder app
 >> You can even load up the tool .DLL explicitly rather than linking to it

   Are you practicing for opening up your own psychic hotline?  If you keep
answering my questions before I ask them I might freak out.  <grin>

   That's cool, so I'll probably end up doing lots of mixed-compiler stuff
like that.

 >> wait_for_actor(manny)

   I wasn't exactly clear what you were doing with your multitasking mods,
but that call clears it up.  "Who" actually flipped the wait/busy-flag
back?  Was it the host animation engine when some form of sprite sequence
file ran out, or were your animations sequenced explicity with Lua code so
it was simply another Lua task did the state change when done?


   More status:  OK, so I've got Lua controlling the game intros.  Nothing
fancy: load the publisher's image, do a screen dissolve, load the
developer's image, do a screen dissolve, load the title image, do a screen
dissolve.  Brain surgery, huh?  <grin>  Still, pretty cool to me, sorry to
waste list bandwidth.


   Cheers,

   Dave
   "Everybody wants a rock to wind a piece of string around."

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
 >> and then in the DllMain you could set global lua functions,etc.

   Ah yes, since everything is one big happy process family, this all
works.  I'm beginning to see the possibilities here.   (But I'm also kinda
getting ahead of myself!)
   So, it ought to be possible to set up fully automatic library
extensions, yes?  If the extensions are in a DLL and the DLL self-registers
those functions in it's own DLLMain, and it's all the same Lua process...

   Cheers,

   Dave

Reply | Threaded
Open this post in threaded view
|

RE: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
   OK, I just discovered the eGroups.com copy of the mailing list and
realized the the archive I had read was not entirely current.  Looking back
over the last 100 or so messages I see many of my same questions being
asked (extensions in DLL's, state management, etc).  So I think I'll shut
up for a while until I've had a chance to digest the rest of that
historical info.  ;)

   I'm not sure Pablo Saldo received this reply (can I get private e-mail
tagged as from the listproc?) so I'll post this again here:

 >> Can you share thiss DLL with me? I use Lua on university, but use
Delphi at work. 

   Well, being the newbie here, I'm probably not the most qualified to
build this thing for you, but...  I just put up a page at:

   http://ourworld.compuserve.com/homepages/dbollinger/lua.htm

   There are a couple of oddball things there (including a Lua port of
h2def, I sorta felt guilty upon reflection for posting an Awk script to
this list, such treason! <grin>)  I haven't done a full a Delphi import
unit though, so you'll have to tackle that on your own (have you done it
before?  basically just shuffle the declaration syntax then add "cdecl;
external 'LUA.DLL';" to the end of everything)

   Cheers,

   Dave

Reply | Threaded
Open this post in threaded view
|

Re: Game oriented usage of Lua?

David Jeske-3
In reply to this post by Vincent PENQUERC'H
I've included some Lua code snippits at the bottom.

On Fri, May 28, 1999 at 04:17:53AM -0300, Vincent PENQUERC'H wrote:
>> 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!
> 
> I'm new to Lua, and thus I may not have taken the best path, but
> here is the way I used it: I have several 'entities' in my game,
> most of them are items or characters. Each of them, when created,
> creates a Lua table representing it.
>
> This table is composed of data and function fields. The only data
> field known to C++ is set at the object construction, and is the
> 'owner' field, initialized to the C++ pointer to the object (a Lua
> userdata). All other data fields are left to the use of Lua scipts.

That sounds similar to how my stuff works...

> The functions depend on the type of table. For a character, for
> example, several functions are predefined and have special meaning
> for the C++ game engine: 'onthink', 'ontalk', 'onhit', 'ondeath',
> etc... Whenever something happens which correspdonds to one of
> those, the function is called (if defined).  This way, default
> behavior is executed if the function is not defined in the table,
> and it can be overriden by defining the function.

Hmm... the methods are all the same for all "Sprites" in my game, and
the Lua code just does different things for different types of
objects.

My methods are "ai_event", "do_tick" (for doing object Physics), and
inputEvent (if an object is active).

> This set of predefined Lua table functions have at hand a set of
> registered C functions that access everything's necessary
> (examples include CharFindPathTo, CharFindPathAround, CharAttack,
> CharSay, CharStopMoving, CharGetInventory, etc...). some of these
> basic bricks are very low level (CharGetXPos) 

Sounds very similar to my stuff as well. I have C_obj_goto,
C_obj_viewfollow, C_obj_delete, C_obj_getvelocity, C_obj_setvelocity.


---------------------------------------------------------------

I also have a multiple inheritence scheme I used to construct objects
out of smaller components I call traits. (The 'traits' term is
borrowed from the Sun SELF language) For example, below is my
helicopter object, notice the traits listed in the _parents line and
the VisualRep pointing to the VisualRep table. The way I handle
defining Visual Representation is worth an email in itself, so if you
are interested after what you see below, go check out this URL:

http://www.chat.net/~jeske/Projects/HZ/docs/sprite_definition.html


hz_register_objtype("heli", {
	_parents = { air_physics, controllable, collidable },
	imgdir = 2.0, -- image index
	rimgdir = 1.0, -- rotor image index
	direction = 0.0, 
	bullet_type = "bullet",
	objtype = "heli",
	exp_timer = 0.0,
	frame_time = 70,
	layer = 1,
	VisualRep = VisualReps.Heli,

	-- dummy ai_event
	ai_event = function(self)
	end,

	new = function (self,a_list) -- constructor
		if (type(a_list) ~= 'table') then
			print("heli:new() called with non-table "..tostring(a_list));
		else
			a_list._parents = { self };
			a_list.key = {}; -- make our private keydown list
			a_list.ctrl_centered = 1.0;
			a_list.dest_dir = 0.0;
		end
		return (a_list);
	end
}); -- register done

--------------------------------------------------------------

Here is a very simple trait... "collidable". This is just responsible
for creating explosions:

collisions_active = 0;
MAX_COLLISIONS = 5;

collidable = {
ge_collision = function(self,x,y,whoIhit)
	if ((collisions_active < MAX_COLLISIONS) and (self.layer == whoIhit.layer)) then
		C_addsprite("explosion",x,y);
		collisions_active = collisions_active + 1;
	end
end

}; -- end collidable

--------------------------------------------------------------

This last example is a bit long, but here you can see one of the
physics traits... air_physics. It includes all the physics
calculations for flying objects:

air_physics = {
vx = 0, vy = 0, rot = 0,
doTick = function(self,tick_diff)
	local vx, vy, rot;
	local dest_dir = self.dest_dir;
	local ax, ay; -- acceleration vectors


	local exp_timer = self.exp_timer;
	local frame_time = self.frame_time; -- 70 seconds? frames? what is this?
	local exp_img_num = self.rimgdir;
	local EXP_IMG_COUNT = 10;

	exp_timer = exp_timer + tick_diff;

	while (exp_timer > frame_time) do
		exp_timer = exp_timer - frame_time;
		exp_img_num = exp_img_num + 1;

		if (exp_img_num > EXP_IMG_COUNT) then
			exp_img_num = 1;
		end
	end

	self.exp_timer = exp_timer;
	self.rimgdir = floor(exp_img_num);

	vx, vy = C_obj_getVelocity(self.objnum);
	rot = self.rot;

	if (self.ctrl_centered == 1.0) then
		ax = 0.0;
		ay = 0.0;
	else -- (not self.ctrl_centered)
		-- accelerate in that direction!
		ax = Dirx[floor(dest_dir)];
		ay = Diry[floor(dest_dir)];
		print(format("accelerate at (%f,%f)",ax,ay));
	end
	
	if (ax == 0.0) then	
		-- coast!
		if (vx > tick_diff/2000.0) then
			vx = vx - tick_diff/2000.0;
		elseif (vx < -tick_diff/2000.0) then
			vx = vx + tick_diff/2000.0;
		else
			vx = 0;
		end
	else
		-- apply the acceleration!
		vx = vx + (ax * tick_diff/4000.0);
	end

	if (ay == 0.0) then
		-- coast!
		if (vy > tick_diff/2000.0) then
			vy = vy - tick_diff/2000.0;
		elseif (vy < -tick_diff/2000.0) then
			vy = vy + tick_diff/2000.0;
		else
			vy = 0;
		end	
	else
		-- apply the acceleration!
		vy = vy + (ay * tick_diff/4000.0);
	end

	if (self.ctrl_centered == 1.0) then
		C_obj_setVelocity(self.objnum,vx,vy);
		return;
	end

	local i_rot = floor(rot);

	if (i_rot == dest_dir) then
		-- we're facing, so given an acceleration boost!
		vx = vx + (ax * tick_diff/2000.0);
		vy = vy + (ay * tick_diff/2000.0);
	else
		-- we need to turn "into the wind"
		local turn_vec;
		local cw_distance;
		local ccw_distance;
		local MAX_SHIP_FRAME = 40;

		-- first, figur out what direction to turn
		if (i_rot > dest_dir) then
			ccw_distance = i_rot - dest_dir;
			cw_distance  = MAX_SHIP_FRAME - (ccw_distance);
		else
			cw_distance = dest_dir - i_rot;
			ccw_distance = MAX_SHIP_FRAME - (cw_distance);
		end

		local TURN_RATE = 1.0;

		if (cw_distance < ccw_distance) then
			if (cw_distance < TURN_RATE) then
				turn_vec = cw_distance;
			else
				turn_vec = TURN_RATE; -- cw
			end
		else
			if (ccw_distance < TURN_RATE) then
				turn_vec = 0.0 - cw_distance;
			else
				turn_vec = 0.0 - TURN_RATE; -- ccw
			end
		end

		i_rot = i_rot + turn_vec;
		if (i_rot < 0.0) then
			i_rot = i_rot + MAX_SHIP_FRAME;
		end
		if (i_rot >= MAX_SHIP_FRAME) then
			i_rot = i_rot - MAX_SHIP_FRAME;
		end
	end 
	self.imgdir = i_rot + 1;
	self.rot = i_rot;
	C_obj_setVelocity(self.objnum,vx,vy);

end -- function end

}; -- end air_physics

-- 
David Jeske (N9LCA) + http://www.chat.net/~jeske/ + [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Game oriented usage of Lua?

Dave Bollinger
In reply to this post by Jeroen Janssen
David Jeske wrote:
 >> I have C_obj_goto, C_obj_viewfollow, C_obj_delete,

   I'd like to discuss naming conventions - if there are any "standards" or
"de facto" ways of keeping everything straight.  For example, you
apparently use a preface of "C_" for your library extensions.

   The situation I'm facing can be illustrated as follows, with a bit of
name mangling using '|' to separate the "owner" from the function:

   LIB|showjpeg    -- from the graphics library linked with host app
   HOST|showjpeg   -- wraps graphics library in host app
   LUAX|showjpeg   -- wraps HOST.showjpeg within host app with Lua calling
conventions
   LUA|showjpeg    -- name registered inside Lua for LUAX.showjpeg

   (The reason, currently, for separate HOST|showjpeg and LUAX|showjpeg is
that I may have need to call the routine directly from the host app and is
more convenient to call the HOST| version there.  If I eventually let Lua
take full control of the app's functionality, I'd then merge those two
functions into a single LUAX| version.)

   Now, I could make things very confusing and just pick random names for
all those related functions, but I'm thinking that's not a wise decision. 
;-)  So far, I've named all the host extensions functions "lx_*" (for "Lua
eXtension") and then registered the name without the decorated prefix,
like:  lua_register("showjpeg", lx_showjpeg).

   That's not bad, however even with only about a dozen functions
registered so far and a hundred lines of Lua code, it's already tricky to
see at a glance where host functions are being called.  I mean
showjpeg("whatever.jpg") just kind of hides out in there looking like it
might be a Lua-defined function, not a host extension.  Your big bold
capital "C_" method handles that problem.

   Any advice, suggestions, recommendations, common conventions?  Thanx.

   Cheers,

   Dave

12