✍️ Your first Rust mod¶
This tutorial takes you from nothing to a Rust mod: first it writes its first log line on the server, then it greets players as they join. You need some Rust, not a lot.
Before you start¶
- The Rust toolchain: install rustup; on Windows the default MSVC target is the right one.
- A server with Pier installed, to test on. If you have none yet, see Installation.
Step one: create a project¶
The quickest way is the template. On its GitHub page, click Use this template to get a repository of your own, or generate a local copy:
| Bash | |
|---|---|
The template is a mod that runs as it is: it logs, subscribes to chat and stops one message, registers a command and schedules a delayed task. Delete what you don't need.
To start from nothing instead, create a library project and make Cargo.toml this:
| TOML | |
|---|---|
crate-type = ["cdylib"] makes cargo build a DLL, which is what the server loads.
The dependency is called pier-rs, while the code says use levilamina::...: the crate the
package exposes is named levilamina.
Step two: write the entry point¶
Make src/lib.rs this:
| Rust | |
|---|---|
When the server loads the mod it calls on_load, and your mod logs hello from Rust.
register_mod! on the last line generates the entry function the server looks for. Without
it, the mod is refused at load.
Step three: write the manifest¶
Create manifest.json at the root of the project:
| JSON | |
|---|---|
Three things must line up:
nameis the name of the mod's folder under the server'splugins/;entryis the name of the file cargo builds. cargo turns the hyphens of the package name into underscores, somy-modbuildsmy_mod.dll;typeispier, which is what makes Pier take it over.
Step four: build, install, look¶
| Bash | |
|---|---|
Then make a my-mod folder under the server's plugins/ and put
target/release/my_mod.dll and manifest.json in it:
Start the server and look for hello from Rust in the log. When it is there, your first mod
is running. /pier list in the console shows my-mod too.
Step five: greet players as they join¶
Now make the mod do something: when a player joins, write their name to the log.
Subscribe while enabling, and keep the listener the call returns: dropping it ends the subscription.
Build again, replace the DLL, restart the server and join: your name appears in the log.
_player.name is a field Pier adds to the event; which fields each event has is in the
event payload reference.
When nothing happens¶
Go through these in order; each one rules out one cause:
- Your mod is not in
/pier list: check thatmanifest.jsonsays"type": "pier", then thatnamematches the folder. With the wrong type the mod is never found, and the log says nothing. - The log has a line refusing the load: read it. Pier says which check failed: the table size, the ABI version, or the target. A target mismatch means a client mod on a server, or the reverse.
- It loaded, but the subscription never fires: the event name is almost always wrong.
Run
/pier eventsin the console to see the names, and use the constants ofnames::, which turn a typo into a compile error. - A call returns "not provided": the Pier on this server was built without that
capability. The error names the slot;
ctx.host_abi()gives the ABI version and table size to include in a report.
Next¶
- 🔄 Lifecycle and logging: when each of the four stages happens and what belongs in it
- 📣 Events: reading the payload, cancelling
- ⌨️ Commands: give your mod a command