Jump to content
  • Advertisement
Sign in to follow this  
ivy

Lua Examples

This topic is 4828 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I started learning lua the other day and was starting to think ways to implement it in a game (Menu, AI, level specific code) Can anyone post specific examples of things they have used or plan to use lua for in their game projects? Even going into detail of how lua would benefit a menu besides removing hard coded numbers would help.

Share this post


Link to post
Share on other sites
Advertisement
There are many different solutions to implementing scripting into a game project. My recommendation would be that every scriptable entity has its own lua_State and reads its own script file.

Share this post


Link to post
Share on other sites
Something that I would really like to see (and haven't yet found) is a tutorial or example on how to use a script written in Lua that can change the values of members of a class. What I mean is this:

// C++ class

class MySprite {
public:
int x_position;
int y_position;
bool dead;
};



// Lua script

function move_sprite ()
x_position = 58
y_position = y_position + 5
if (y_position == 12) then
dead = true
end
end



Or if something like this is even possible. I know enough with C++/Lua that I can extract data from a Lua file and then save it to a C++ variable, but it would be so much easier if I could pass Lua a pointer to a class object and have it modify that data in the script itself without any more handling. I'm still very new and naive to the world of scripting (plus another guy on my team has been doing the majority of this stuff so far). If someone could post a good, complete tutorial and Lua game scripting and outline what you can/can not do, that would be freaking awesome. [wink] I'm reading the Programming in Lua text right now, but a tutorial on this specific subject would really help a lot.

[/source]

Share this post


Link to post
Share on other sites
Using LuaPlus (example from LuaPlus's TestScript.cpp):



class VECTOR
{
public:
double x,y,z;
};


class MONSTER
{
public:
int alive;
void *mesh;
VECTOR position;
char name[32];
};

namespace LPCD
{
template <int NUM_CHARS>
inline void Push(lua_State* L, char value[NUM_CHARS])
{
lua_pushstring(L, value);
}

template <int NUM_CHARS>
inline bool Match(TypeWrapper<char [NUM_CHARS]>, lua_State* L, int idx)
{
return lua_type(L, idx) == LUA_TSTRING;
}

/* template <int NUM_CHARS>
inline const char* Get(TypeWrapper<char [NUM_CHARS]>, lua_State* L, int idx)
{
return lua_tostring(L, idx);
}
*/

inline void Push(lua_State* L, const VECTOR& value)
{
LuaState* state = LuaState::CastState(L);
LuaObject obj = state->BoxPointer((void*)&value);
obj.SetMetaTable(state->GetRegistry()["VECTOR"]);
}

inline bool Match(TypeWrapper<VECTOR>, lua_State* L, int idx)
{
LuaState* state = LuaState::CastState(L);
LuaObject obj = state->Stack(idx);
return obj.GetMetaTable() == state->GetRegistry()["VECTOR"];
}

inline bool Match(TypeWrapper<VECTOR&>, lua_State* L, int idx)
{
LuaState* state = LuaState::CastState(L);
LuaObject obj = state->Stack(idx);
return obj.GetMetaTable() == state->GetRegistry()["VECTOR"];
}

inline VECTOR Get(TypeWrapper<VECTOR>, lua_State* L, int idx)
{
return *(VECTOR*)lua_unboxpointer(L, idx);
}

inline VECTOR& Get(TypeWrapper<VECTOR&>, lua_State* L, int idx)
{
return *(VECTOR*)lua_unboxpointer(L, idx);
}
}


void PassVector(VECTOR& vec)
{
printf("Vector: %f, %f, %f\n", vec.x, vec.y, vec.z);
}

using namespace LuaPlus;

void VectorMonsterMetatableTest()
{
LuaStateOwner state(true);

LuaObject vectorMetaTableObj = state->GetRegistry().CreateTable("VECTOR");
LPCD::MetaTable_IntegratePropertySupport(vectorMetaTableObj);

LPCD::PropertyCreate(vectorMetaTableObj, "x", &VECTOR::x);
LPCD::PropertyCreate(vectorMetaTableObj, "y", &VECTOR::y);
LPCD::PropertyCreate(vectorMetaTableObj, "z", &VECTOR::z);

LuaObject monsterMetaTableObj = state->GetRegistry().CreateTable("MONSTER");
LPCD::MetaTable_IntegratePropertySupport(monsterMetaTableObj);

LPCD::PropertyCreate(monsterMetaTableObj, "alive", &MONSTER::alive);
LPCD::PropertyCreate(monsterMetaTableObj, "mesh", &MONSTER::mesh);

LPCD::PropertyCreate(monsterMetaTableObj, "position", &MONSTER::position);
// LPCD::PropertyCreate(monsterMetaTableObj, "name", &MONSTER::name);

MONSTER monster;

LuaObject monsterObj = state->GetGlobals().CreateTable("Monster");
monsterObj.SetLightUserData("__object", &monster);
monsterObj.SetMetaTable(monsterMetaTableObj);

state->DoString("Monster.alive = 1");
state->DoString("Monster.position.x = 5");
state->DoString("Monster.position.y = 10");
state->DoString("Monster.position.z = 15");
state->DoString("print(Monster.position.x)");

state->GetGlobals().RegisterDirect("PassVector", &PassVector);
state->DoString("PassVector(Monster.position)");
}




Also see a language very similar to Lua: Squirrel (with table code from Lua). See this thread. Squirrel was designed by an experienced Lua programmer, specifically for use in games. Class support is native, and interfacing with C++ classes is much easier (see the example in the referenced link). Reference counting/class (memory) handling is also built in (a major issue for standard Lua, but not as much with LuaPlus (reference counted)).

The example higher-level helper code for Squirrel uses macros, which is not as clean looking as using template metaprogramming (as with LuaPlus and boost-based methods). However, the resulting code is relatively simple and easy to understand/debug (and can be faster at runtime as multiple template helpers aren't needed).

Share this post


Link to post
Share on other sites
Thanks for the example. I was looking for something a little more low-level though (not relying on a C++/Lua extension library). We had considered all of the (numerous!) C++/Lua integration libraries in the past, but the data/scripting guy really wanted to do the binding himself, and a lot of those libraries we had issues with so I let him have his way. I took a look at the LuaPlus documentation just now out of interest and it actually requires you to use a non-standard implementation of Lua to use it. [sad]




Also on another note, is it possible to use Unicode in Lua strings? I know you can set the locale so that you can have variable names that are in Portugese or whatever, but what if I'm running on an English machine, and I want to assign a string variable to a piece of Japanese text? I've never been able to find a clear answer to this question unfortunately.

Share this post


Link to post
Share on other sites
Quote:
Original post by Roots
Thanks for the example. I was looking for something a little more low-level though (not relying on a C++/Lua extension library). We had considered all of the (numerous!) C++/Lua integration libraries in the past, but the data/scripting guy really wanted to do the binding himself, and a lot of those libraries we had issues with so I let him have his way. I took a look at the LuaPlus documentation just now out of interest and it actually requires you to use a non-standard implementation of Lua to use it. [sad]


An advantage of the non-standard (improved) version of Lua via LuaPlus is the support for reference counting (this is one of the reasons Squirrel was created). Of all the template metaprogramming Lua enhancements, I feel that LuaPlus is the best. It also includes a remote debugger. LuaPlus is extremely powerful, has a good deal of test/example code, serialized tables, custom memory allocators/handlers, extensions to use COM controlled objects, SQL, etc. See LuaPlus Home Page.

Quote:
Original post by Roots
Also on another note, is it possible to use Unicode in Lua strings? I know you can set the locale so that you can have variable names that are in Portugese or whatever, but what if I'm running on an English machine, and I want to assign a string variable to a piece of Japanese text? I've never been able to find a clear answer to this question unfortunately.


It appears vanilla Lua does not support wide/UNICODE strings. Both LuaPlus and Squirrel support wide/UNICODE (16 bit) strings.

While LuaPlus is very powerful, and generally very easy to use (just one line of code to bind new functions/variables in some cases), Squirrel's core code is only 6K lines of code. While Squirrel is now a few years old, if a bug-fix/enhancement is required, it's a relatively small amount of code to work through (and relatively simple compared to LuaPlus). The Squirrel forum appears to show that the language is solid enough for use in commercial game production (the language author is using it for an XBox title).

Using the macro-based binding/setup method for Squirrel is only a little bit more code than a template-based solution, and at run time is simpler. Perhaps try the simple Squirrel example I posted in the other thread, trace through the code with the debugger to see how simple/elegant the interface to C++ can be (as well as the language itself). It should be possible to download the .zip, extract, compile and run the example in a few minutes (all self-contained, no warnings/errors during compile, etc.).

What impresses me most about Squirrel vs. Lua is that the author fixed/improved all the issues he had when using Lua in the commercial game FarCry. Moving from Lua to Squirrel is straightforward (again, the table code comes from Lua).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!