Guides

Mudlet with open-source tools

This guide outlines the architecture for a robust, performant Mudlet scripting environment. It focuses on namespace isolation, efficient trigger management, and event-driven UI updates to ensure your scripts scale without impacting client responsiveness.

60 minutes6 steps
Mudlet with open-source tools hero illustration
1

Establish a Script Namespace

To prevent variable collisions with other packages or Mudlet's internal functions, encapsulate all logic within a single global table. This makes your code modular and easier to debug via the Lua console.

init.lua
MyProject = MyProject or {}
MyProject.stats = MyProject.stats or {}
MyProject.configs = MyProject.configs or { debug = true }

function MyProject.echo(msg)
  cecho(string.format("<white>[<blue>MyProject<white>] %s\n", msg))
end

⚠ Common Pitfalls

  • Declaring variables without 'local' inside functions, which pollutes the global environment.
  • Overwriting existing Mudlet functions like 'send' or 'echo' by not using a namespace.
2

Implement an Efficient Prompt Trigger

The prompt is the most frequently updated element. Use a regex trigger that matches your MUD's prompt format and raises a custom event. Raising an event allows other scripts to update without being hard-coded into the trigger itself.

trigger_pattern
^(\d+)h, (\d+)m, (\d+)v\s-

⚠ Common Pitfalls

  • Using wildcards like '.*' which force the regex engine to backtrack, increasing CPU load.
  • Putting heavy logic (like UI redraws) directly inside the trigger script instead of using events.
3

Register Event Handlers for UI Updates

Use Mudlet's event system to decouple data processing from display. This ensures that UI elements like gauges only update when the underlying data actually changes.

events.lua
function MyProject.updateGauges(_, hp, maxhp)
  hpGauge:setValue(hp, maxhp)
end

if MyProject.handlerID then killAnonymousEventHandler(MyProject.handlerID) end
MyProject.handlerID = registerAnonymousEventHandler("onPromptUpdate", "MyProject.updateGauges")

⚠ Common Pitfalls

  • Failing to kill old anonymous event handlers when re-saving scripts, leading to memory leaks and duplicate execution.
  • Triggering events too frequently, which can cause UI flickering.
4

Configure the Automapper for Room Tracking

Initialize the Mudlet mapper and create a basic script to capture room names and exits. Use 'centerview' to keep the visual map synchronized with your character's movement.

mapper.lua
function MyProject.handleRoomDetection(name, exits)
  local roomID = mmp.searchRoom(name, exits)
  if roomID then
    centerview(roomID)
  else
    MyProject.echo("Room not found in map database.")
  end
end

⚠ Common Pitfalls

  • Assuming room names are unique; always validate against available exits to ensure correct room identification.
  • Attempting to move the mapper before the map database has been initialized or loaded.
5

Optimize Trigger Priority and Gates

Organize triggers into groups. Use 'disableTimer' or 'disableTrigger' for features not currently in use (e.g., combat triggers while idling) to save CPU cycles. Set high-frequency triggers to a lower priority number.

⚠ Common Pitfalls

  • Leaving all triggers active at all times, which degrades performance in high-spam environments.
  • Overlapping regex patterns that match the same line multiple times, causing redundant script execution.
6

Implement a Command Queue for Anti-Spam

Many MUDs have command limits. Create a local queue that sends commands at a fixed interval using a Mudlet timer, ensuring you don't get disconnected for flooding.

queue.lua
MyProject.queue = {}

function MyProject.processQueue()
  if #MyProject.queue > 0 then
    send(table.remove(MyProject.queue, 1))
  end
end

tempTimer(0.5, [[MyProject.processQueue()]], true)

⚠ Common Pitfalls

  • Not clearing the queue on death or character logout, leading to accidental command execution on reconnect.
  • Setting the timer interval too low, which still triggers the MUD's flood protection.

What you built

A successful Mudlet implementation relies on keeping the global scope clean and using events to handle data flow. By isolating your project in a namespace and optimizing trigger execution, you create a script base that remains responsive even during intense combat or high-traffic scenarios.