Pumpkin-Docs/docs/en/plugin-dev/d/quick-start.md
Alexander Medvedev 5c23b676ed feat: d binding
2026-09-17 09:23:24 +02:00

136 lines
3.6 KiB
Markdown

# Quick Start
This guide will help you get started with writing Pumpkin server plugins using the [D programming language](https://dlang.org/).
D plugins for Pumpkin compile to WebAssembly (Wasm) components using the official [`pumpkin-api-d`](https://github.com/Pumpkin-MC/pumpkin-api-d) bindings.
---
## Prerequisites
Before building D plugins for Pumpkin, ensure you have the following installed:
- **[LDC](https://github.com/ldc-developers/ldc)**: Version 1.43 or later (LLVM-based D compiler).
- **`addon-wasi`**: The WASI target package for LDC.
- **[DUB](https://dub.pm/)**: The D package and build tool (usually included with LDC).
---
## 1. Setting Up the Project
Create a new directory for your plugin project and add a `dub.json` configuration file:
```bash
mkdir my-d-plugin
cd my-d-plugin
```
Create `dub.json` in the project root:
```json [dub.json]
{
"name": "my-d-plugin",
"description": "A minimal Pumpkin plugin built with D.",
"license": "proprietary",
"authors": ["You"],
"copyright": "Copyright © 2026, You",
"dependencies": {
"pumpkin-api-d": "~>0.1.0"
},
"targetType": "executable",
"dflags": ["-Xcc=-mexec-model=reactor"],
"buildTypes": {
"debug": {
"buildOptions": ["debugMode", "debugInfo"]
},
"release": {
"buildOptions": ["optimize", "inline"],
"dflags": ["-L-S"]
}
}
}
```
> [!NOTE]
> The flag `-Xcc=-mexec-model=reactor` is required by the WebAssembly linker so that the plugin is treated as a reactor (a component exposing entry points) rather than a command-line program with an exit point.
---
## 2. Writing the Plugin
Create a `source` directory and place your code in `source/app.d`:
```d [source/app.d]
module plugin;
import wit.pumpkin.plugin.plugin;
import wit.common;
import pumpkin.register;
struct MyPlugin {
@GetMetadata PluginMetadata getMetadata()
{
immutable(WitString)[$] authors = [
"You".witList
];
return (immutable PluginMetadata(
name: "my-d-plugin".witList,
version_: "0.1.0".witList,
authors: authors.witList,
description: "An example plugin in D.".witList,
dependencies: WitList!WitString(),
permissions: WitList!WitString()
)).witClone;
}
@OnLoad
Result!(void, WitString) onLoad(Context ctx)
{
scope (exit)
ctx.witDrop; // Incoming resources must be cleaned up after use
log(Level.info, "Hello from D plugin!".witList);
return ok!WitString;
}
}
mixin RegisterPlugin!MyPlugin;
```
### Key Elements:
- **`@GetMetadata`**: Defines plugin information (name, version, authors, description, permissions) requested by Pumpkin when loading the component.
- **`@OnLoad`**: Entry point invoked when Pumpkin initializes the plugin. Ensure incoming context resources (`ctx`) are freed with `ctx.witDrop`.
- **`mixin RegisterPlugin!MyPlugin;`**: Generates the necessary WebAssembly component exports and boilerplate required by Pumpkin's WASM loader.
---
## 3. Building the Plugin
Compile your plugin into a WebAssembly component targeting `wasm32-wasip2`:
```bash
dub build -b release -a wasm32-wasip2
```
This generates `my-d-plugin.wasm` in your project root.
---
## 4. Running Your Plugin
1. Copy the compiled `.wasm` file to your server's `plugins/` directory:
```bash
cp my-d-plugin.wasm /path/to/pumpkin/plugins/
```
2. Start or restart Pumpkin:
```bash
./pumpkin
```
3. Check the server logs to verify your plugin loaded:
```text
[INFO] Hello from D plugin!
```