Lua ~ Research on Passing Structs via Lua AND C - uchicago-cs/chiventure GitHub Wiki
Sample LUA Files and C Files
As we had outlined in our issue, we were going to be making some sample C files and lua scripts which would showcase how the contents withing C structs cold be modified using Lua. To show the proof of concept, we created our own struct called "chest" which had an integer variable called "coins" which was passed between C and LUA and subsequently modified.
The details of the code are located inside the custom-scripts sandbox and can be found at the following location: https://github.com/uchicago-cs/chiventure/tree/custom-scripts/src/custom-scripts/sandbox
Summary of Code
Essentially we created a simple Lua script with a function called "change" that would essentially alter the value of the "coins" variable inside the C struct "chest". In the above code, the value of coins is initially set to "0" but later changes to "10" as the variable gets pushed to the virtual stack from which Lua gets hold of the variable and applies the "change" function to it.
Moving forward, we try to explore different ways that we can pass C structs directly to Lua instead of pushing and popping each individual fields within a struct (strings, integers, bools, etc) onto Lua stack, as we think this might be a bit space-inefficient.
From my research, there are 2 ways to pass C structs back and forth from Lua:
- The first way is turning C structs into Lua tables. Tables are the only data structure available in Lua, and they work like associative arrays, which can be indexed with not only numbers but also with strings except nil. To perform certain operations on Lua objects, we would have to write C functions that specify the methods (addition, subtraction, concatenation,...) that can be operated on elements from that Lua table (these methods will be called Lua metatable). This is an example link: https://gist.github.com/bloodstalker/91261e541666f16c3b8315d3ff1085d6.
One thing to note about this is that the functions specified in .c file will determine and restrict the operations we can do on the C structs that are passed into Lua, so if we follow this way, we have to cover all possible ways (methods) that game authors are allowed to change these C structs, and the Lua files will just cover the specific cases. Thus, my main concern about this is that it may not give game authors enough flexibility on changing the game state through Lua, instead of C. If we choose this way, then we have to be very comprehensive about what types of chiventure structs can be accessed and modified from Lua, and what are all possible changes that Lua is allowed to operate on these structs.
- The second way is using SWIG library - it is an open-source software tool used to connect computer programs or libraries written in C or C++ with scripting languages like Lua. This is the link to the documentation of SWIG for C and Lua integration: http://www.swig.org/Doc1.3/Lua.html#Lua_nn13 From my understanding, SWIG allows you to wrap C structure to Lua userdata, so you can access and use the struct very flexibly from within Lua. I think SWIG handles all the metatable and table setup while passing these structs around. This is an example extracted from the documentation that shows the passing of C structs to Lua:
One advantage of this is that game authors from the Lua side can access these Structs and modify them in whatever way they can within Lua, without having to be restricted to a set of methods specified in C. One disadvantage of this is that we would have to write interface files in addition to c files and lua files if we use SWIG, thus adding more complications to the custom script. Example:
To conclude, more research needs to be done on the advantages and disadvantages of using Lua built-in functionality vs SWIG as we get a better idea of what kinds of custom script we can provide to other Chiventure’s features like NPC, game state, ...