Area 51
This page is for the development of documentation for Lua API functions that are currently being worked on. Ideally the entries here can be created in the same format as will be eventually used in Lua Functions and its sub-sites.
Note: Please use the Area_51/Template to add new entries in the sections below.
Note: Links to other functions need to include the wiki page name before the '#' character in the link identifier on the left side of the '|' divider between the identifier and the display text. e.g.
- [[Manual:Lua_Functions#getCustomLines|getCustomLines()]]
rather than:
- [[#getCustomLines|getCustomLines()]]
which would refer to a link within the current (in this case Area 51) section.
Note: The following headings reflect those present in the main Wiki area of the Lua API functions. It is suggested that new entries are added so as to maintain a sorted alphabetical order under the appropriate heading.
Basic Essential Functions
- These functions are generic functions used in normal scripting. These deal with mainly everyday things, like sending stuff and echoing to the screen.
Database Functions
- A collection of functions for helping deal with the database.
Date/Time Functions
- A collection of functions for handling date & time.
File System Functions
- A collection of functions for interacting with the file system.
Mapper Functions
- A collection of functions that manipulate the mapper and its related features.
setRoomHidden, PR #8443
- setRoomHidden(roomID, hidden)
- Sets whether a room should be hidden on the 2D map. Hidden rooms are not drawn but still exist in the map data and can be used for pathfinding.
- See also: getRoomHidden(), getHiddenRooms()
- Parameters
- roomID:
- The ID of the room to modify.
- hidden:
- Boolean value - true to hide the room, false to show it.
- Returns
- true on success, or nil and an error message if the room ID is invalid.
- Example
-- hide room 1 from the map display
setRoomHidden(1, true)
-- show the room again
setRoomHidden(1, false)
-- hide all rooms in a specific area
for _, roomID in ipairs(getAreaRooms(5)) do
setRoomHidden(roomID, true)
end
getRoomHidden, PR #8443
- hidden = getRoomHidden([roomID])
- Returns whether a room is hidden on the 2D map.
- See also: setRoomHidden(), getHiddenRooms()
- Parameters
- roomID:
- (optional) The ID of the room to check. If not provided, uses the current player room.
- Returns
- true if the room is hidden, false if it is visible, or nothing if the room doesn't exist.
- Example
-- check if room 1 is hidden
if getRoomHidden(1) then
echo("Room 1 is hidden\n")
else
echo("Room 1 is visible\n")
end
-- check if current room is hidden
if getRoomHidden() then
echo("You are in a hidden room\n")
end
getHiddenRooms, PR #8443
- roomTable = getHiddenRooms()
- Returns a table of all hidden room IDs in the map.
- See also: setRoomHidden(), getRoomHidden()
- Returns
- A table with sequential integer keys (starting at 1) containing all hidden room IDs, or an empty table if no rooms are hidden. Returns nil and an error message if no map is loaded.
- Example
-- get all hidden rooms
local hiddenRooms = getHiddenRooms()
echo(string.format("There are %d hidden rooms\n", #hiddenRooms))
-- unhide all rooms
for _, roomID in ipairs(getHiddenRooms()) do
setRoomHidden(roomID, false)
end
-- list all hidden rooms
local hidden = getHiddenRooms()
if #hidden > 0 then
echo("Hidden rooms: " .. table.concat(hidden, ", ") .. "\n")
else
echo("No hidden rooms\n")
end
setRoomBorderColor, PR #8758
- setRoomBorderColor(roomID, r, g, b[, a])
- Sets a custom border color for an individual room on the 2D map. When set, this color overrides the global map border color for that specific room.
- Parameters
- roomID:
- The ID of the room to set the border color for.
- r:
- The red component of the color (0-255).
- g:
- The green component of the color (0-255).
- b:
- The blue component of the color (0-255).
- a:
- (optional) The alpha/transparency component (0-255). Defaults to 255 (fully opaque).
- Returns
- true on success, or nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- Set room 1 to have a red border
setRoomBorderColor(1, 255, 0, 0)
-- Set room 2 to have a semi-transparent blue border
setRoomBorderColor(2, 0, 0, 255, 128)
-- Mark all rooms with environment ID 5 (it could mean "outdoors" in your map, for example) with a green border
for _, roomID in ipairs(getRooms()) do
if getRoomEnv(roomID) == 5 then
setRoomBorderColor(roomID, 0, 200, 0)
end
end
getRoomBorderColor, PR #8758
- r, g, b, a = getRoomBorderColor(roomID)
- Returns the custom border color for a room, if one has been set.
- See also: setRoomBorderColor(), clearRoomBorderColor()
- Parameters
- roomID:
- The ID of the room to get the border color for.
- Returns
- Four numbers (r, g, b, a) if a custom border color is set, or nil if the room uses the global default border color. Returns nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- Check if room 1 has a custom border color
local r, g, b, a = getRoomBorderColor(1)
if r then
echo(string.format("Room 1 has custom border: RGB(%d, %d, %d) Alpha: %d\n", r, g, b, a))
else
echo("Room 1 uses the global border color\n")
end
clearRoomBorderColor, PR #8758
- clearRoomBorderColor(roomID)
- Removes the custom border color from a room, causing it to use the global map border color setting.
- See also: setRoomBorderColor(), getRoomBorderColor()
- Parameters
- roomID:
- The ID of the room to clear the custom border color from.
- Returns
- true on success, or nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- Reset room 1 to use the global border color
clearRoomBorderColor(1)
-- Clear custom borders from all rooms in an area
for _, roomID in ipairs(getAreaRooms(5)) do
clearRoomBorderColor(roomID)
end
setRoomBorderThickness, PR #8758
- setRoomBorderThickness(roomID, thickness)
- Sets a custom border thickness for an individual room on the 2D map. When set, this thickness overrides the global default for that specific room.
- Parameters
- roomID:
- The ID of the room to set the border thickness for.
- thickness:
- The border thickness (1-10).
- Returns
- true on success, or nil and an error message if no map is loaded, the room ID is invalid, or the thickness is out of range.
- Example
-- Set room 1 to have a thick border
setRoomBorderThickness(1, 5)
-- Highlight important rooms with thick red borders
local importantRooms = {1, 5, 10, 15}
for _, roomID in ipairs(importantRooms) do
setRoomBorderColor(roomID, 255, 0, 0)
setRoomBorderThickness(roomID, 3)
end
getRoomBorderThickness, PR #8758
- thickness = getRoomBorderThickness(roomID)
- Returns the custom border thickness for a room, if one has been set.
- Parameters
- roomID:
- The ID of the room to get the border thickness for.
- Returns
- The thickness value (1-10) if a custom thickness is set, or nil if the room uses the global default thickness. Returns nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- Check if room 1 has a custom border thickness
local thickness = getRoomBorderThickness(1)
if thickness then
echo(string.format("Room 1 has custom border thickness: %d\n", thickness))
else
echo("Room 1 uses the global border thickness\n")
end
clearRoomBorderThickness, PR #8758
- clearRoomBorderThickness(roomID)
- Removes the custom border thickness from a room, causing it to use the global default thickness.
- See also: setRoomBorderThickness(), getRoomBorderThickness()
- Parameters
- roomID:
- The ID of the room to clear the custom border thickness from.
- Returns
- true on success, or nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- Reset room 1 to use the global border thickness
clearRoomBorderThickness(1)
-- Clear all custom border settings from a room
clearRoomBorderColor(1)
clearRoomBorderThickness(1)
exportAreaImage PR#8156
- exportAreaImage(areaID, filePath[, zLevel])
- Exports an area from the mapper as an image file. This function allows you to save a visual representation of a specific area (or a specific Z level within that area) to disk as an image. The exported image will show rooms, exits, and other map elements as they appear in the 2D mapper.
- The image is rendered at a fixed 2.0x zoom level to provide good quality output while maintaining reasonable file sizes.
- See also
- createMapImageLabel(), createMapLabel()
Note: This function requires the mapper to be open and a valid map to be loaded. It will return an error if no map is present or if the specified area ID doesn't exist.
- Parameters
- areaID:
- Area ID number of the area to export as an image.
- filePath:
- File path where the image should be saved. Should include the desired file extension (e.g., ".png", ".jpg"). When exporting all Z levels, this will be used as a template for generating individual filenames.
- zLevel:
- (optional) Can be one of the following:
- integer - exports only the specific Z level within the area
- true - exports all Z levels in the area as separate image files
- nil/omitted - exports the current player's Z level
- Returns
- success: boolean - true if the export was successful, false if it failed
- errorMessage: string - only returned when success is false, contains the error message describing what went wrong
- Example
-- Export the current player's Z level of area 1 to a PNG file
exportAreaImage(1, "/home/user/mymap.png")
-- Export only Z level 0 of area 5 to a JPG file
exportAreaImage(5, "/home/user/level0.jpg", 0)
-- Export area 10, Z level -1 (basement level)
exportAreaImage(10, "basement_map.png", -1)
-- Export ALL Z levels in area 12 as separate images
-- This will create files like: mymap_level_0.png, mymap_level_1.png, mymap_level_-1.png, etc.
local success, error = exportAreaImage(12, "mymap.png", true)
if success then
echo("All Z levels exported successfully!")
else
echo("Export failed: " .. error)
end
-- Export all Z levels in multiple areas
for areaID, areaName in pairs(getAreaTable()) do
local filename = string.format("%s_area_%d.png", areaName, areaID)
local success, error = exportAreaImage(areaID, filename, true)
if success then
echo("Exported all Z levels for area: " .. areaName)
else
echo("Failed to export area " .. areaName .. ": " .. error)
end
end
-- Get a list of all Z levels in an area and export them individually
local areaID = 5
local area = getAreaTable()[areaID]
if area then
-- Get all Z levels by examining rooms in the area
local zLevels = {}
for roomID in pairs(getAreaRooms(areaID)) do
local x, y, z = getRoomCoordinates(roomID)
if z and not zLevels[z] then
zLevels[z] = true
end
end
-- Export each Z level individually with custom naming
for zLevel in pairs(zLevels) do
local filename = string.format("area_%s_floor_%d.png", area, zLevel)
exportAreaImage(areaID, filename, zLevel)
echo("Exported Z level " .. zLevel .. " to " .. filename)
end
end
createMapLabel, merged #7598
- labelID = createMapLabel(areaID, text, posX, posY, posZ, fgRed, fgGreen, fgBlue, bgRed, bgGreen, bgBlue[, zoom, fontSize, showOnTop, noScaling, fontName, foregroundTransparency, backgroundTransparency, temporary, outlineRed, outlineGreen, outlineBlue])
- Creates a text label on the map at given coordinates, with the given background and foreground colors. It can go above or below the rooms, scale with zoom or stay a static size. From Mudlet 4.17.0 an additional parameter (assumed to be false if not given from then) makes the label NOT be saved in the map file which, if the image can be regenerated on future loading from a script can reduce the size of the saved map somewhat. It returns a label ID that you can use later for deleting it.
- The coordinates 0,0 are in the middle of the map, and are in sync with the room coordinates - so using the x,y values of getRoomCoordinates() will place the label near that room.
- See also: getMapLabel(), getMapLabels(), deleteMapLabel, createMapImageLabel()
Note: Some changes were done prior to 4.13 (which exactly? function existed before!) - see corresponding PR and update here!
- Parameters
- areaID:
- Area ID where to put the label.
- text:
- The text to put into the label. To get a multiline text label add a '\n' between the lines.
- posX, posY, posZ:
- Position of the label in (floating point numbers) room coordinates.
- fgRed, fgGreen, fgBlue:
- Foreground color or text color of the label.
- bgRed, bgGreen, bgBlue:
- Background color of the label.
- zoom:
- (optional) Zoom factor of the label if noScaling is false. Higher zoom will give higher resolution of the text and smaller size of the label. Default is 30.0.
- fontSize:
- (optional, but needed if zoom is provided) Size of the font of the text. Default is 50.
- showOnTop:
- (optional) If true the label will be drawn on top of the rooms and if it is false the label will be drawn as a background, defaults to true if not given.
- noScaling:
- (optional) If true the label will have the same size when you zoom in and out in the mapper, If it is false the label will scale when you zoom the mapper, defaults to true if not given.
- fontName:
- (optional) font name to use.
- foregroundTransparency
- (optional) transparency of the text on the label, defaults to 255 (in range of 0 to 255) or fully opaque if not given.
- backgroundTransparency
- (optional) transparency of the label background itself, defaults to 50 (in range of 0 to 255) or significantly transparent if not given.
- temporary
- (optional) if true does not save the image that the label makes in map save files, defaults to false if not given, or for prior versions of Mudlet.
- outlineRed, outlineGreen, outlineBlue
- (optional) the outline colour of the displayed text
- Example
-- the first 50 is some area id, the next three 0,0,0 are coordinates - middle of the area
-- 255,0,0 would be the foreground in RGB, 23,0,0 would be the background RGB
-- zoom is only relevant when when you're using a label of a static size, so we use 0
-- and we use a font size of 20 for our label, which is a small medium compared to the map
local labelid = createMapLabel( 50, "my map label", 0,0,0, 255,0,0, 23,0,0, 0,20)
-- to create a multi line text label add '\n' between lines
-- the position is placed somewhat to the northeast of the center of the map
-- this label will be scaled as you zoom the map.
local labelid = createMapLabel( 50, "1. Row One\n2. Row 2", .5,5.5,0, 255,0,0, 23,0,0, 30,50, true, false)
local x,y,z = getRoomCoordinates(getPlayerRoom())
createMapLabel(getRoomArea(getPlayerRoom()), "my map label", x,y,z, 255,0,0, 23,0,0, 0,20, false, true, "Ubuntu", 255, 100)
-- create a temporary, multiline label with purple text and a white outline
lua createMapLabel(1, "This is a really long text\nwith multiple lines.", 0, 0, 0, 125, 0, 125, 0, 0, 0, 50, 48, true, false, "Noto Sans", 255, 0, true, 255, 255, 255)
getRoomsByPosition1, PR #8619
- roomTable = getRoomsByPosition1(areaID, x,y,z)
- Returns an indexed table of all rooms at the given coordinates in the given area, or an empty table if there are none. This function can be useful for checking if a room exists at certain coordinates, or whenever you have rooms overlapping. This returns exactly the same thing as getRoomsByPosition() except the table is indexed at 1, not zero.
- See also: getRoomsByPosition(), getRoomCoordinates()
mapSymbolFontInfo, PR #4038 closed
- mapSymbolFontInfo()
- See also: setupMapSymbolFont()
Note: pending, not yet available. See https://github.com/Mudlet/Mudlet/pull/4038
- returns
- either a table of information about the configuration of the font used for symbols in the (2D) map, the elements are:
- fontName - a string of the family name of the font specified
- onlyUseThisFont - a boolean indicating whether glyphs from just the fontName font are to be used or if there is not a glyph for the required grapheme (character) then a glyph from the most suitable different font will be substituted instead. Should this be true and the specified font does not have the required glyph then the replacement character (typically something like �) could be used instead. Note that this may not affect the use of Color Emoji glyphs that are automatically used in some OSes but that behavior does vary across the range of operating systems that Mudlet can be run on.
- scalingFactor - a floating point number between 0.50 and 2.00 which modifies the size of the symbols somewhat though the extremes are likely to be unsatisfactory because some of the particular symbols may be too small (and be less visible at smaller zoom levels) or too large (and be clipped by the edges of the room rectangle or circle).
- or nil and an error message on failure.
- As the symbol font details are stored in the (binary) map file rather than the profile then this function will not work until a map is loaded (or initialized, by activating a map window).
moveMapLabel, PR #6014 open
- moveMapLabel(areaID/Name, labeID/Text, coordX/deltaX, coordY/deltaY[, coordZ/deltaZ][, absoluteNotRelativeMove])
Re-positions a map label within an area in the 2D mapper, in a similar manner as the moveRoom() function does for rooms and their custom exit lines. When moving a label to given coordinates this is the position that the top-left corner of the label will be positioned at; since the space allocated to a particular room on the map is ± 0.5 around the integer value of its x and y coordinates this means for a label which has a size of 1.0 x 1,0 (w x h) to position it centrally in the space for a single room at the coordinates (x, y, z) it should be positioned at (x - 0.5, y + 0.5, z).
- See also: getMapLabels(), getMapLabel().
Note: pending, not yet available. See https://github.com/Mudlet/Mudlet/pull/6014
- Parameters
- areaID/Name:
- Area ID as number or AreaName as string containing the map label.
- labelID/Text:
- Label ID as number (which will be 0 or greater) or the LabelText on a text label. All labels will have a unique ID number but there may be more than one text labels with a non-empty text string; only the first matching one will be moved by this function and image labels also have no text and will match the empty string. with mo or AreaName as string containing the map label.
- coordX/deltaX:
- A floating point number for the absolute coordinate to use or the relative amount to move the label in "room coordinates" along the X-axis.
- coordY/deltaY:
- A floating point number for the absolute coordinate to use or the relative amount to move the label in "room coordinates" along the Y-axis.
- coordZ/deltaZ:
- (Optional) A floating point number for the absolute coordinate to use or the relative amount to move the label in "room coordinates" along the Z-axis, if omitted the label is not moved in the z-axis at all.
- absoluteNotRelativeMove:
- (Optional) a boolean value (defaults to false if omitted) as to whether to move the label to the absolute coordinates (true) or to move it the relative amount from its current location (false).
- Returns
- true on success or nil and an error message on failure, if successful it will also refresh the map display to show the result.
- Example
-- move the first label in the area with the ID number of 2, three spaces to the east and four spaces to the north
moveMapLabel(0, 2, 3.0, 4.0)
-- move the first label in the area with the ID number of 2, one space to the west, note the final boolean argument is unneeded
moveMapLabel(0, 2, -1.0, 0.0, false)
-- move the second label in the area with the ID number of 2, three and a half spaces to the west, and two south **of the center of the current level it is on in the map**:
moveRoom(1, 2, -3.5, -2.0, true)
-- move the second label in the area with the ID number of 2, up three levels
moveRoom(1, 2, 0.0, 0.0, 3.0)
-- move the second label in the "Test 1" area one space to the west, note the last two arguments are unneeded
moveRoom("Test 1", 1, -1.0, 0.0, 0.0, false)
-- move the (top-left corner of the first) label with the text "Home" in the area with ID number 5 to the **center of the whole map**, note the last two arguments are required in this case:
moveRoom(5, "Home", 0.0, 0.0, 0.0, true)
-- all of the above will return the 'true' boolean value assuming there are the indicated labels and areas
moveRoom, PR #6010 open
- moveRoom(roomID, coordX/deltaX, coordY/deltaY[, coordZ/deltaZ][, absoluteNotRelativeMove])
Re-positions a room within an area, in the same manner as the "move to" context menu item for one or more rooms in the 2D mapper. Like that method this will also shift the entirety of any custom exit lines defined for the room concerned. This contrasts with the behavior of the setRoomCoordinates() which only moves the starting point of such custom exit lines so that they still emerge from the room to which they belong but otherwise remain pointing to the original place.
- See also: setRoomCoordinates()
Note: pending, not yet available. See https://github.com/Mudlet/Mudlet/pull/6010
- Parameters
- roomID:
- Room ID number to move.
- coordX/deltaX:
- The absolute coordinate or the relative amount as a number to move the room in "room coordinates" along the X-axis.
- coordY/deltaY:
- The absolute coordinate or the relative amount as a number to move the room in "room coordinates" along the Y-axis.
- coordZ/deltaZ:
- (Optional) the absolute coordinate or the relative amount as a number to move the room in "room coordinates" along the Z-axis, if omitted the room is not moved in the z-axis at all.
- absoluteNotRelativeMove:
- (Optional) a boolean value (defaults to false if omitted) as to whether to move the room to the absolute coordinates (true) or the relative amount from its current location (false).
- Returns
- true on success or nil and an error message on failure, if successful it will also refresh the map display to show the result.
- Example
-- move the first room one space to the east and two spaces to the north
moveRoom(1, 1, 2)
-- move the first room one space to the west, note the final boolean argument is unneeded
moveRoom(1, -1, 0, false)
-- move the first room three spaces to the west, and two south **of the center of the current level it is on in the map**:
moveRoom(1, -3, -2, true)
-- move the second room up three levels
moveRoom(2, 0, 0, 3)
-- move the second room one space to the west, note the last two arguments are unneeded
moveRoom(2, -1, 0, 0, false)
-- move the second room to the **center of the whole map**, note the last two arguments are required in this case:
moveRoom(2, 0, 0, 0, true)
-- all of the above will return the 'true' boolean value assuming there are rooms with 1 and 2 as ID numbers
setExitWeightFilter, PR #8487 open
- setExitWeightFilter(callback)
- installs a custom filter that lets you adjust or block exits while Mudlet computes routes.
- Use setExitWeightFilter(nil) to remove the filter and restore stored exit weights.
Note: setExitWeightFilter Each call clears the cached routing graph so Mudlet rebuilds it using the new logic. If your callback input is changed it might be worth setting new filter once again.
- Parameters
callback one of:
- a Lua function function(roomId, exitCommand) that Mudlet calls during pathfinding;
- nil to clear the currently installed filter.
- The callback receives:
- roomId — numeric id of the room the exit begins in;
- exitCommand — command string to take that exit (e.g. "north" or a custom command).
- roomId — numeric id of the room the exit begins in;
- The callback may return:
- a number to override the exit weight (lower weights are preferred);
- false or the string "block" to prevent Mudlet from considering the exit;
- nil to keep Mudlet’s original weight.
- a number to override the exit weight (lower weights are preferred);
- Returns
true on success;
nil and an error message if the pathfinding data cannot be updated (e.g. no map loaded).
- Example
- discourage mountain travel if your char is not dwarf, and totally avoid for elves
local race = getCharacterRaceFromFancyScript()
local mountainsEnv = 100
setExitWeightFilter(function(roomId, exitCommand)
-- Block entirely for elves
if race == "elf" then
return "block" -- or false
end
-- Look up the current weight so we can base adjustments on it.
local currentWeight = getRoomWeight(roomID) or 0
-- Add a penalty to room for not dwarfs
if race ~= "dwarf" and mountainsEnv == getRoomEnv(roomID) then
return currentWeight + 25
end
-- No change: keep Mudlet's original weight.
return nil
end)
- Clearing the filter
Remove the custom logic and restore default weighting:
setExitWeightFilter(nil)
setupMapSymbolFont, PR #4038 closed
- setupMapSymbolFont(fontName[, onlyUseThisFont[, scalingFactor]])
- configures the font used for symbols in the (2D) map.
- See also: mapSymbolFontInfo()
Note: pending, not yet available. See https://github.com/Mudlet/Mudlet/pull/4038
- Parameters
- fontName one of:
- - a string that is the family name of the font to use;
- - the empty string "" to reset to the default {which is "Bitstream Vera Sans Mono"};
- - a Lua nil as a placeholder to not change this parameter but still allow a following one to be modified.
- onlyUseThisFont (optional) one of:
- - a Lua boolean true to require Mudlet to use graphemes (character) only from the selected font. Should a requested grapheme not be included in the selected font then the font replacement character (�) might be used instead; note that under some circumstances it is possible that the OS (or Mudlet) provided color Emoji Font may still be used but that cannot be guaranteed across all OS platforms that Mudlet might be run on;
- - a Lua boolean false to allow Mudlet to get a different glyph for a particular grapheme from the most suitable other font found in the system should there not be a glyph for it in the requested font. This is the default unless previously changed by this function or by the corresponding checkbox in the Profile Preferences window for the profile concerned;
- - a Lua nil as a placeholder to not change this parameter but still allow the following one to be modified.
- scalingFactor (optional): a floating point value in the range 0.5 to 2.0 (default 1.0) that can be used to tweak the rectangular space that each different room symbol is scaled to fit inside; this might be useful should the range of characters used to make the room symbols be consistently under- or over-sized.
- Returns
- true on success
- nil and an error message on failure. As the symbol font details are stored in the (binary) map file rather than the profile then this function will not work until a map is loaded (or initialised, by activating a map window).
getMapBackgroundColor, PR #8071 open
- getMapBackgroundColor()
- Gets the color and transparency of the map background.
See also: setMapBackgroundColor()
- Returns
- 4 integers - red, green, blue, transparency. Colors are 0 to 255 (0 being black), and transparency is 0 to 255 (0 being completely transparent).
- Example
local r, g, b, a = getMapBackgroundColor()
setMapBackgroundColor, PR #8071 open
- setMapBackgroundColor(r, g, b, [transparency])
- Sets the color (and optionally transparency) for the map background. Colors are 0 to 255 (0 being black), and transparency is 0 to 255 (0 being completely transparent).
See also: getMapBackgroundColor()
- Parameters
- r:
- Amount of red to use, 0 (none) to 255 (full).
- g:
- Amount of green to use, 0 (none) to 255 (full).
- b:
- Amount of red to use, 0 (none) to 255 (full).
- transparency:
- (optional) amount of transparency to use, 0 (fully transparent) to 255 (fully opaque). Defaults to 255 if omitted.
- Example
-- make the map have a somewhat transparent red background
setMapBackgroundColor(255,0,0,200)
-- make the map have an opaque black background
setMapBackgroundColor(0,0,0)
setMapPerspective, PR #8147 open
- setMapPerspective(distance, polarAngle, azimuthalAngle)
- Sets the camera's position for the 3d map. See the wiki page on spherical coordinates for more clarification on the polar and azimuthal angles.
See also: shiftMapPerspective()
- Parameters
- distance:
- Distance of the camera from the focal point. 1 distance is equivalent to the distance between 10 rooms on the 3d map.
- polarAngle:
- Angle of the camera from the z-axis, e.g. 0 (looking straight down from above), 90 (looking along the x/y plane) 180 (looking straight up from below).
- azimuthalAngle:
- Angle of the camera rotating counter-clockwise from the x-axis, e.g. 0 (looking west from the east), -90 or 270 (looking north from the south) etc.
- Example
-- make the map perspective looking down from above at a 45 degree angle, with north facing forward (up) on the map, 5 rooms' distance from the focus point.
setMapPerspective(0.5, 45, 270)
shiftMapPerspective, PR #8147 open
- shiftMapPerspective(verticalAngle, horizontalAngle, cameraRotation)
- Shifts the camera's relative position for the 3d map. All arguments are expected in degrees. Each shift of the camera occurs in the order of the arguments, i.e. first vertical shift, then horizontal, and finally the camera is rotated.
See also: setMapPerspective()
- Parameters
- verticalAngle:
- How many degrees to shift the camera vertically, with positive values moving the camera up.
- horizontalAngle:
- How many degrees to shift the camera horizontally, with positive values moving the camera to the right.
- cameraRotation:
- How many degrees to rotate the camera, with positive values rotating it clockwise.
- Example
-- Move the camera 10 degrees down, 20 degrees to the right, and invert the map.
shiftMapPerspective(-10, 20, 180)
Miscellaneous Functions
- Miscellaneous functions.
playSpatialSound, PR #8452 open
- playSpatialSound(settings table)
Plays spatial audio files with 3D positioning using Qt6's SpatialAudio framework. Allows precise positioning, occlusion effects, room acoustics, and environmental audio for immersive gameplay experiences.
| Required | Key | Purpose | Default | Description |
|---|---|---|---|---|
| Yes | key | <unique identifier> | Unique key to identify this spatial sound source for later updates or removal. | |
| Yes | name | <file name> | Name of the audio file. May contain directory information (i.e. ambient/forest.ogg). May be part of the profile (i.e. getMudletHomeDir().. "/spatial/wind.wav") or on the local device (i.e. "C:/Users/YourName/Documents/sound.mp3"). | |
| No | url | <url> | Resource location where the audio file may be downloaded. Only required if file is to be downloaded remotely. | |
| No | position | {azimuth, elevation, distance} | {0, 0, 1} | 3D position as a table: azimuth (horizontal angle in degrees, 0-360), elevation (vertical angle in degrees, -90 to 90), distance (in meters, > 0). |
| No | volume | 1 to 100 | 50 | Volume level relative to master spatial audio volume. |
| No | occlusion | 0.0 to 1.0 | 0.0 | Occlusion factor simulating objects blocking the sound path. |
| No | loops | -1 or >= 1 | 1 | Number of times to loop. -1 for infinite looping. |
| No | room | {dimensions, reverb, reflection, material} | Room acoustics configuration table. |
See also: updateSpatialSound(), stopSpatialSound(), removeSpatialSound(), getSpatialSounds()
- Example
-- Play forest ambience behind the player
playSpatialSound({
key = "forest_ambience",
name = "ambient/forest_birds.ogg",
position = {180, 0, 5}, -- behind player, 5 meters away
volume = 30,
loops = -1 -- infinite loop
})
-- Play footsteps with room acoustics
playSpatialSound({
key = "footsteps",
name = "effects/footstep_stone.wav",
position = {45, -10, 2}, -- front-right, slightly below, 2 meters
volume = 60,
room = {
dimensions = {10, 3, 8}, -- 10m wide, 3m high, 8m deep
reverb = 0.3,
reflection = 0.7,
material = "sheetrock"
}
})
-- Download and play remote spatial sound
playSpatialSound({
key = "wind_howl",
name = "wind.ogg",
url = "https://example.com/sounds/",
position = {270, 45, 10}, -- left side, elevated, distant
volume = 40,
occlusion = 0.2 -- partially blocked
})
updateSpatialSound, PR #8452 open
- updateSpatialSound(key, settings table)
Updates properties of an existing spatial audio source without stopping playback.
- Parameters
• key: Unique identifier of the spatial sound source to update • settings table: Table containing properties to update (same format as playSpatialSound)
See also: playSpatialSound()
- Example
-- Move sound to new position
updateSpatialSound("forest_ambience", {
position = {90, 0, 3} -- move to right side, closer
})
-- Update volume and add occlusion
updateSpatialSound("footsteps", {
volume = 80,
occlusion = 0.5
})
-- Update multiple properties
updateSpatialSound("wind_howl", {
position = {315, 30, 15},
volume = 25,
occlusion = 0.8
})
stopSpatialSound, PR #8452 open
- stopSpatialSound(key)
Stops playback of a spatial audio source but keeps the source available for later use.
- Parameters
• key: Unique identifier of the spatial sound source to stop
- Returns
• boolean: true on success, false if source not found
See also: playSpatialSound(), removeSpatialSound()
- Example
-- Stop the forest ambience
stopSpatialSound("forest_ambience")
-- Stop footsteps when player stops walking
if not moving then
stopSpatialSound("footsteps")
end
pauseSpatialSound, PR #8452 open
- pauseSpatialSound(key)
Pauses playback of a spatial audio source, allowing it to be resumed later from the same position.
- Parameters
• key: Unique identifier of the spatial sound source to pause
- Returns
• boolean: true on success, false if source not found
See also: playSpatialSound(), stopSpatialSound()
- Example
-- Pause ambient sound temporarily
pauseSpatialSound("forest_ambience")
-- Resume by playing again (will continue from pause position)
playSpatialSound({
key = "forest_ambience",
name = "ambient/forest_birds.ogg",
position = {180, 0, 5}
})
removeSpatialSound, PR #8452 open
- removeSpatialSound(key)
Completely removes a spatial audio source, stopping playback and freeing resources.
- Parameters
• key: Unique identifier of the spatial sound source to remove
- Returns
• boolean: true on success, false if source not found
See also: stopSpatialSound(), getSpatialSounds()
- Example
-- Remove completed sound effect
removeSpatialSound("door_slam")
-- Clean up old ambient sounds
for _, key in ipairs({"old_wind", "old_rain", "old_birds"}) do
removeSpatialSound(key)
end
getSpatialSounds, PR #8452 open
- getSpatialSounds()
Returns a list of all currently active spatial audio sources.
- Returns
• table: Indexed table containing the keys of all active spatial sound sources
See also: playSpatialSound(), removeSpatialSound()
- Example
-- List all active spatial sounds
local activeSounds = getSpatialSounds()
for i, soundKey in ipairs(activeSounds) do
echo("Active spatial sound: " .. soundKey .. "\n")
end
-- Stop all spatial sounds
for _, soundKey in ipairs(getSpatialSounds()) do
stopSpatialSound(soundKey)
end
-- Check if specific sound is playing
local activeSounds = getSpatialSounds()
local isPlaying = table.contains(activeSounds, "forest_ambience")
setSpatialListener, PR #8452 open
- setSpatialListener(settings table)
Sets the position and orientation of the spatial audio listener (the player's ears).
| Required | Key | Purpose | Default | Description |
|---|---|---|---|---|
| No | position | {x, y, z} | {0, 0, 0} | 3D position of the listener in world coordinates. |
| No | rotation | {yaw, pitch, roll} | {0, 0, 0} | Orientation of the listener's head: yaw (left/right), pitch (up/down), roll (tilt). |
See also: playSpatialSound()
- Example
-- Set listener at origin, facing north
setSpatialListener({
position = {0, 0, 0},
rotation = {0, 0, 0}
})
-- Player moved to new room and is facing east
setSpatialListener({
position = {10, 0, 5},
rotation = {90, 0, 0} -- 90 degrees yaw = facing east
})
-- Looking up at the sky
setSpatialListener({
rotation = {0, 45, 0} -- 45 degrees pitch up
})
setSpatialMasterVolume, PR #8452 open
- setSpatialMasterVolume(volume)
Sets the master volume for all spatial audio sources.
- Parameters
• volume: Master volume level (0-100)
- Returns
• boolean: true on success
See also: playSpatialSound()
- Example
-- Set moderate spatial audio volume
setSpatialMasterVolume(60)
-- Mute all spatial audio
setSpatialMasterVolume(0)
-- Maximum spatial audio volume
setSpatialMasterVolume(100)
playSpatialTestTone, PR #8452 open
- playSpatialTestTone(settings table)
Plays a generated test tone at a specific spatial position for testing and calibration purposes.
| Required | Key | Purpose | Default | Description |
|---|---|---|---|---|
| Yes | key | <unique identifier> | Unique key to identify this test tone source. | |
| Yes | type | "white", "pink", or "sine" | Type of test tone to generate. | |
| Yes | duration | <seconds> | Duration of the test tone in seconds. | |
| Yes | azimuth | <degrees> | Horizontal angle (0-360 degrees). | |
| Yes | elevation | <degrees> | Vertical angle (-90 to 90 degrees). | |
| Yes | distance | <meters> | Distance from listener in meters. | |
| No | frequency | <Hz> | 440 | Frequency for sine wave test tones. |
| No | volume | 1 to 100 | 50 | Volume of the test tone. |
| No | loops | -1 or >= 1 | 1 | Number of loops (-1 for infinite). |
See also: playSpatialSound(), stopSpatialSound()
- Example
-- Test speaker positions with white noise
playSpatialTestTone({
key = "test_left",
type = "white",
duration = 2,
azimuth = 270, -- left side
elevation = 0,
distance = 2,
volume = 70
})
-- Test frequency response with sine wave
playSpatialTestTone({
key = "test_1khz",
type = "sine",
frequency = 1000,
duration = 3,
azimuth = 0, -- front center
elevation = 0,
distance = 1,
volume = 50
})
-- Test distance with pink noise
playSpatialTestTone({
key = "test_distant",
type = "pink",
duration = 5,
azimuth = 180, -- behind
elevation = 0,
distance = 10, -- far away
volume = 80,
loops = 2
})
getCustomLoginTextId, PR #3952 open
- getCustomLoginTextId()
Returns the Id number of the custom login text setting from the profile's preferences. Returns 0 if the option is disabled or a number greater than that for the item in the table; note it is possible if using an old saved profile in the future that the number might be higher than expected. As a design policy decision it is not permitted for a script to change the setting, this function is intended to allow a script or package to check that the setting is what it expects.
Introduced along with four other functions to enable game server log-in to be scripted with the simultaneous movement of that functionality from the Mudlet application core code to a predefined doLogin() function, a replacement for which is shown below.
Note: Not available yet. See https://github.com/Mudlet/Mudlet/pull/3952
Only one custom login text has been defined initially:
| Id | Custom text | Introduced in Mudlet version |
|---|---|---|
| 1 | "connect {character name} {password}" | TBD |
The addition of further texts would be subject to negotiation with the Mudlet Makers.
- Example
-- A replacement for the default function placed into LuaGlobal.lua to reproduce the previous behavior of the Mudlet application:
function doLogin()
if getCustomLoginTextId() ~= 1 then
-- We need this particular option but it is not permitted for a script to change the setting, it can only check what it is
echo("\nUnable to login - please select the 'connect {character name} {password}` custom login option in the profile preferences.\n")
else
tempTime(2.0, [[sendCustomLoginText()]], 1)
end
end
sendCharacterName, PR #3952 open
- sendCharacterName()
Sends the name entered into the "Character name" field on the Connection Preferences form directly to the game server. Returns true unless there is nothing set in that entry in which case a nil and an error message will be returned instead.
Introduced along with four other functions to enable game server log-in to be scripted with the simultaneous movement of that functionality from the Mudlet application core code to a predefined doLogin() function that may be replaced for more sophisticated requirements.
- See also: getCharacterName(), sendCharacterPassword(), sendCustomLoginText(), getCustomLoginTextId().
Note: Not available yet. See https://github.com/Mudlet/Mudlet/pull/3952
sendCharacterPassword, PR #3952 open
- sendCharacterPassword()
Sends the password entered into the "Password" field on the Connection Preferences form directly to the game server. Returns true unless there is nothing set in that entry or it is too long after (or before) a connection was successfully made in which case a nil and an error message will be returned instead.
Introduced along with four other functions to enable game server log-in to be scripted with the simultaneous movement of that functionality from the Mudlet application core code to a predefined doLogin() function, reproduced below, that may be replaced for more sophisticated requirements.
Note: Not available yet. See https://github.com/Mudlet/Mudlet/pull/3952
- Example
-- The default function placed into LuaGlobal.lua to reproduce the previous behavior of the Mudlet application:
function doLogin()
if getCharacterName() ~= "" then
tempTime(2.0, [[sendCharacterName()]], 1)
tempTime(3.0, [[sendCharacterPassword()]], 1)
end
end
sendCustomLoginText, PR #3952 open
- sendCustomLoginText()
Sends the custom login text (which does NOT depend on the user's choice of GUI language) selected in the preferences for this profile. The {password} (and {character name} if present) fields will be replaced with the values entered into the "Password" and "Character name" fields on the Connection Preferences form and then sent directly to the game server. Returns true unless there is nothing set in either of those entries (though only if required for the character name) or it is too long after (or before) a connection was successfully made or if the custom login feature is disabled, in which case a nil and an error message will be returned instead.
Introduced along with four other functions to enable game server log-in to be scripted with the simultaneous movement of that functionality from the Mudlet application core code to a predefined doLogin() function, a replacement for which is shown below.
Note: Not available yet. See https://github.com/Mudlet/Mudlet/pull/3952
Only one custom login text has been defined initially:
| Id | Custom text | Introduced in Mudlet version |
|---|---|---|
| 1 | "connect {character name} {password}" | TBD |
The addition of further texts would be subject to negotiation with the Mudlet Makers.
- Example
-- A replacement for the default function placed into LuaGlobal.lua to reproduce the previous behavior of the Mudlet application:
function doLogin()
if getCustomLoginTextId() ~= 1 then
-- We need this particular option but it is not permitted for a script to change the setting, it can only check what it is
echo("\nUnable to login - please select the 'connect {character name} {password}` custom login option in the profile preferences.\n")
else
tempTime(2.0, [[sendCustomLoginText()]], 1)
end
end
Mudlet Object Functions
- A collection of functions that manipulate Mudlet's scripting objects - triggers, aliases, and so forth.
createComposer PR #8114 open
- ok = createComposer(title, text, callbackFunction)
Creates a Composer dialog window with the given title and initial text, and registers a Lua function to handle the result. When the user clicks **Save** or **Cancel**, the Composer closes and your callback function is invoked with two arguments: the resulting text and a boolean indicating whether the user saved (true) or canceled editing (false).
- Parameters
- title:
- The title of the Composer window.
- text:
- The initial text content in the Composer. You can use
\nto start a new line,\tfor tabulators, etc.
- callbackFunction:
- A Lua function to call when the Composer closes. It will receive two parameters:
- A string with the text the user entered.
- A boolean value – `true` if the user clicked **Save**, `false` if they clicked **Cancel**.
- Returns
- Boolean `true` if the Composer was successfully created, otherwise nil + error (for example, if another Composer is already open).
- Example
-- Create a Composer window for editing a note
createComposer("Edit Note", "Default text", function(editedText, isSaved)
if isSaved then
echo(f"Saved text: {editedText}\n")
else
echo("Edit was canceled.\n")
end
end)
getComposerText PR #8114
- text = getComposerText()
Returns the current text from the Composer window, if it is open.
- See also
- createComposer(), setComposerText()
- Parameters
- (none)
- Returns
- The text currently displayed in the Composer, or nil + error if the Composer is not open.
- Example
-- Retrieve and print the current text from the Composer
local currentText = getComposerText()
if currentText then
echo(f"Current text in Composer: {currentText}\n")
else
echo("No Composer is open.\n")
end
getComposerTitle PR #8114
- title = getComposerTitle()
Returns the current title from the Composer window, if it is open.
- See also
- createComposer(), setComposerTitle()
- Parameters
- (none)
- Returns
- The current title of the Composer, or nil + error if the Composer is not open.
- Example
-- Print the Composer title
local currentTitle = getComposerTitle()
if currentTitle then
echo(f"Composer title: {currentTitle}\n")
else
echo("No Composer is open.\n")
end
setComposerText PR #8114
- setComposerText(newText)
Sets the text content of the Composer window, if it is open.
- See also
- createComposer(), getComposerText()
- Parameters
- newText:
- The text to display in the Composer. You can use
\nto start a new line,\tfor tabulators, etc.
- Returns
- Boolean `true` if the Title was successfully set, or nil + error if no Composer is open.
- Example
-- Change the Composer text dynamically
setComposerText("Updated text for the Composer")
setComposerTitle PR #8114
- setComposerTitle(newTitle)
Sets the title of the Composer window, if it is open.
- See also
- createComposer(), getComposerTitle()
- Parameters
- newTitle:
- The title to display in the Composer.
- Returns
- Boolean `true` if the Title was successfully set, or nil + error if no Composer is open.
- Example
-- Change the Composer title dynamically
setComposerTitle("Declaration of Independence")
stopNamedTrigger PR#7767
- success = stopNamedTrigger(userName, triggerName)
- Stops a named trigger with name triggerName and prevents it from firing any more. Information is stored so it can be resumed later if desired.
- See also
- registerNamedTrigger(), resumeNamedTrigger()
- Parameters
- userName:
- The user name the event handler was registered under.
- triggerName:
- The name of the trigger to stop. Same as used when you called registerNamedTrigger()
- Returns
- true if successful, false if it didn't exist or was already stopped
- Example
local stopped = stopNamedTrigger("Zooka", "automatic drinking trigger")
if stopped then
echo("No longer drinking automatically.")
else
echo("Drinking trigger doesn't exist or already stopped; either way it won't fire any more.")
end
Networking Functions
- A collection of functions for managing networking.
String Functions
- These functions are used to manipulate strings.
Table Functions
- These functions are used to manipulate tables. Through them you can add to tables, remove values, check if a value is present in the table, check the size of a table, and more.
Text to Speech Functions
- These functions are used to create sound from written words. Check out our Text-To-Speech Manual for more detail on how this all works together.
UI Functions
- These functions are used to construct custom user GUIs. They deal mainly with miniconsole/label/gauge creation and manipulation as well as displaying or formatting information on the screen.
getBorderColor, PR #8688
- getBorderColor()
- Returns the RGB values of the main window border color (the area outside the main console where the mapper, buttons, and other UI elements are placed).
- See also: setBorderColor(), getBorderSizes(), getBackgroundColor()
- Example
-- get the current border color
local r, g, b = getBorderColor()
echo(string.format("Border color is RGB(%d, %d, %d)\n", r, g, b))
-- check if border is using default black color
local r, g, b = getBorderColor()
if r == 0 and g == 0 and b == 0 then
echo("Border is black - consider customizing it!\n")
end
-- store current color before changing it
local oldR, oldG, oldB = getBorderColor()
setBorderColor(50, 50, 50)
-- later, restore the original color
setBorderColor(oldR, oldG, oldB)
insertPopup, revised in PR #6925
- insertPopup([windowName], text, {commands}, {hints}[{, tool-tips}][, useCurrentFormatElseDefault])
- Creates text with a left-clickable link, and a right-click menu for more options at the end of the current line, like echo. The added text, upon being left-clicked, will do the first command in the list. Upon being right-clicked, it'll display a menu with all possible commands. The menu will be populated with hints, one for each line; if a tool-tips table is not provided the same hints will also be listed one-per-line as a tool-tip but if a matching number of tool-tips are provided they will be concatenated to provide a tool-tip when the text is hovered over by the pointer - these tool-tips can be rich-text to produce information formatted with additional content in the same manner as labels.
- Parameters
- windowName:
- (optional) name of the window as a string to echo to. Use either main or omit for the main window, or the miniconsole's or user-window's name otherwise.
- text:
- the text string to display.
- {commands}:
- a table of lua code to do, in text strings or as functions (since Mudlet 4.11), i.e.
{[[send("hello")]], function() echo("hi!") end}.
- {hints}:
- a table of strings which will be shown on the right-click menu (and popup if no {tool-tips} table is provided). If a particular position in both the commands and hints table are both the empty string "" but there is something in the tool-tips table, no entry for that position will be made in the context menu but the tool-tip can still display something which can include images or text.
- {tool-tips}:
- (optional) a table of possibly rich-text strings which will be shown on the popup if provided.
- useCurrentFormatElseDefault:
- (optional) a boolean value for using either the current formatting options (color, underline, italic and other effects) if true or the link default (blue underline) if false, if omitted the default format is used.
Note: Mudlet will distinguish between the optional tool-tips and the flag to switch between the standard link and the current text format by examining the type of the argument, as such this pair of arguments can be in either order.
- Example
-- Create some text as a clickable with a popup menu, a left click will ''send "sleep"'':
insertPopup("activities to do", {function() send "sleep" end, function() send "sit" end, function() send "stand" end}, {"sleep", "sit", "stand"})
-- alternatively, put commands as text (in [[ and ]] to use quotation marks inside)
insertPopup("activities to do", {[[send "sleep"]], [[send "sit"]], [[send "stand"]]}, {"sleep", "sit", "stand"})
-- one can also provide helpful information
-- todo: an example with rich-text in the tool-tips(s)
Discord Functions
- All functions to customize the information Mudlet displays in Discord's rich presence interface. For an overview on how all of these functions tie in together, see our Discord scripting overview.
Mud Client Media Protocol
- All GMCP functions to send sound and music events. For an overview on how all of these functions tie in together, see our MUD Client Media Protocol scripting overview.
Client.Media.Spatial, PR #8452 open
The Client.Media.Spatial family of GMCP packages extends the Client.Media protocol to provide 3D positional audio capabilities. These packages allow games to create immersive spatial soundscapes with positioned audio sources and listener orientation.
Enabling Spatial Audio
Spatial audio requires the same settings as regular Client.Media:
- The "Enable GMCP" box in the Miscellaneous section must be checked.
- The "Allow server to download and play media" box in the Game protocols section must be checked.
Coordinate System
The spatial audio system uses a 3D coordinate system where:
- Azimuth: Horizontal angle in degrees (0° = front, 90° = right, 180° = back, 270° = left)
- Elevation: Vertical angle in degrees (-90° = below, 0° = level, 90° = above)
- Distance: Distance from listener in arbitrary units (1.0 = close, higher values = farther)
For listener positioning, a Cartesian coordinate system is used:
- X: Left/right position
- Y: Forward/back position
- Z: Up/down position
Playing Spatial Media
Send Client.Media.Spatial.Play GMCP events to play positioned sound sources in 3D space.
| Required | Parameter | Value | Default | Description |
|---|---|---|---|---|
| Yes | "key" | <string> | Unique identifier for this spatial audio source. Used for updates and stopping. | |
| Yes | "name" | <file name> | Name of the media file. May contain directory information (i.e. ambient/wind.wav). | |
| Maybe | "url" | <url> | Resource location where the media file may be downloaded. Only required if not using Client.Media.Default URL or if file is not cached. | |
| No | "volume" | 1 to 100 | 80 | Volume level relative to the master spatial audio volume. |
| No | "loops" | -1, or >= 1 | 1 | Number of times to loop the sound. -1 for infinite looping. |
| No | "position" | <array or object> | 3D position of the sound source. See position formats below. | |
| No | "occlusion" | 0.0 to 1.0 | 0.0 | Occlusion factor (0.0 = no occlusion, 1.0 = fully occluded/muffled). |
| No | "room" | <object> | Room acoustics parameters. See room acoustics below. |
Position Formats
Position can be specified as an array [azimuth, elevation, distance] or as an object:
// Array format
Client.Media.Spatial.Play {
"key": "footsteps_player",
"name": "footsteps.wav",
"position": [45, 0, 2.5]
}
// Object format
Client.Media.Spatial.Play {
"key": "footsteps_player",
"name": "footsteps.wav",
"position": {
"azimuth": 45,
"elevation": 0,
"distance": 2.5
}
}
Room Acoustics
Room acoustics can enhance spatial realism by simulating reverb and reflections:
Client.Media.Spatial.Play {
"key": "cave_drip",
"name": "water_drop.wav",
"position": [0, -45, 8],
"room": {
"dimensions": [20, 30, 5],
"reverb": 2.5,
"reflection": 1.8,
"material": "sheetrock"
}
}
Updating Spatial Media
Send Client.Media.Spatial.Update GMCP events to modify properties of already playing spatial audio sources.
| Required | Parameter | Value | Description |
|---|---|---|---|
| Yes | "key" | <string> | Unique identifier of the spatial audio source to update. |
| No | "position" | <array or object> | New 3D position for the sound source. |
| No | "volume" | 1 to 100 | New volume level. |
| No | "occlusion" | 0.0 to 1.0 | New occlusion factor. |
Example of moving a sound source:
Client.Media.Spatial.Update {
"key": "footsteps_player",
"position": [90, 0, 3.0],
"volume": 60
}
Stopping Spatial Media
Send Client.Media.Spatial.Stop GMCP events to stop spatial audio sources.
| Required | Parameter | Value | Description |
|---|---|---|---|
| No | "key" | <string> | Unique identifier of the spatial audio source to stop. If omitted, stops all spatial audio. |
Stop a specific source:
Client.Media.Spatial.Stop {
"key": "footsteps_player"
}
Stop all spatial audio:
Client.Media.Spatial.Stop {}
Listener Control
Send Client.Media.Spatial.Listener GMCP events to control the listener's position and orientation in 3D space.
| Required | Parameter | Value | Description |
|---|---|---|---|
| No | "position" | <array or object> | Listener position in 3D space [x, y, z] or {x, y, z}. |
| No | "rotation" | <array or object> | Listener rotation [yaw, pitch, roll] or {yaw, pitch, roll} in degrees. |
Listener Position
Position uses Cartesian coordinates:
// Array format: [x, y, z]
Client.Media.Spatial.Listener {
"position": [5.0, -2.0, 1.5]
}
// Object format
Client.Media.Spatial.Listener {
"position": {
"x": 5.0,
"y": -2.0,
"z": 1.5
}
}
Listener Rotation
Rotation controls where the listener is facing:
// Array format: [yaw, pitch, roll]
Client.Media.Spatial.Listener {
"rotation": [180, -10, 0]
}
// Object format
Client.Media.Spatial.Listener {
"rotation": {
"yaw": 180,
"pitch": -10,
"roll": 0
}
}
Usage Examples
Basic Positioned Sound
Client.Media.Spatial.Play {
"key": "sword_clash",
"name": "combat/sword_hit.wav",
"position": [30, 0, 2],
"volume": 85
}
Moving Ambient Sound
// Start a moving creature sound
Client.Media.Spatial.Play {
"key": "wolf_howl",
"name": "creatures/wolf_howl.wav",
"position": [-90, 10, 5],
"loops": 3
}
// Update its position as it moves
Client.Media.Spatial.Update {
"key": "wolf_howl",
"position": [-45, 5, 3]
}
Environmental Audio with Room Acoustics
Client.Media.Spatial.Play {
"key": "cathedral_organ",
"name": "music/organ_chord.wav",
"position": [0, 15, 20],
"volume": 70,
"room": {
"dimensions": [40, 80, 15],
"reverb": 3.0,
"reflection": 2.2,
"material": "sheetrock"
}
}
Dynamic Listener Movement
// Player turns to face north and moves forward
Client.Media.Spatial.Listener {
"position": [0, 5, 0],
"rotation": [0, 0, 0]
}
// Player turns to look northeast and up slightly
Client.Media.Spatial.Listener {
"rotation": [45, 15, 0]
}
Note: Spatial audio provides the most immersive experience when used with headphones or properly positioned stereo speakers. The 3D positioning effects may be less apparent with poor audio hardware.
GMCP Spatial Audio Capability Detection
Mudlet provides three GMCP messages for server developers to detect and query spatial audio capabilities. These allow servers to adapt their audio content based on the client's actual capabilities and current settings.
Client.Media.Spatial.Capabilities
Query the client's spatial audio capabilities to determine what features and formats are supported.
Server sends:
Client.Media.Spatial.Capabilities {}
Client responds with:
Client.Media.Spatial.Capabilities {
"version": "1.0",
"formats": ["wav", "mp3", "ogg", "flac", "aac", "m4a"],
"output_modes": ["stereo", "surround", "headphone"],
"room_materials": ["brick", "concrete", "wood", "metal", "glass", ...],
"max_sources": 32,
"distance_model": "inverse",
"coordinate_system": "spherical",
"features": {
"positioning": true,
"room_acoustics": true,
"occlusion": true,
"listener_control": true,
"test_tones": true,
"volume_control": true,
"loops": true
}
}
Response Fields:
- version: Protocol version (currently "1.0")
- formats: Array of supported audio file formats (detected at runtime based on Qt6 multimedia backend)
- output_modes: Available audio output configurations
- room_materials: Supported acoustic materials for room simulation
- max_sources: Maximum number of simultaneous spatial audio sources
- distance_model: Audio attenuation model used ("inverse")
- coordinate_system: Position coordinate system ("spherical" with azimuth/elevation/distance)
- features: Boolean flags indicating supported capabilities
Room Materials
The room materials are baed on this list from Qt QAudioRoom's Material enum. Mudlet is accepting the list of aliases as well.
| Material | Aliases | Description |
|---|---|---|
| transparent | air | The side of the room is open and won't contribute to reflections or reverb. |
| acousticceilingtiles | acoustictiles | Acoustic tiles that suppress most reflections and reverb. |
| brickbare | brick | Bare brick wall. |
| brickpainted | Painted brick wall. | |
| concreteblockcoarse | concrete | Raw concrete wall |
| concreteblockpainted | concretepainted | Painted concrete wall |
| curtainheavy | curtain, fabric | Heavy curtain. Will mostly reflect low frequencies |
| fiberglassinsulation | fiberglass, carpet | Fiber glass insulation. Only reflects very low frequencies |
| glassthin | glass | Thin glass wall |
| glassthick | Thick glass wall | |
| grass | Grass | |
| linoleumonconcrete | linoleum | Linoleum floor |
| marble | Marble floor | |
| metal | Metal | |
| parquetonconcrete | parquet, parquetonfiberboard | Parquet wooden floor on concrete |
| plasterrough | plaster | Rough plaster |
| plastersmooth | Smooth plaster | |
| plywoodpanel | plywood | Plywood panel |
| polishedconcreteortile | tile, polishedconcrete | Polished concrete or tiles |
| sheetrock | stone | Rock |
| wateroricesurface | water, ice, wateroriceereflector | Water or ice |
| woodceiling | Wooden ceiling | |
| woodpanel | wood | Wooden panel |
| uniformmaterial | uniform | Artificial material giving uniform reflections on all frequencies |
Client.Media.Spatial.Settings
Query the client's current spatial audio configuration and user settings.
Server sends:
Client.Media.Spatial.Settings {}
Client responds with:
Client.Media.Spatial.Settings {
"master_volume": 80,
"listener": {
"position": [0, 0, 0],
"rotation": [0, 0, 0]
},
"room": {
"dimensions": [10, 10, 4],
"reverb_gain": 0.3,
"reflection_gain": 0.5,
"reverb_time": 1.0,
"reverb_brightness": 0.0
}
}
Response Fields:
- master_volume: Current master volume (0-100)
- listener.position: 3D listener position [x, y, z] in Cartesian coordinates
- listener.rotation: Listener orientation [yaw, pitch, roll] in degrees
- room.dimensions: Room size [width, height, depth] in meters
- room.reverb_gain: Reverberation intensity (0.0-5.0)
- room.reflection_gain: Early reflection intensity (0.0-5.0)
- room.reverb_time: Reverberation decay time in seconds (0.0-20.0)
- room.reverb_brightness: Reverb frequency bias (-1.0 to 1.0)
Client.Media.Spatial.Status
Query the current status of active spatial audio sources managed by the server.
Server sends:
Client.Media.Spatial.Status {}
Client responds with:
Client.Media.Spatial.Status {
"engine_initialized": true,
"source_count": 2,
"max_sources": 32,
"active_sources": [
{
"key": "ambient_forest",
"status": "playing",
"position": [45, 0, 5],
"volume": 60,
"occlusion": 0.0,
"size": 1.0,
"loops": -1
},
{
"key": "footsteps",
"status": "paused",
"position": [-90, -10, 2],
"volume": 80,
"occlusion": 0.5,
"size": 0.5,
"loops": 1
}
]
}
Response Fields:
- engine_initialized: Whether the spatial audio engine is ready
- source_count: Number of currently active sources
- max_sources: Maximum supported sources
- active_sources: Array of source objects with current state
- key: Server-assigned source identifier
- status: Current playback state ("playing", "paused", "stopped")
- position: Source position [azimuth, elevation, distance] in spherical coordinates
- volume: Current volume level (0-100)
- occlusion: Occlusion/obstruction level (0.0-4.0)
- size: Source spatial size (0.0+, affects audio spread)
- loops: Loop count (-1 for infinite, 0 for stopped, >0 for remaining loops)
Supported Protocols
MXP FRAME and DEST Tags, PR #8577
MXP FRAME and DEST tags allow MUD servers to create multi-window layouts, directing game output to separate panels within Mudlet. This enables rich interfaces with dedicated areas for chat, inventory, status, and more.
Overview
FRAME creates a new window panel that can display game content.
DEST (destination) redirects subsequent text to a specific frame.
FRAME Tag
Creates a named frame where content can be directed.
Basic Syntax
<FRAME name="frameName" title="Frame Title" align="left" width="25%" height="100%">
Attributes
| Attribute | Required | Description | Default |
|---|---|---|---|
| NAME | Yes | Unique identifier for the frame | - |
| TITLE | No | Display title shown in the frame's tab | Same as NAME |
| INTERNAL | No | Frame appears inside the main window | Yes (default) |
| EXTERNAL | No | Frame appears as a separate floating window | No |
| FLOATING | No | Borderless frame without title bar | No |
| ALIGN | No | Position: left, right, top, bottom | left |
| LEFT | No | Absolute horizontal position (pixels, %, or 'c' suffix) | - |
| TOP | No | Absolute vertical position (pixels, %, or 'c' suffix) | - |
| WIDTH | No | Frame width (pixels, %, or characters with 'c' suffix) | 25% |
| HEIGHT | No | Frame height (pixels, %, or characters with 'c' suffix) | 25% |
| SCROLLING | No | Enable scrolling (YES/NO) | YES |
| ACTION | No | open (show), close (hide), or focus | open |
Size Units
- Pixels:
300pxor300 - Percentage:
25%of available space - Characters:
40cfor 40 characters width/height
CMUD Extension: DOCK
<FRAME name="tab2" INTERNAL align="client" DOCK="parentFrame">
When used with align="client", the DOCK attribute creates a tabbed frame inside an existing frame.
Examples
Create a left-aligned chat panel:
<FRAME name="chat" title="Chat" align="left" width="30%">
Create a status bar at the bottom:
<FRAME name="status" align="bottom" height="50">
Create a borderless floating frame:
<FRAME name="minimap" FLOATING width="200" height="200" LEFT="10" TOP="10">
Show an existing frame:
<FRAME name="chat" action="open">
Close a frame:
<FRAME name="chat" action="close">
DEST Tag
Redirects text output to a named frame.
Syntax
<DEST name="frameName">Text goes here</DEST>
Or as a self-closing tag to set destination for all following text:
<DEST name="frameName">
Attributes
| Attribute | Required | Description |
|---|---|---|
| NAME | Yes | Target frame name (empty string returns to main window) |
| EOF | No | If present, clears all content in the frame before writing |
| EOL | No | If present, clears the current line before writing |
Examples
Send text to a chat frame:
<DEST name="chat">Player says: Hello!</DEST>
Clear frame and write new content:
<DEST name="status" EOF>HP: 100/100 MP: 50/50</DEST>
Return output to main window:
<DEST name="">
Complete Example
A typical MXP sequence to set up a multi-panel interface:
<!-- Create the frames -->
<FRAME name="chat" title="Chat" align="left" width="25%">
<FRAME name="status" title="Status" align="bottom" height="3c">
<!-- Send content to chat frame -->
<DEST name="chat">
[Guild] Bob: Anyone want to group?
[Guild] Alice: Sure!
</DEST>
<!-- Send content to status frame, clearing previous content -->
<DEST name="status" EOF>HP: 100/100 | MP: 75/100 | XP: 45%</DEST>
<!-- Return to main window for regular game output -->
<DEST name="">
You are standing in the town square.
Behavior Notes
- Frames persist until explicitly closed with
action="close" - Re-opening an existing frame shows it without changing its size or position (respects user customization)
- Frame names are case-sensitive
- Content sent via DEST inherits the formatting of the destination frame
- Frames reset on reconnect (don't persist between sessions)
See Also
- createMiniConsole() - Lua equivalent for creating sub-windows
Events
- New or revised events that Mudlet can raise to inform a profile about changes. See Mudlet-raised events for the existing ones.
MudMaster Chat Protocol (MMCP) PR #7765 open
- MMCP is a peer-to-peer protocol enabling out of band data to be sent to connected peers in the form of public or private chats, or general data.
- See MMCP protocol documentation at: https://tintin.mudhalla.net/protocols/mmcp/
- See https://wiki.mudlet.org/w/Notes_on_MMCP
Note: pending, not yet available. See https://github.com/Mudlet/Mudlet/pull/7765
Lua functions
- Note for all functions using target as an argument, the argument can be the client chatname or ID of the client as seen in mmcp.displayClientList()
accept
- mmcp.accept(target)
- Accepts an incoming connection request.
- Parameters
- target:
- Incoming client name or ID.
Note: pending, not yet available in initial MMCP release.
allowSnoop
- mmcp.allowSnoop(target)
- Toggles the Allow Snoop flag for a client, allowing them to initiate a snoop request which will forward them text you see from your game.
- Parameters
- target:
- Client name or ID.
call
- mmcp.call(host[, port])
- Initiate an outgoing connection to another client.
- Parameters
- host:
- IPv4 address or fully qualified domain name.
- port:
- (optional) Port to connect to. Default 4050.
- Example
local host = "1.2.3.4"
local port = 4050
mmcp.call(host, port)
- You should see the following message
[ CHAT ] - Connecting to 1.2.3.4:4050...
[ CHAT ] - Waiting for response from 1.2.3.4:4050...
[ CHAT ] - Connection to ChatClient at 1.2.3.4:4050 accepted.
chatAll
- mmcp.chatAll(message)
- Sends a message to all connected clients.
- Parameters
- message:
- The message to send.
This message will have the format of: <Name> chats to everybody, '<message>'
You will see the message: You chat to everybody, '<message>'
chatGroup
- mmcp.chatGroup(group, message)
- Sends a message to all clients in the specified group.
- Parameters
- group:
- The group to send the message to.
- message:
- The message to send.
The message will have the format of: <Name> chats to the group, '<message>'
You will see the message: You chat to <<group>>, '<message>'
chatName
- mmcp.chatName([name])
- Sets or gets your current chat name visible to other clients.
- Parameters
- name:
- (optional) The new chat name to use.
- Returns
-
- If no name is specified, this function will return your current chat name.
chatTo
- mmcp.chatTo(target, message)
- Sends a message to a specific client.
- Parameters
- target:
- Client name or ID.
- message:
- The message to send.
The target client will see the message: <Name> chats to you, '<message>'
You will see the message: You chat to <target>, '<message>'
deny
- mmcp.deny(target)
- Denies an incoming connection request.
- Parameters
- target:
- Client name or ID.
Note: pending, not yet available in initial MMCP release.
disconnect
- mmcp.disconnect(target)
- Disconnects a connected client.
- Parameters
- target:
- Client name or ID
displayClientList
- mmcp.displayClientList()
- Displays a table showing information about connected and pending clients.
- Example
mmcp.displayClientList()
- You should see the following table
Id Name Address Port Group Flags ChatClient
==== ==================== ==================== ===== =============== ======== ================
1 ChatClient 1.2.3.4 4050 Mudlet
==== ==================== ==================== ===== =============== ======== ================
Color Key: Connected Pending
Flags: F - Firewall, I - Ignored, P - Private, S - Serving
n - Allow Snooping, N - Being Snooped- You may then use the mmcp lua commands referencing the client by their ID (1) or name (ChatClient)
emoteAll
- mmcp.emoteAll(message)
- Sends an emote message to all connected clients.
- Parameters
- message:
- The message to send.
Clients will see the message: <Name> <message>
If you have enabled the "Prefix emote messages" option, you will see: You emote to everyone: '<Name> <message>'
Otherwise you will see: <Name> <message>
getClientFlags
- mmcp.getClientFlags(target)
- Returns a string containing the client flags of a connected client.
- Parameters
- target:
- Client name or ID.
- Returns
This string is an 8 character string where letters in the following positions have meaning: "12345678"
- 1: Reserved, blank
- 2: Reserved, blank
- 3: P if the connection is Private, otherwise blank
- 4: I if the connection is Ignored, otherwise blank
- 5: S if the client is being served, otherwise blank
- 6: F if the client is firewalled, otherwise blank
- 7: N if the client is snooping us, n if the client can snoop us, otherwise blank
- 8: Reserved, blank
getClientList
- clientInfo = mmcp.getClientList()
- Returns a lua table containing the following information for each connected client.
- Returns
- id: The ID of the client
- name: The chat name of the client.
- host: The hostname or IP address of the client.
- port: The port the client (check if this is the reported port or port they connected from)
- version: The MUD client and version of the client
- Example
local clientList = mmcp.getClientList()
- The variable clientList will then contain
{ {
host = "1.2.3.4",
id = 1,
name = "ChatClient",
port = 4050,
version = "Mudlet"
} }ignore
- mmcp.ignore(target)
- Toggles ignoring a client. You will not see chat messages from an ignored client.
- Parameters
- target:
- Client name or ID.
peek
- mmcp.peek(target)
- Sends a request to the target client to peek at their connection list.
- Parameters
- target:
- Client name or ID.
ping
- mmcp.ping(target)
- Sends a ping request to a client.
- Parameters
- target:
- Client name or ID.
request
- mmcp.request(target)
- Sends a request to the target client to request and connect to their public connections.
- Mudlet will attempt to connect to each of the hosts returned by this command.
- Parameters
- target:
- Client name or ID.
sendSideChannel
- mmcp.sendSideChannel(channel, message)
- Sends an OOB (Out of band) message to all connected clients.
- Parameters
- channel:
- The channel to send the message on.
- message:
- The message to send.
Note: This will only send to other Mudlet clients. Upon receipt of this message Mudlet will raise a sysMMCPSideChannelMessage containing
the channel and message data.
- Example
-- myStats populated by prompt trigger
local outStr = string.format("%s,%d,%d,%d,%d,%s",
mmcp.chatName(), myStats.hp, myStats.maxHp, myStats.mana, myStats.maxMana, myStats.buffs)
mmcp.sendSideChannel("stats", outStr)
serve
- mmcp.serve(target)
- Toggles the serve flag for a client, this clients chat messages will be sent to all other connected clients.
- Parameters
- target:
- Client name or ID.
setDoNotDisturb
- mmcp.setDoNotDisturb(target)
- Toggles the Do Not Disturb flag, any incoming connections will be automatically denied.
Note: pending, not yet available in initial MMCP release.
setGroup
- mmcp.setGroup(target, group)
- Assigns a client to a chat group.
- Parameters
- target:
- Client name or ID.
- group:
- The group name.
Note: The group name is only visible to you.
setPrivate
- mmcp.setPrivate(target)
- Toggles the private flag for a client. Any clients set as private will not be listed in peek or connection requests.
- Parameters
- target:
- Client name or ID.
snoop
- mmcp.snoop(target)
- Starts snooping a client. The target may first need to enable snooping on their client.
- Parameters
- target:
- Client name or ID.
startServer
- mmcp.startServer([port])
- Starts accepting connections from clients.
- Parameters
- port:
- (optional) Port to listen for incoming connections. Default 4050.
Note: pending, not yet available in initial MMCP release.
stopServer
- mmcp.stopServer()
- Stops accepting connections from clients.
Note: pending, not yet available in initial MMCP release.
Events
sysMMCPChatMessage
- Raised when Mudlet receives an MMCP chat message from a client
- Arguments
- peerName:
- Peer Name of the client
- message:
- Message content
- Example putting MMCP messages into an EMCO window
function mmcpEventHandler(event, ...)
-- trim whitespace
local trimmedStr = arg[1]:match("^%s*(.-)%s*$")
myEmcoWindow:decho("MMCP", ansi2decho(trimmedStr) .. "\n", false)
end
registerNamedEventHandler(getProfileName(), "MMCP", "sysMMCPMessage", "mmcpEventHandler")
sysMMCPSideChannelMessage
- Raised when an MMCP side channel message has been received
- Arguments
- peerName:
- Peer Name of the client
- channel:
- Channel identifier string
- message:
- Message content
- Example
function VFrame.eventHandler(event, ...)
if event == "gmcp.Char.Vitals" then
VFrame.updateVitals()
elseif event == "sysMMCPSideChannelMessage" then
--display("event: " .. event .. " from: " .. arg[1] .. " channel: " .. arg[2] .. " message: " .. arg[3])
if arg[2] == "stats" and myVFrame then -- check if its actually for us
myVFrame:playerData(arg[3])
end
end
end
VFrame.registeredEvents = {
registerAnonymousEventHandler("gmcp.Char.Vitals", "VFrame.eventHandler"),
registerAnonymousEventHandler("sysMMCPSideChannelMessage", "VFrame.eventHandler"),
}
sysMMCPIncomingSnoopMessage
- Raised when an MMCP client whom you are snooping has sent new snoop data
- Arguments
- peerName:
- Peer Name of the client
- message
- Snoop content
sysMMCPPeerUpdateEvent
- Raised when an MMCP client has been connected or disconnected
- Arguments
- peerName:
- Chat name of the client