C++ engine hosting LUA scripts

Started by
10 comments, last by og knuckles 8 years, 7 months ago

Hello,

So as the title states I'd like to be able to run lua scripts in my c++ engine. I currently have a c++ openGL rendering engine with enough graphical effects to start making games with. I have looked at embedding LUA and it does look fairly simple however there is a few things I am unclear about. How do I make an editor for lua? I understand that once LUA is embedded I only have to run my .exe and then edit the LUA scripts to modify what the game is doing real-time. How am I able to make something that can edit the script while the .exe is running then say ok send the new script to the engine? If you could provide resources/tutorials or a direction for me to head in that would be great! Thanks for your time.

Advertisement

I'm unclear about what you are wanting to do here. Do you want to read a Lua script and then modify the data in state and then execute it (without modifying the existing script)? Or do you want to read a Lua file, overwrite that file, and then read it again and run it? I'm not sure about how to do the former off-hand. The latter I've done, but we only do this sort of thing for writing a save game file, user preferences, or other sort of long-term storage. We don't overwrite our existing scripts in real-time (which seems like a bad idea both for performance and maintainability).

I wrote an API a few years back that can construct a Lua file piece by piece. You can tell it to write single data, tables, containers of data (vectors), and even comments. It doesn't build actual functions/code though, but we could easily add that functionality if we had a need for it. Follow the link below to check it out. You want to look at the "script_write.h" and .cpp functions to see how this is done. It's rather simple really, and is just a matter of text processing.

https://bitbucket.org/allacrost/allacrost/src/9888d7df09f92ced52900621b282e95d2855a576/game/src/engine/script/?at=default

Hero of Allacrost - A free, open-source 2D RPG in development.
Latest release June, 2015 - GameDev annoucement

Yeah overwrite that file and read it again. The developer of GRIMROCK had a page stating he was able to do this during run time ie changing the ai for monsters right infront of him in game. To me this is huge I would love to be able to do this rather than constantly recompiling the whole program.

http://www.grimrock.net/2012/07/25/making-of-grimrock-rapid-programming/

I looked at LUA for this kind of application years ago (back when LUA was 10X slower than C and Python 20X slower). Now it looks like they have sped things up significantly (but the performance examples Ive seen have begun to look more C-like - which I though moved away from that 'script' advantage of being 'simpler').

The one aspect (for performance consideration) which isn't part of those examples is the overhead for the constant interfacing between the 'script' LUA and the rest of a game's system (game mechanics and data and OS interfacing for an imbedded 'script' language). Note in the GRIMROCK project webpage they said - "In Legend of Grimrock we decided to fully embrace Lua and code everything that we possible could in Lua to really leverage all the" which MIGHT allieviate alot of the LUA-C interfacing, but the I'm still curious about what the impact is of the interfacing that still remains - it may move alot of the burden/overhead to the LUA libraries which have to be calling the script's external access - like for graphics/network or OS operations)

If the requirement is for quick code patching (at runtime) that can be done with DLLs in C (which would be my chosen solution) Either way you have to be clever about the design to try to isolate the code that is likely to have the most changing required (the game logic/entity behaviors)

I actually wonder about the utility of the patching feature -- and would want to see real world statistics about how frequently runtime code patching actually is done and how often the needed patch changes STILL required restarting everything anyway (the scripter has to consider/judge what the code change affects, as they can't patch all the related runtime data easily). In my experience as a maintenance programmer it was finding/analysing the bug that took most of the time, and the patching/recomplile being the trival part. If they have THAT many minor errors then better code review might be much more productive.

--------------------------------------------[size="1"]Ratings are Opinion, not Fact
Yeah I can agree with that. However I view this as more of a utility bar without limitations or the need to program it. Like a bar that you can slide back and fourth in game to change specular values. With grim rocks implementation there's no limitations and can be used on a lot more. I am willing to do just as they did only having the audio and render components in c++

There are two ways to do this on Windows.

One way is to use Win32 API functions ReadDirectoryChanges coupled with WaitForSingleObject in another thread. I personally found this to be a pain in the ass when trying to implement it myself, so i found a project somewhere on the interwebz and just took it for granted it will do what i need. This will give you notifications about any file that changes in a specific directory of your choosing.

The other way is to use GetFileTime coupled with CompareFileTime function. When you read the file the first time, read it's modification time and store it. Each time through the game loop, for each file you're interested in, read the modification time again, compare it with the stored time and if it's newer, read it again, because you know it's been modified from the last time you used it.

devstropo.blogspot.com - Random stuff about my gamedev hobby

I have done similar thing about 3-4 years ago for my previous company engine. We have bound all the major classes to the lua, and also provided support for dynamic reloading and the lua console that one could remotely connect to and modify certain values, call functions etc. It was working better than expected. It led us to code entire game logic using lua ( it wasn't anything requiring great performance though, but an education game for children, so performance was very satisfying ). The major reason of going this way was the fact that we wanted to be able to distribute additional content which could include new sets of minigames etc. but without any need of coding it in the game and updating it in the appstore. In other words - for DLC smile.png. Hence, it had to be 100% data driven approach. Since our major platform was iOS, where's no JIT allowed (haven't been touching iOS since then, so maybe it changed ;) ), using lua came very handy.

As for editor, we didn't make anything custom. There are text editors supporting lua already. From the point of view of scripts deployment, the entire game didn't have to be reinstalled again. Scripts could be replaced using the remote console in the runtime.

As for the details, we used lua metatables to mimic classes and OO behaviour. It was a bit of headache to make sure that nothing was leaking as objects could be created on both sides - native and through scripting (lua uses ref counting, we used it as well for anything bindable, n refs on the lua side was 1+ ref on the native side ). lua script had to implement simple interface responsible for updating certain entity/actor/object (whatever you call it). When script was bound to the object, the update state was just executing it and that's it.

I find it most easy to simply have a reload script key in the game so i can click it to relead all the scripts when i'm done changing them.

Some information on interfacing C++/Lua can be found at https://eliasdaler.wordpress.com/2013/10/11/lua_cpp_binder . I also have a page about lua on my website at http://www.gamedevpensieve.com/programming/language/lua .

@spinningcubes | Blog: Spinningcubes.com | Gamedev notes: GameDev Pensieve | Spinningcubes on Youtube

Thank you for all your replies. Should I use luaJIT?

Yeah for script reloading, the simplest solution is just bind your "load all lua scripts" function to a key, so you can call it again later.

You should be careful how you write your Lua code though, such that it can be executed multiple times without too many surpises.
E.g. Compare these two Lua files:
A)
foo = {}foo.blah = 42
B)
foo = foo or {}foo.blah = 42
(A) creates a new table containing an 'blah'=>42, and assigns it to the global variable 'foo'. If 'foo' already had a value, it is lost.
(B) only creates a new table if the global variable 'foo' doesn't already exist, and then assigns foo's member 'blah' to 42.
If 'foo' did already exist and contained other members, they will persist.

(B) is a more "reload friendly" coding style, as it's less likely to accidentally throw away game state when re-executing a Lua file :)
Little things like this might bite you arse from time to time.


For an IDE you really do want one that can integrate with your game, allowing you to catch errors, set breakpoints, step over code line-by-line, and inspect state.
Check out:
https://github.com/jjensen/lua-tilde
And:
http://unknownworlds.com/blog/lua-ide-decoda-open-source/

Should I use luaJIT?

If you're using Lua 5.1, you can switch to LuaJIT later with no changes required to your Lua code; it's a drop-in replacement :)
It's waaaaaay faster than regular Lua, but not as friendly for debugging when things go wrong.

I actually wonder about the utility of the patching feature -- and would want to see real world statistics about how frequently runtime code patching actually is done and how often the needed patch changes STILL required restarting everything anyway (the scripter has to consider/judge what the code change affects, as they can't patch all the related runtime data easily).

Imagine a simple tweaking GUI, where I can click on a slider to change the enemy's Hit Points during a battle, playing it over and over until it feels right.
Now picture the same thing, but instead of dragging a simple slider, I've got full control over all of their behaviours, priorities, pathfinding and animation code.
I can tweak any of that logic and see the results a second later. That means I can try out several AI tweaks per minute. If I have to quit the game and recompile, I can probably try out one iteration once per every several minutes :(

For iteration/tweaking type tasks, it's invaluable.

For bug-fixing type tasks, yeah it's less useful -- usually your game state is too invalid to continue even if you can fix it and reload. However, the dynamism of Lua is really useful in allowing you to enable/disable/hack code at runtime, to very quickly get the gamestate intoba situation where you can reproduce a bug you're looking for.

This topic is closed to new replies.

Advertisement