Jump to content
  • Advertisement
Sign in to follow this  
evilsanta

Best Way to Embed Lua

This topic is 3232 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

Hello everyone, I am attempting to embed lua into my game. I am currently using luabind and it's going great. However my question is what is the best way to embed it? I want to use Lua to control enemies/characters/levels things of that nature. I know how to take, say for example an enemy class with getters and move functions and make them visible to lua. But should I open a new lua state for each enemy? For my list of enemies? I'm not sure how to approach giving lua some control over large amounts of objects. I would like it to be as efficient as possible. If anyone could give me any pointers on how to design the program I would appreciate it.

Share this post


Link to post
Share on other sites
Advertisement
You don't need more than one LUA state in your game.

The way I do it is by using the pointers to the objects I want to control as "handles" in LUA - they are passed back and forth with the lua_pushlightuserdata/lua_touserdata functions. When some function is called (like a callback or something), my object pointer is passed to LUA. My object manipulation functions exposed to LUA take this "handle" as a parameter so the application can know which object I want to work with.

I'm not sure if there is another way of doing this that might be safer, but this works for my purposes.

Share this post


Link to post
Share on other sites
A state per enemy is excessive and makes it hard to exchange data from one state to the next without using a plugin from Luaforge.
Quote:
I would like it to be as efficient as possible
I am not going to pimp my own work, but if speed is something you are after then from my tests Luabind is the wrong library to be using. As Badgerr pointed out the most efficient yet less user friendly way is to use object handles, this could be light user data or entity id's.

Share this post


Link to post
Share on other sites
Thanks for the replies, pardon me for being completely ignorant on this subject... So I attempted to implement a simple Lua based particle system. The idea is that the user can change how particles are created, and how they are updated from lua by defining two functions in a lua file.

I have it working at the moment, the following lua code executes.


luaL_dostring(luaState,
"function updateParticle(p)\n"
"p.color.a = p.color.a-5\n"
"end\n"
"function spawnParticle(system)\n"
"p = system:createParticle()\n"
"p.life = 50\n"
"p.width = 50\n"
"p.height = 50\n"
"p.color.r = 255\n"
"p.color.g = 155\n"
"p.color.b = 55\n"
"p.color.a = 255\n"
"p.xVel = math.random(-2.2,2.2)\n"
"p.yVel = math.random(-2.2,2.2)\n"
"end\n"
);





So is this alright? I'm reluctant to feel that because it works at the moment that it is the correct way to do it. I guess I'm not going for optimum speed but rather ease of code while maintaining decent frame rates.

So with the current code, each particle system would have a string of code associated with it, and it would make a call to dostring to set the current functions. Then the particles update by making calls to say for example...


luabind::call_function<void>(luaState, "updateParticle", p);





And it seems that if doString is called multiple times, and functions have the same name then it picks the most recent? Should the lua state be cleared or anything? I have a feeling calling luaL_dostring multiple loops isn't the way to do it (hence why I thought having multiple lua states might be useful, just define each custom function once in each state).

If I renamed the function for each different particle file and ran toString in the initialize phase would that work? For example having/calling updateParticle[fileName] as the function name?

[Edited by - evilsanta on December 7, 2009 4:51:14 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by dmail
A state per enemy is excessive and makes it hard to exchange data from one state to the next without using a plugin from Luaforge.
Quote:
I would like it to be as efficient as possible
I am not going to pimp my own work, but if speed is something you are after then from my tests Luabind is the wrong library to be using.


Note that the performance of luabind has drastically improved for the next version, 0.9, which is approaching a stable state at http://github.com/luabind/luabind/tree/0.9.

--
Daniel Wallin

Share this post


Link to post
Share on other sites
My blog should help, if you go to my first couple posts you will see a presentation i made about lua and architecture. i would go into it here but the video and posts explain it in pretty good detail.

Share this post


Link to post
Share on other sites
Quote:
Original post by AverageJoeSSU
My blog should help, if you go to my first couple posts you will see a presentation i made about lua and architecture. i would go into it here but the video and posts explain it in pretty good detail.


Thanks for the video, very interesting stuff. So you kinda talked about this in the video, but I don't want to be passing objects to Lua (like in my code above)? I guess my question is, what should I be doing in my update loop? And what should I be initializing.

At the moment, I bind my classes in the init phase. Should I be calling do_string (or some equivalent) during the update? The code I posted above works, but I can only call update 20 times or so per iteration before my framerate dies.

[Edited by - evilsanta on December 8, 2009 3:03:52 PM]

Share this post


Link to post
Share on other sites
The main difference between your code and my code is that the main graphical stuff updates every frame at the native level. Lua just has a set of functions to work with the things.

Camera for example updates every frame with its matrix at the native level. (its a array of cameras and the active camera is what is used in rendering hence the id)

in lua i have a set of functions that take an ID of the camera (can be an actual instance of it but again this defeats the purpose of the architecture like i described in my errata) and pass that id to a native function that tells the camera to move to xyz point. lua doesnt really update the camera... it just tells the engine to move the camera and then the engine updates it and moves it accordingly during update.... (really the move function just adds an animator to the cameras animator stack, which gets evaluated every update).

Share this post


Link to post
Share on other sites
Quote:
Original post by evilsanta
The code I posted above works, but I can only call update 20 times or so per iteration before my framerate dies.


Seeing as this is for particles and they are normally created in large numbers I suspect the following line of your code is the problem

"p = system:createParticle()\n"


It should be written

"local p = system:createParticle()\n"


In Lua when you declare a variable and do not mark it local then it is global and therefore the garbage collector never cleans it up or the C++ Luabind "class_" and all its members. IIRC that it what it is called in Luabind yet I may be incorrect here. It is good Lua programming practice to declare all variables local unless this is not what you want them to be.


Offtopic:
Quote:
in lua i have a set of functions that take an ID of the camera (can be an actual instance of it but again this defeats the purpose of the architecture like i described in my errata) and pass that id to a native function that tells the camera to move to xyz point. lua doesnt really update the camera... it just tells the engine to move the camera and then the engine updates it and moves it accordingly during update.... (really the move function just adds an animator to the cameras animator stack, which gets evaluated every update).

Out of interest how does your C++ Lua registered functions know of your class instances, for example the "engine". I have not looked at your blog or the video which you mention yet I would assume it is one of three ways if you are using raw Lua.
1) You stuff the instances in the Lua state's registry and pull them out inside the registered functions.
2) Your instances are global.
3) You are using a monostate pattern and the functions and instances are static to a structure.

Share this post


Link to post
Share on other sites
Quote:
I have a feeling calling luaL_dostring multiple loops isn't the way to do it (hence why I thought having multiple lua states might be useful, just define each custom function once in each state).

By this do you mean that each buffer is being loaded for each particle at every iteration? If so then I would say this is the wrong approach to take.

Quote:
Note that the performance of luabind has drastically improved for the next version, 0.9, which is approaching a stable state at http://github.com/luabind/luabind/tree/0.9.

I look forward to the improvements that you are making, although I find it funny that you are willing to make a post about these yet not willing to help the OP who is using your library :)

[Edited by - dmail on December 9, 2009 5:29:54 AM]

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!