-
Notifications
You must be signed in to change notification settings - Fork 8
Native Go Plugins
Native Go plugins are experimental. Each plugin runs as its own process and communicates with GoCraft through a versioned, protocol-neutral Plugin API. A panic or process crash therefore does not directly crash the server.
Put its .gcpkg file in plugins/ and restart GoCraft. The server discovers bundles before opening its network listeners — a failed plugin prevents startup rather than leaving gameplay partly protected.
Configuration defaults stored under config/ inside the bundle are copied on first load to plugins/<plugin-id>/. Existing administrator files are never overwritten. Context.DataDirectory() returns that directory.
Implement gocraft.Plugin:
import gocraft "github.com/GoCraft-MC/gocraft-api-go"
type Plugin struct{}
func (*Plugin) OnLoad(ctx gocraft.Context) error { return nil }
func (*Plugin) OnEnable() error { return nil }
func (*Plugin) OnDisable() error { return nil }OnLoad receives the logger, event registry, command registry, scheduler, and data directory — register callbacks there. OnEnable runs after loading; OnDisable runs during orderly shutdown or failed-enable cleanup.
Listeners and command callbacks run synchronously and serially for one plugin — do not block them. Scheduler callbacks run asynchronously. When a plugin is disabled, GoCraft unregisters its listeners and commands and cancels its tasks. Panics at every callback boundary are recovered and logged with a stack trace.
The shared schema exposes native events. The two core events:
| Event | Timing | Cancellable |
|---|---|---|
PlayerJoinEvent |
after the player is reachable | no |
BlockBreakEvent |
before the block mutation | yes |
Java and Bedrock actions produce the same event types. No packet or numeric protocol IDs are exposed. Cancelling BlockBreakEvent keeps the block intact for either edition.
ctx.Events().OnBlockBreak(func(event *gocraft.BlockBreakEvent, control gocraft.EventControl) {
if event.Block.ID == "minecraft:diamond_block" {
control.Cancel()
}
})Commands are declared in the bundle's generated commands.pb. Register a callback against the path through that tree during OnLoad:
ctx.Commands().Register("shop sell <price>", func(call *gocraft.CommandContext) error {
call.Reply("Hello, " + call.SenderName)
return nil
})Register the path, not the executor ID. Literals appear as written; arguments are in angle brackets — the same spelling a Java plugin uses. A path that names nothing in the bundle is refused at load (listing the paths the bundle declares) rather than becoming a handler that silently never runs.
The host owns everything before the callback: it matches the line against the tree, resolves each argument to its declared type, and checks the permissions guarding the path. The plugin never sees the raw line — typed values arrive through CommandContext.Args, and call.Can answers from host-resolved permissions.
Replies are queued as effects and delivered on the next tick (the same path event-handler effects take), so they reach players on either edition and the console alike.
Both editions are told about the command — Java receives a Brigadier graph, Bedrock a flat signature per way of running it — because the host renders one neutral tree twice. Each player is sent only the branches their permissions allow, and the list is resent when a plugin loads or unloads while they are online.
See gocraft-plugin-examples for a complete plugin. Build its executable for the server OS, place it at the manifest's entry, then package it:
go install github.com/GoCraft-MC/gocraft-cli@latest
gocraft-cli build -o my-plugin.gcpkg ./my-pluginThe build tool is its own module (a plugin author compiles; they never run a server). It reads the bundle format from the same code the server does.
Native binaries are OS- and architecture-specific. Hot reload and in-process unloading are not supported. Rebuild plugins after a Plugin API version change — the host rejects incompatible manifests before executing code.
GoCraft — native-Go Minecraft server · Java 1.21.4 + Bedrock 1.26.45 cross-play · GPL-3.0 · © 2026 Oreo Studios · Discord
Playing on GoCraft
Server & cross-play
Internals