Why use Lua/Scripting?

Started by
5 comments, last by _the_phantom_ 15 years, 3 months ago
I am currently working on a game in C# which is going pretty well and Ive got a system that is working pretty well for doing scripting events (user moves to a certain area which triggers an event, etc). The system I am using however is a bit limited because Ive had to implement the different situation in C#. At the same time I am aware that most games use some kind of scripting system for this type of work, Lua seems to be the most common language used. Ive checked out a bunch of articles that cover off the technical aspects of using Lua but I havent been able to find anything that explains how Lua might be implemented into a typical game engine setup. Can anyone please provide some explanation here or provide some resources that address the use of Lua from this perspective? Thanks! This is what I have been reading so far: http://www.gamedev.net/reference/articles/article2275.asp http://einfall.blogspot.com/2006/05/scripting-with-lua-in-c.html http://www.godpatterns.com/article/lua-in-c/
Advertisement
Using a scripting language was/is very popular for games for a few reasons:

1. Most scripting languages are much more high-level than C++ (which just about all commercial games use), and can be used much more readily by gameplay or level designers.

2. The portions of a game written in scripting languages can be modified while the game is running, without having to restart or recompile. This is important if the people working on the scripted portions don't have access to the compilation tools, or if compilation takes a long time.

3. C++ has no built-in reflection capabilities.

I'm sure there are more reasons, but AFAIK these are the bigger ones. However before you decide whether you need to embed Lua or Python or whatever in your game, you should evaluate whether using a scripting language would hold the same benefits for you as it would for your average commercial game. For instance the fact that you're using C# and not C++ changes things considerably. C# is quite a bit simpler and easier to use than C++, has built-in reflection, and can even be compiled and run on-the-fly.

I think what I am experiencing in my development is that the more dynamic features of C# are somewhat alleviating my need for a specific scripting language. In fact, I use the reflection features of C# for my current scripted event system.

Id still be very curious to know how scripting systems are usually implemented in game engines, are the Lua scripts called on each frame to determine the behavior of the in game objects? What is the best strategy here?
If you decide to use Lua, I highly suggest reading Programming in Lua (Second Edition) from cover to cover (you can also read the first edition online here. How you integrate Lua into your project depends greatly on the application itself. However, a good understanding of how the virtual machine works will give you a great deal of insight into how your application should interact with it. Lua is quite flexible and offers many features to help you achieve what you need but you'll have to understand these facilities. Not to worry though. It's also quite simple and once you've "got it", you've "got it". Most of its features center around the concept of tables and, from the API perspective, stacks.

The Lua VM is manipulated through scripts and/or the API so it's fairly trivial to pass data back and forth as well as call functions in Lua from your application or vice versa (C/C++ functions can be easily registered and called directly from scripts).

Some links:
Introducing Lua
Simple Lua Api Example
Lua 5.1 Reference Manual
Calling Lua Functions
Re: Pass pointer into LUA

Hope this helps. If not, feel free to ask.
Quit screwin' around! - Brock Samson
There's several threads on these forums with good information about connecting host-language objects' interfaces into Lua, such that your Lua code can manipulate host-language data easily.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
Quote:Original post by richardmonette
Ive checked out a bunch of articles that cover off the technical aspects of using Lua but I havent been able to find anything that explains how Lua might be implemented into a typical game engine setup.


I've not yet seen any such articles on the net that cover that. I might write one later on after I finish a current project that specifically does that. So, here's some perspective on how I would go about it.

When you integrate Lua into a game engine, it is a two phase process. The first and most important phase is to write the Lua binding for the engine. In doing this, you fully expose your engine to Lua so that, a user can write a "hello world" program in Lua using your engine without the need for any C++ code (aside from perhaps the host application that executes the script and setups the engine for Lua usage)

Once you have a Lua binding down, the next phase is to write a second layer that binds the Lua and C++ logic together, but is independent of the actual Lua binding (this will payoff in the future, not just present). The first phase only bound the programming semantics together, not the actual logic. If you create an object in C++ code, you want your Lua scripts to be aware of it and have access to that information as well as vice versa.

There are a few ways to do this, but the approach I will be taking involves maps/reference strings/getter functions. Let's say I have something like this in Lua: local box = CreateBox(1, 1, 1); -- Create a box with dimensions Phase 1 of the above is seen in this API function call, phase 2 cannot be seen since it is independent of phase 1. To accomplish phase 2, we would need a second API call: RegisterBox(box, "MyBox1"); -- Share this instance between scripts and programs.

Our C++ code would look something like this (quick example, not good design):
std::map<std::string, tEntity *> entityMap;...void RegisterBox(tEntity * entity, const char * refName){   entityMap[refName] = entity;}...int Phase2_RegisterBox(lua_State * L){   tEntity * e = Lua_touserdata(L, 1);   const char * n = Lua_tostring(L, 2);   RegisterBox(e, n); // Let's keep things consistent with C++ usage!}tEntity * GetEntity(const char * refName){   return entityMap[refName];}

Now, if C++ code were to create a box, the code would also call the RegisterBox method to register the entity with the map. This sort of logic then allows you to fully interact with your world in different scripts without having to worry about unnecessary complexities:
-- gracity.Lualocal count = GetBoxCount();if count > 0 then   box = GetNextEntity(-1); -- Think of this as some sort of iterator function   while box ~= nil      AddForceToEntity(box, 0, -9.8, 0);      box = GetNextEntity(1); -- Next entity   endend

Those are kind of trivial examples, but hopefully you can see the goal. You want one layer that implements the core engines ability in their entity. Next, you want a second independent API that uses the results of the first API to bind everything together from each side. Doing this, you can arbitrarily execute scripts that pull from the C++ API and have the entire world state available rather than having to register it all through Lua globals.

The reason you do not want to couple the two is you then no longer have a project independent Lua binding that cannot be reused. By making the second layer part of the first, you make the whole thing project specific and in the future, if you use the engine again, you have to go and rip out all that extra stuff if your design is different. Further more, other people would not be able to benefit from it, so it's worth while to make two separate APIs.


[Edited by - Drew_Benton on January 9, 2009 8:56:51 PM]
if you are going to write an article please write it about "Lua" not "LUA"... mostly because the latter isn't a scripting language.

This topic is closed to new replies.

Advertisement