Skip to content

Getting Started with Plugins

This guide walks you through creating your first HoloMUSH plugin. By the end, you will have a working Lua plugin that responds to in-game speech.

You need a running HoloMUSH server. If you have not set one up yet, follow the Installation Guide first.

You also need a text editor and a way to connect to the server (telnet or the web client).

Plugins live in the plugins/ directory under the HoloMUSH data path. Each plugin gets its own subdirectory:

Terminal window
mkdir -p plugins/greeter

Your plugin needs two files: a manifest that tells the server what your plugin does, and a Lua script that handles events.

Create plugins/greeter/plugin.yaml:

name: greeter
version: 1.0.0
type: lua
events:
- say
policies:
- name: "emit-events"
dsl: |
permit(principal is plugin, action in ["emit"], resource is stream) when {
principal.plugin.name == "greeter"
};
lua-plugin:
entry: main.lua

This tells HoloMUSH:

  • name — A unique identifier for your plugin.
  • type — This is a Lua plugin (no compilation needed).
  • events — Subscribe to say events (character speech).
  • policies — Request permission to emit events back to streams.
  • lua-plugin.entry — The Lua file to load.

Create plugins/greeter/main.lua:

function on_event(event)
-- Only respond to say events
if event.type ~= "say" then
return nil
end
-- Ignore messages from other plugins (prevents loops)
if event.actor_kind == "plugin" then
return nil
end
-- Parse the message from the JSON payload
local msg = event.payload:match('"message":"([^"]*)"')
if not msg then
return nil
end
-- Respond to greetings
if msg:lower():match("^hello") or msg:lower():match("^hi") then
return {
{
stream = event.stream,
type = "say",
payload = '{"message":"Hello! Welcome to HoloMUSH."}'
}
}
end
return nil
end

The on_event function is called every time an event your plugin subscribed to arrives. It receives an event table and can return a list of new events to emit, or nil to do nothing.

Restart the HoloMUSH server to pick up the new plugin. Then connect and try it out:

> connect testuser password
Welcome back, TestChar!
> say Hello everyone!
You say, "Hello everyone!"
Greeter says, "Hello! Welcome to HoloMUSH."

If the plugin does not respond, check the server logs for loading errors. Common issues:

  • YAML syntax error — Validate your plugin.yaml with a YAML linter.
  • Missing policy — Without the emit-events policy, the plugin can receive events but cannot send any back.
  • Lua syntax error — The server logs the specific line and error message.

Here is the flow:

  1. You typed say Hello everyone!
  2. The server created a say event on the location’s stream.
  3. The greeter plugin received that event (because it subscribes to say).
  4. Your on_event function matched the greeting and returned a new say event.
  5. The server emitted that event, and everyone in the location saw the response.
  • Read the Plugin Guide for the full picture: binary plugins, host functions, world queries, ABAC policies, and error handling.
  • See the Event Reference for all available event types and their payload schemas.
  • Browse the example plugins for more patterns.