Garry's Mod Wiki

Creating Binary Modules

Creating Binary Modules

Binary modules allow you to extend Lua's functionality using C++.

Dependencies

Binary Modules only need CMake and a C++ compiler for building.

You can install both through either the Visual Studio Installer ("Desktop development with C++" in Visual Studio 2019) on Windows, Xcode/homebrew on macOS, or by using your favorite package manager on Linux. For CMake, downloads are also available on the CMake website.

If you want to use an IDE, you should be able to choose any as long as it has support for CMake projects (Visual Studio, CLion, etc.).

If you don't want to use an IDE you can also build the module manually, but that approach will not be detailed in this guide.

Project setup

The headers you need are available here. They will provide your project with information about how to interface with the game and set a few common settings for compiling the module.

First, create an empty folder. This will contain all the files related to your module and will be referred to as "main folder" from now on.

Now, download a copy of the headers into a subfolder of the main folder. While you can name it freely, for this guide I will use gmod-headers as the name of the subfolder. You will have to replace that name accordingly if you chose something different. To check whether you extracted the files in the correct location, make sure that the paths gmod-headers/include and gmod-headers/examples are present in the main folder.

Next, we will set up a CMake project definition. To do that, create a file called CMakeLists.txt in the main folder and paste the following content in there:

cmake_minimum_required(VERSION 3.10) # The project name is rather unimportant and you can name it anything you want. # It just mustn't conflict with the module name that is defined further below. project(gmod-module-guide LANGUAGES CXX) set(CMAKE_CONFIGURATION_TYPES Release Debug) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Load the gmod-module-base project that sets up headers and settings. add_subdirectory(gmod-headers/include) # The library name defined here (in this case, "testmodule") will be the name of the module. add_library(testmodule SHARED) # Add the source files required for the module. # Again, the file names don't matter and you can even add multiple files by adding more space-delimited filenames after "module.cpp". target_sources(testmodule PRIVATE module.cpp) # Actually apply the headers and settings to our module. target_link_libraries(testmodule gmod-module-base) set_gmod_suffix_prefix(testmodule)

Now that we have our project defined, we just need something that we can compile into a module.

For demonstration purposes the "Hello World" example works just fine, so copy gmod-headers/examples/HelloWorld/HelloWorld.cpp and paste it into the main folder as module.cpp. This file you can now change and experiment with.

For building, simply open the main folder in your chosen IDE (any half-decent one should detect the CMakeLists.txt file and set up a CMake project) and press "Build" in there. Developers without IDE can now follow any existing "how to build a CMake project" guide. The binary module will end up whereever the CMake output was placed, with the correct name already applied.

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.

File name Side require(name) Platform
gmsv_example_win32.dll Server example Windows x32
gmcl_example_win32.dll Client example Windows x32
gmsv_example_win64.dll Server example Windows x64 (x86-64 branch is required)
gmcl_example_win64.dll Client example Windows x64 (x86-64 branch is required)
gmsv_example_osx.dll Server example OSX (actually a .so file, just renamed)
gmcl_example_osx.dll Client example OSX (actually a .so file, just renamed)
gmsv_example_linux.dll Server example Linux x32 (actually a .so file, just renamed)
gmcl_example_linux.dll Client example Linux x32 (actually a .so file, just renamed)
gmsv_example_linux64.dll Server example Linux x64 (actually a .so file, just renamed; x86-64 branch is required)
gmcl_example_linux64.dll Client example Linux x64 (actually a .so file, just renamed; x86-64 branch is required)
Menu state modules are categorized under gmsv_name_platform.dll

Special Pages


Wikis

?

Render Time: 23ms

DB GetPage 2
Generate Html 3
SaveChanges (1) 7
Render Body 0
Render Sidebar 8