Skip to content

About

Pumpkin plugin API for Zig

Topics

Resources

Contributing

Stars

6 stars

Watchers

1 watching

Forks

Repository files navigation

Pumpkin API for Zig

This package provides Zig bindings for building Pumpkin plugins using WebAssembly (Wasm) components.

Requirements

Setup

Add a release of the package to your project:

zig fetch --save git+https://github.com/Pumpkin-MC/pumpkin-api-zig#v0.2.1

The releases list every version, and to update you run the command again with the new one. main contains unreleased changes. If you are working on the API itself, point the dependency at a local checkout instead:

.dependencies = .{
    .pumpkin_api_zig = .{ .path = "../pumpkin-api-zig" },
},

Then create a build.zig:

const std = @import("std");
const pumpkin_api = @import("pumpkin_api_zig");

pub fn build(b: *std.Build) void {
    _ = pumpkin_api.addPlugin(b, b.dependency("pumpkin_api_zig", .{}), .{
        .name = "my-plugin",
        .root_source_file = b.path("src/main.zig"),
    });
}

zig build produces zig-out/my-plugin.wasm. Copy it into the server's plugins folder and restart the server.

Dependencies

Other Zig packages are added through .imports. They have to be built for the same target as the plugin, which pumpkin_api.target(b) returns:

const std = @import("std");
const pumpkin_api = @import("pumpkin_api_zig");

pub fn build(b: *std.Build) void {
    const sqlite = b.dependency("sqlite", .{
        .target = pumpkin_api.target(b),
        .optimize = .ReleaseSmall,
    });

    _ = pumpkin_api.addPlugin(b, b.dependency("pumpkin_api_zig", .{}), .{
        .name = "my-plugin",
        .root_source_file = b.path("src/main.zig"),
        .imports = &.{.{ .name = "sqlite", .module = sqlite.module("sqlite") }},
    });
}

addPlugin also returns the plugin's root module, for anything else the build needs, such as C sources of your own:

const plugin = pumpkin_api.addPlugin(b, api, .{ ... });
plugin.module.addCSourceFile(.{ .file = b.path("src/helper.c") });
plugin.module.link_libc = true;

C libraries work too, including ones that link libc, since Zig builds them against wasi-libc. What a library can't use is anything WASI doesn't provide to plugins, such as threads or child processes.

A plugin

const std = @import("std");
const pumpkin = @import("pumpkin");
const cmd = pumpkin.cmd;
const msg = pumpkin.msg;

pub const std_options: std.Options = .{ .logFn = pumpkin.logFn };

const MyPlugin = struct {
    pub const metadata: pumpkin.Metadata = .{
        .name = "my-plugin",
        .version = "0.1.0",
        .authors = &.{"You"},
        .description = "Says hello.",
    };

    pub const events = .{
        .player_join_event = onJoin,
    };

    pub const commands: []const cmd.Spec = &.{.{
        .names = &.{ "hello", "hi" },
        .description = "Says hello.",
        .permission = "my-plugin:command.hello",
        .run = hello,
    }};

    pub fn onLoad(_: pumpkin.Context) !void {
        std.log.info("loaded", .{});
    }

    fn onJoin(_: pumpkin.Server, ev: *pumpkin.EventData(.player_join_event)) void {
        ev.join_message = msg.build(&.{
            .{ .text = "+ ", .color = .green, .bold = true },
            .{ .text = ev.player.getName(), .color = .yellow },
        });
    }

    fn hello(sender: cmd.Sender, _: pumpkin.Server, _: cmd.Args) cmd.Result {
        sender.sendMessage(msg.fmt(.gold, "Hello, {s}!", .{sender.getName()}));
        return cmd.ok(1);
    }
};

comptime {
    pumpkin.register(MyPlugin);
}

examples/ has a small plugin for each part of the API, and zig build builds them all into zig-out/:

Example Shows
hello Events, a command and styled text
heal Command arguments read with cmd.typed
menu Inventory menus with buttons, and a trash can with free slots
config A TOML config file that can be reloaded
dns Looking up the addresses of a host name
http A TCP connection with a timeout and a plain HTTP request
https HTTPS with std.http.Client
tcp-server A TCP server that bridges the chat, polled from a task
udp Receiving and answering UDP datagrams
tasks Delayed and repeating tasks that carry a value
items Building, editing and recognizing items, and giving and taking them
store Data kept for every player in a file of its own
prompt Questions answered in chat and choices to click
vault Personal storage with a page selector, usage indicators and configurable capacity
realm An economy built with every helper: shop, daily rewards, payments, cheques and coin rushes
nettest Runs every networking path with /nettest and reports each one

Working on the bindings

git submodule update --init
zig build test   # unit tests for the ABI layer and the generator
zig build check  # compiles every generated binding
zig build gen    # regenerates src/bindings/

CONTRIBUTING.md explains how the repository is laid out and what a pull request needs.

The Pumpkin bindings are generated from the wit submodule, pumpkin-plugin-wit.

The WASI bindings come from wasi/. wasi/world.wit lists the WASI interfaces plugins get bindings for, currently wasi:sockets and what it depends on. Their definitions in wasi/deps/ are fetched from the wasi.dev registry with wkg, pinned in wasi/wkg.lock. To change them, edit world.wit and run wkg fetch . inside wasi/, then zig build gen. The WASI interfaces and everything derived from them in src/bindings/wasi/ are © the Contributors to the WASI Specification, published by the WebAssembly Community Group under the W3C Community Contributor License Agreement, see wasi/LICENSE.md.

adapter/wasi_snapshot_preview1.reactor.wasm is the WASI preview 1 adapter from Wasmtime 48.0.2 (Apache-2.0 WITH LLVM-exception). Zig emits WASI preview 1, and the adapter maps it onto the preview 2 interfaces the server provides. The WASI version in wasi/world.wit has to stay the one the adapter imports.

To make a release, set the new version in build.zig.zon, commit it and push a matching tag such as v0.1.0. The Release workflow checks that the tag and build.zig.zon agree, runs the tests, and publishes a GitHub release with the example plugins and the plugin API revision it was built against.

About

Pumpkin plugin API for Zig

Topics

Resources

Contributing

Stars

6 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages