Creating Binary Modules
Binary modules allow you to extend Lua's functionality using C++.
The headers you need and an example are available here.
To turn the example into a visual studio project you should download premake4, place the premake5.exe file in the same directory as BuildProjects.bat (or ideally in your main windows folder), and then run BuildProjects.bat.
This will then create a folder called "windows-vs2010", which contains the Visual Studio project file.
Read up on how to use Premake to compile your modules for osx/linux.
A note on userdata & metatables
Userdata and metatables are handled differently in Garry's Mod. This helps the engine determine userdata type much faster.
First create your metatable (ideally in GMOD_MODULE_OPEN), then create a reference to it and store it globally in a variable.
LUA->CreateTable(); LUA->PushCFunction(gcDeleteWrapper); LUA->SetField(-2, "__gc"); LUA->PushCFunction(toStringWrapper); LUA->SetField(-2, "__tostring"); LUA->PushCFunction(indexWrapper); LUA->SetField(-2, "__index"); LUA->PushCFunction(newIndexWrapper); LUA->SetField(-2, "__newindex"); metatable = LUA->ReferenceCreate();
To push your userdata to the stack:
GarrysMod::Lua::UserData* ud = ( GarrysMod::Lua::UserData* )LUA->NewUserdata( sizeof( GarrysMod::Lua::UserData ) ); ud->data = pointer_to_your_c_class; ud->type = your_type_id; LUA->ReferencePush( metatable ); LUA->SetMetaTable(-2);
To get your userdata from the stack:
GarrysMod::Lua::UserData* obj = (GarrysMod::Lua::UserData* )LUA->GetUserdata(position); your_c_class* var = (your_c_class*)(obj->data);
Naming & Location
The module files should be placed in the garrysmod/lua/bin/ folder.
The names differ between platform and Lua realm.
- gmcl_example_win32.dll - windows clientside module
- gmsv_example_win32.dll - windows serverside/menu state module
- gmcl_example_osx.dll - osx clientside module
- gmsv_example_linux.dll - linux serverside/menu state module
Converting From GMod 12
The interface in GMod 13 is very different to that of GMod 12 - the handy object wrappers are gone and the interface is very very similar to the standard Lua C API. Infact, nearly all of the functions in the interface work exactly the same way as their equivalents in the Lua C API, they're just named slightly differently.
You should be able to work out what most of the functions do from the example and the Lua C API Documentation.
If you find this kind of stack-level programming too hard, BlackAwps has created some "backwards headers", which should work exactly how the GMod 12 interface worked, you can find them here.