TheBuzzSaw wrote:I understand the C++/Lua relationship and how it should be applied, but I am very new to the process of integration. How did you learn? Are there good tutorials out there? I am looking for the actual implementation process. For instance, what library should I use to bind the two? Where in the game loop is Lua invoked? Should any of it be threaded?
The "how do you learn" part is kinda hazy. There's not really any halfway complete guide to helping you do it.
I spent a very large amount of time at
http://lua.org looking at the official documentation. Then google something like "invoking Lua from C++" to see the process. It's basically instantiate the Lua VM, send it a stream of characters to interpret/execute, then close it when you're done.
As for binding libraries, it really all depends. They aren't
required. You can write your own bindings from C++ to Lua. And while it's really a pain in the ass, I think that I would recommend at least getting the basics of that down (passing things to and from Lua's stack), before turning to a binding library--that stuff is the basis for communication between the two. Also, I use toLua++, which (like all binding libraries) has certain limitations. Since I know what I'm doing, I can alter the outputted bindings if I need something that toLua++ doesn't support.
Now about the binding libraries. There's no clear-cut best one. M_D_K on these forums uses SWIG. I use toLua++, and Trufun (of Golvellius 3D fame) uses LuaBind. I had originally looked into LuaBind for Elysian Shadows, but I found that it had a huge amount of overhead and additional dependencies (from the Boost library), so I opted to use toLua++. LuaBind produces bindings at compile-time using metatemplate programming (or whatever). This is kind of new to C++ (so the standard isn't really... standardized). GCC on the Dreamcast was too old to handle it.
Basically it boils down to:
LuaBind - Generates bindings at compile-time from your C++ code. Compiling takes longer, and there is a pretty hefty dependency, but it is pretty damn convenient.
toLua++ - Console-application that generates bindings from C++ headers that you pass to it. It outputs a <whatever>_bind.c that you link with your application. Very little overhead, very light weight.
Now to answer your final question about where to invoke Lua from the engine: it really depends. What are you using Lua to do? I'll give you an example in ES. Each level has a level.lua, which has any special scripting in the level. Maybe events triggered by picking up a key and opening a door, maybe an event triggered by the player walking on a certain tile, or maybe just updating some sort of animation. This script is invoked when the engine updates the level.
Then we have items with their own "use" scripts, which are more or less something like
for something like a healing potion. These are invoked when the player selects an item and hits use on the menu.
ES also has enemies/NPCs powered by AI scripts. These are invoked when each enemy/NPC's Update() is invoked.
Creating an engine that really takes advantage of scripting is an art. I've seen far too many people who implement Lua and basically brute force everything via Lua script while the engine does nothing but render and maybe do some collision checks. The engine is the thing powering the game--not Lua. Lua should serve as a logical extension, so that you aren't hard-coding content-specific logic into an engine. An engine relying on Lua for too many things is weaker than an engine that doesn't even support scripting.
Oh, and for the record, the Lua VM is not getting its own thread. There's really not a need to bother with multithreading (usually).