Garry's Mod Wiki

Creating Binary Modules: Rust

Unlike C++, Rust doesn't require an hour of CMake/other tweaking to build a project, you just need to have Cargo.

To create binary modules in Rust, there are now two main crates (libraries) - gmod-rs and rglua (the library defines functionality and structure).

They both have different but similar approaches to writing code, as well as different functionality and threshold of entry.

In this article we will look at the gmod-rs crate (library) from WilliamVenner.

Dependencies

Install rust from official site, in one installer you will have Cargo (package manager), and the Rust compiler itself at once.

Rust analyzer (LSP)

If you want, you can install rust-analyzer (it's a set of utilities for easy code writing, including Language Server and other goodies) for your IDE.

To install it on vscode, all you need to do is install the official extension from marketplace

Setup a new project

To create a new project on Rust you just need to write one command - cargo new <project name> --lib.

cargo new my_gmod_dll --lib

Congratulations! You have initialized your Rust project.

Configuring the project

Now let's customize our project for gmod:

  1. Install gmod-rs as a dependency:
cargo add gmod
  1. Add these lines to the Cargo.toml file:
[lib] crate-type = ["cdylib"]

It should be something like this:

[package] name = "my_gmod_dll" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] gmod = "17.0.0"
  1. Set the nightly toolchain:
rustup override set nightly

Modifying the code

Our project is almost ready, we only need to change the source code of the lib.rs file - in this case it is a entrypoint file, and it is the analog of main.cpp in C++.

Open the lib.rs file and remove everything from there.

Put this code in it:

use gmod::{gmod13_close, gmod13_open, lua::State}; #[gmod13_open] fn gmod13_open(lua: State) -> i32 { println!("Hello from Rust!"); 0 } #[gmod13_close] fn exit(_: State) -> i32 { 0 }

Done! Your project only needs to be builded, and then you can start explore the gmod-rs crate (library) and working with Lua stack!

As you can see, the gmod13_open and gmod13_close functions are fluffed with the State argument. This is an object that is the interface between Lua and your binary module. Through it we can control the Lua stack.

Building

WilliamVenner provides ready-made CLI commands in the gmod-rs repository for building the project, but I'll duplicate them:

Platform Command Description
win32 cargo build --target i686-pc-windows-msvc Windows 32-bit
Use this if your server is running Windows and is on the main branch of Garry's Mod (this is the default branch.)
win64 cargo build --target x86_64-pc-windows-msvc Windows 64-bit
Use this if your server is running Windows and is on the x86-64 branch of Garry's Mod.
linux cargo build --target i686-unknown-linux-gnu Linux 32-bit
Use this if your server is running Linux and is on the main branch of Garry's Mod (this is the default branch.)
linux64 cargo build --target x86_64-unknown-linux-gnu Linux 64-bit
Use this if your server is running Linux and is on the x86-64 branch of Garry's Mod.

After the project has been successfully built, find the built .dll (.so on unix-like systems), and rename it according to the desired result as written here.

You can find the compiled binary in target/<TARGET>/debug/my_gmod_dll.dll on Windows or target/<TARGET>/debug/libmy_gmod_dll.so on Linux.

If you want to build the project in release mode, then add the --release flag to the build command.

Conclusion

I don't want you to think that everything is easy in Rust, since we have such handy tools. Yes, unlike C++, our tools are very handy, but the language itself takes a long time to get used to. So if you are thinking about learning it, think a couple of times whether it is worth it.