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.
GMCP Extensions
- A collection of GMCP options for UI builders or server administrators.
Client.GUI baseui, PR #10278 merged
Note: merged, will be available in the next release. See https://github.com/Mudlet/Mudlet/pull/10278
- Client.GUI {"baseui": false}
- A game that brings its own interface can tell Mudlet up front not to activate the built-in starter UI (the base UI), by sending this GMCP message. Mudlet raises the existing sysServerGuiInstalled event with no package named, and the starter UI stands aside through the same path it already uses when a game's interface package finishes installing. The message also reaches
gmcp.Client.GUI.baseuifor scripts to read.
- See also: Automatic package installation, Base UI
- Parameters
- baseui:
falsedeclines the built-in starter UI. The JSON boolean is preferred; the string"false"is also accepted, for GMCP serializers that can only spell values as strings.
- Notes
- Send it after GMCP is negotiated, before the game's first vitals or chat data: the starter UI builds its dock on the first game data it recognises, so a decline that arrives ahead of that data means the dock is never built at all. A decline arriving later still stands the starter UI aside from that point.
- Only the JSON form of Client.GUI can decline - the older raw
Client.GUI <package version>\n<url>form (and its ATCP equivalent) carries only a version and a url. - The decline is honoured only while the "Allow server to install script packages" preference is enabled - the same preference that gates Client.GUI package installation.
baseui showbrings the starter UI back; because the game repeats the decline on every connect, that holds for the session but not past the next reconnect.
- Example
What the game sends:
Client.GUI {
"baseui": false
}
A script can see the decline arrive:
registerAnonymousEventHandler("sysServerGuiInstalled", function(_, packageName)
if not packageName then
echo("The game declined the built-in starter UI.\n")
end
end)
Mapper Functions
- A collection of functions that manipulate the mapper and its related features.
mapperButton setConfig key, PR #10196 merged
Note: merged, will be available in the next release. See https://github.com/Mudlet/Mudlet/pull/10196
This row joins the "Mapper & Map UI" table on Configuration Options at the next release:
| Config Key | Description | Type | Default | Available Since |
|---|---|---|---|---|
| mapperButton | Controls the built-in map buttons: "default", "scripted" (raises a sysMapperButtonAction event instead), or "disabled" (greys them out). Session-only, reapply each profile load | string | "default" | next release |
mapSymbolFont setConfig keys, PR #10166 merged
Note: merged, will be available in the next release. See https://github.com/Mudlet/Mudlet/pull/10166
These rows join the "Mapper & Map UI" table on Configuration Options at the next release. They supersede the setupMapSymbolFont()/mapSymbolFontInfo() functions staged for PR #4038 - review asked for setConfig/getConfig keys instead of new functions:
| Config Key | Description | Type | Default | Available Since |
|---|---|---|---|---|
| mapSymbolFont | Font family for room symbols on the 2D map. Stored in the map file, not the profile | string | "Bitstream Vera Sans Mono" | next release |
| mapSymbolFontOnlyUseSelected | Use only the selected symbol font instead of borrowing missing glyphs from other fonts. Stored in the map file | boolean | false | next release |
| mapSymbolFontScaling | Scaling factor for room symbols. Accepts 0.5 to 2.0. Stored in the map file | number | 1.0 | next release |
setRoomBorderStyle, PR #8985
- setRoomBorderStyle(roomID, style)
- Sets the border style for a specific room on the map. This allows visually distinguishing rooms with dashed or dotted borders instead of the
default solid border - useful for marking temporary, unvisited, or special rooms.
- See also: setRoomBorderColor(), setRoomBorderThickness(), getRoomBorderStyle(), clearRoomBorderStyle()
- Parameters
- roomID:
- The ID of the room to set the border style for.
- style:
- The border style to apply. Valid values: "dashed" (or "dash line") for a dashed border, "dotted" (or "dot line") for a dotted border, or "solid" to reset to the default solid border.
- Returns
- true on success, or nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- set room 1234 to have a dashed border
setRoomBorderStyle(1234, "dashed")
-- set room 1234 to have a dotted border
setRoomBorderStyle(1234, "dotted")
-- reset room 1234 back to solid border
setRoomBorderStyle(1234, "solid")
getRoomBorderStyle, PR #8985
- getRoomBorderStyle(roomID)
- Returns the border style for a specific room on the map.
- See also: setRoomBorderStyle(), clearRoomBorderStyle()
- Parameters
- roomID:
- The ID of the room to get the border style for.
- Returns
- "dashed" if the room has a dashed border, "dotted" if the room has a dotted border, or nil if the room has the default solid border.
- Example
local style = getRoomBorderStyle(1234)
if style then
echo(f"Room 1234 has a {style} border.\n")
else
echo("Room 1234 has a solid (default) border.\n")
end
clearRoomBorderStyle, PR #8985
- clearRoomBorderStyle(roomID)
- Resets the border style for a specific room back to the default solid border.
- See also: setRoomBorderStyle(), getRoomBorderStyle()
- Parameters
- roomID:
- The ID of the room to clear the border style for.
- Returns
- true on success, or nil and an error message if no map is loaded or the room ID is invalid.
- Example
-- reset room 1234 back to solid border
clearRoomBorderStyle(1234)
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
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.
Networking Functions
- A collection of functions for managing networking.
getTelnetOptionsStatus PR #8962, open
- getTelnetOptionsStatus()
- Returns the current status of telnet options that have been negotiated between Mudlet and the game server. This function is useful for debugging telnet protocol issues and understanding which features are currently enabled in your connection. The values returned are the same as those that would be reported back to the Server if it requested them via the telnet option number 5 (STATUS).
- The function returns a table where each key is a telnet option number (0-255), and the value is a sub-table containing the option details. Only options that have been negotiated so far during the telnet session are included in the results. As nearly all options are handled separately in the two directions each numbered option has two statuses to report,
- See also: Telnet Protocols
- Returns
- A table with telnet option numbers as keys, each containing:
- Name: A string with the human-readable name of the telnet option (e.g., "ECHO (1)", "NAWS (31)", "MCCP2 (86)")
- Server: (optional) Boolean indicating if the server (who sent the <IAC><WILL><OPTION> to which Mudlet replied<IAC><DO><OPTION> to agree or <IAC><DONT><OPTION> to disagree to it) has this option enabled (true) or disabled (false). Only present if the server requested this option.
- Mudlet: (optional) Boolean indicating if Mudlet (who sent the <IAC><WILL><OPTION> to which the Server replied <IAC><DO><OPTION> to agree or <IAC><DONT><OPTION> to disagree to it) has this option enabled (true) or disabled (false). Only present if Mudlet requested this option.
- Example
-- Display all negotiated telnet options
local options = getTelnetOptionsStatus()
cecho("<cyan>Current Telnet Options Status:\n")
for optionNumber, details in pairs(options) do
cecho(string.format("<white>Option %d: <yellow>%s<reset>\n", optionNumber, details.Name))
if details.Server ~= nil then
if details.Server then
cecho(" <white>Server: <green>enabled<reset>\n")
else
cecho(" <white>Server: <red>disabled<reset>\n")
end
end
if details.Mudlet ~= nil then
if details.Mudlet ~= nil then
cecho(" <white>Mudlet: <green>enabled<reset>\n")
else
cecho(" <white>Mudlet: <red>disabled<reset>\n")
end
end
end
-- Check if compression (MCCP2) is enabled
local options = getTelnetOptionsStatus()
-- Option 86 is MCCP2 (Mud Client Compression Protocol 2)
if options[86] and options[86].Server then
cecho("<green>Compression is enabled!\n")
else
cecho("<red>Compression is not active.\n")
end
-- Monitor telnet negotiation on connect
function checkTelnetFeatures()
local options = getTelnetOptionsStatus()
-- Check for common features
local features = {
[1] = "Echo",
[3] = "Suppress Go Ahead",
[24] = "Terminal Type",
[31] = "Negotiate Window Size (NAWS)",
[69] = "MSDP",
[86] = "MCCP2 Compression",
[201] = "GMCP"
}
cecho("<cyan>Enabled Features:\n")
for optNum, name in pairs(features) do
if options[optNum] then
local status = "announced"
if options[optNum].Server and options[optNum].Mudlet then
status = "fully enabled"
elseif options[optNum].Server then
status = "server enabled"
elseif options[optNum].Mudlet then
status = "client enabled"
end
cecho(string.format("<white>%s: <green>%s\n", name, status))
end
end
end
registerAnonymousEventHandler("sysConnectionEvent", "checkTelnetFeatures")
Note: This function is primarily intended for debugging telnet protocol issues. Most users won't need to use it in normal scripts, as Mudlet handles telnet negotiation automatically. At the time of introduction there is a suspicion that the status of some options were not being correctly handled and this function was created to provide a means to monitor them.
Note: pending, not yet available. See https://github.com/Mudlet/Mudlet/pull/8962
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.
setBackgroundImage (updated), PR #8935
Note: As of Mudlet 5.1, setBackgroundImage() accepts SVG files for labels in addition to raster images (PNG, JPG and so on). Simply pass the path to the file. Whether a file is an SVG is decided by its content, not its name: a PNG saved as .svg is drawn as a raster, an SVG under any name is drawn as an SVG, and .svgz files work too.
An SVG is drawn as a layer behind the label's text or movie, so echo() and setMovie() work on the same label as before. It is scaled to fit inside the label's border while keeping its proportions, centred, and re-rendered at full resolution on every resize and on HiDPI screens. It is not clipped to a stylesheet border-radius, so a rounded label shows the SVG square in its corners. The SVG can be recoloured with setSvgTint() and transformed with setSvgRotation() and setSvgShear().
A raster image behaves as it always has: it is drawn at its own size as the label's content, in place of any text.
resetBackgroundImage() removes the SVG layer, a raster image and a movie in one call and leaves the label's text in place. It does not touch the tint, rotation or shear, which have their own reset functions.
A label showing only an SVG reports the SVG's own size through getLabelSizeHint(), plus any border and padding from its stylesheet, so Geyser's auto-size works with SVG icons the way it does with raster ones.
If the file cannot be read as an image, the function returns nil and an error message and the label keeps what it was showing.
- Example
-- set an SVG background on a label
setBackgroundImage("myLabel", getMudletHomeDir() .. "/compass.svg")
-- text is drawn over it
echo("myLabel", "N")
-- rotate it 45 degrees
setSvgRotation("myLabel", 45)
-- remove the image again; the text stays
resetBackgroundImage("myLabel")
-- Geyser usage
myLabel:setBackgroundImage(getMudletHomeDir() .. "/compass.svg")
myLabel:setSvgRotation(45)
setSvgTint, PR #8935
- setSvgTint(labelName, r, g, b)
- setSvgTint(labelName, colorName)
- Recolours a label's SVG background image without changing the file. Every visible pixel of the SVG takes the given colour and keeps its own transparency, so a multi-colour SVG becomes a single-colour silhouette. The tint is a property of the label rather than of the image: it can be set before any SVG is there and applies as soon as one arrives, it survives the image being replaced and resetBackgroundImage(), and only resetSvgTint() removes it.
- See also
- resetSvgTint(), setBackgroundImage()
- Parameters
- labelName:
- The name of the label whose SVG background to tint.
- r, g, b:
- The red, green and blue components of the tint colour, each 0 to 255.
- colorName:
- Instead of r, g, b: a colour as a string. Accepts a Mudlet colour name from color_table such as "alice_blue" (case and underscores do not matter, so "AliceBlue" works too), an SVG colour name such as "aliceblue", or a hex value such as "#f0f8ff".
- Returns
- true on success, or nil and an error message if the colour is not recognised or the label is not found. The Geyser method returns the same, and accepts every format Geyser.Color.parse understands; a colour it cannot read is handed to the global, so an unknown name returns nil and a message rather than raising an error.
- Example
-- tint with RGB components
setSvgTint("myLabel", 255, 100, 50)
-- tint with a Mudlet colour name, an SVG colour name or a hex value
setSvgTint("myLabel", "dark_orange")
setSvgTint("myLabel", "darkorange")
setSvgTint("myLabel", "#ff6432")
-- the tint may be set before the image; it applies when the image arrives
setSvgTint("myLabel", "dark_orange")
setBackgroundImage("myLabel", getMudletHomeDir() .. "/compass.svg")
-- Geyser usage; accepts every format Geyser.Color.parse understands
myLabel:setSvgTint("dark_orange")
myLabel:setSvgTint(255, 100, 50)
resetSvgTint, PR #8935
- resetSvgTint(labelName)
- Removes the tint from a label's SVG background image, restoring the colours in the file. This is the only call that removes a tint; changing or removing the image does not.
- See also
- setSvgTint()
- Parameters
- labelName:
- The name of the label to reset the SVG tint for.
- Returns
- true on success, or nil and an error message if the label is not found.
- Example
resetSvgTint("myLabel")
-- Geyser usage
myLabel:resetSvgTint()
setSvgRotation, PR #8935
- setSvgRotation(labelName, angle)
- Sets the rotation angle for a label's SVG background image. The SVG is rotated around the centre of the label; the label's text and background colour are unaffected. Content rotated beyond the label's edges is clipped, so a square image loses its corners at 45 degrees - a circular design, or some padding inside the SVG, avoids that. Like the tint, the angle is a property of the label: it can be set before any SVG is there, survives the image being replaced or removed, and is kept until resetSvgRotation() or resetSvgTransform() is called.
- See also
- resetSvgRotation(), setSvgShear(), resetSvgTransform()
- Parameters
- labelName:
- The name of the label to rotate the SVG background for.
- angle:
- Rotation angle in degrees (positive = clockwise). Must be a finite number.
- Returns
- true on success, or nil and an error message if the label is not found or the angle is not a finite number.
- Example
-- rotate the SVG background 45 degrees clockwise
setSvgRotation("myLabel", 45)
-- rotate it upside down
setSvgRotation("myLabel", 180)
-- Geyser usage
myLabel:setSvgRotation(45)
resetSvgRotation, PR #8935
- resetSvgRotation(labelName)
- Resets the SVG background image rotation to 0 degrees.
- See also
- setSvgRotation(), resetSvgTransform()
- Parameters
- labelName:
- The name of the label to reset the SVG rotation for.
- Returns
- true on success, or nil and an error message if the label is not found.
- Example
resetSvgRotation("myLabel")
-- Geyser usage
myLabel:resetSvgRotation()
setSvgShear, PR #8935
- setSvgShear(labelName, shearX, shearY)
- Sets the shear (skew) for a label's SVG background image. The SVG is sheared around the centre of the label; the label's text and background colour are unaffected. As with rotation, content sheared outside the label is clipped. Like the tint, the shear is a property of the label: it can be set before any SVG is there, survives the image being replaced or removed, and is kept until resetSvgShear() or resetSvgTransform() is called.
- See also
- resetSvgShear(), setSvgRotation(), resetSvgTransform()
- Parameters
- labelName:
- The name of the label to shear the SVG background for.
- shearX:
- Horizontal shear factor. Must be a finite number.
- shearY:
- Vertical shear factor. Must be a finite number.
- Returns
- true on success, or nil and an error message if the label is not found or a factor is not a finite number.
- Example
-- apply a horizontal skew to the SVG background
setSvgShear("myLabel", 0.3, 0)
-- apply both horizontal and vertical skew
setSvgShear("myLabel", 0.2, 0.1)
-- Geyser usage
myLabel:setSvgShear(0.3, 0)
resetSvgShear, PR #8935
- resetSvgShear(labelName)
- Resets the SVG background image shear to (0, 0).
- See also
- setSvgShear(), resetSvgTransform()
- Parameters
- labelName:
- The name of the label to reset the SVG shear for.
- Returns
- true on success, or nil and an error message if the label is not found.
- Example
resetSvgShear("myLabel")
-- Geyser usage
myLabel:resetSvgShear()
resetSvgTransform, PR #8935
- resetSvgTransform(labelName)
- Resets all SVG transforms (rotation and shear) back to their defaults but keeps any SVG tint. A convenience equivalent to calling both resetSvgRotation() and resetSvgShear().
- Parameters
- labelName:
- The name of the label to reset all SVG transforms for.
- Returns
- true on success, or nil and an error message if the label is not found.
- Example
-- reset all transforms at once, the tint stays
resetSvgTransform("myLabel")
-- Geyser usage
myLabel:resetSvgTransform()
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.
Supported Protocols
Model Context Protocol (MCP), PR #8576
- Mudlet can run a Model Context Protocol server, so an AI assistant - Claude, ChatGPT, VS Code's chat, or anything else that speaks MCP - can run Lua inside Mudlet on your behalf. That lets it read your map, look at windows, triggers, aliases and variables, and send commands to the game.
Note: Lua can run programs and change files on your computer, not just script your game. Turning this on hands that reach to whichever assistant you give the address to. Leave it off when you are not using it.
Turning it on
- Preferences → Special Options → AI assistant access (MCP)
- Tick Let an AI assistant run Lua in Mudlet, pick a port if 11235 is taken, and press Save. The label underneath then shows the address to hand to your assistant. The setting is remembered across restarts, so the server comes back up on its own next launch.
- One server covers the whole application rather than one per profile: an MCP client is configured with a single URL, and a per-profile endpoint would move about as profiles are opened and closed.
The address
- The address Mudlet shows looks like this, where the trailing part is an access token:
http://127.0.0.1:11235/mcp/1a2b3c4d5e6f708192a3b4c5d6e7f809
- Most MCP clients only take a URL, so the token is carried in the path. A client that can set headers may instead use
http://127.0.0.1:11235/mcpwithAuthorization: Bearer <token>.
- For example, in VS Code's
mcp.json:
{
"servers": {
"mudlet": {
"type": "http",
"url": "http://127.0.0.1:11235/mcp/1a2b3c4d5e6f708192a3b4c5d6e7f809"
}
}
}
Note: The token is generated fresh every time Mudlet starts, so one that leaks into a log or a screenshot stops working - but you will need to re-copy the address into your assistant after a restart.
The lua tool
- The server offers a single tool,
lua.
- Parameters
- code:
- (string, required) The Lua code to run.
- profile:
- (string, optional) The name of the profile to run it in. Matched the way the rest of Mudlet matches profile names, so achaea finds Achaea. Defaults to the profile you are currently looking at.
- Returns
- Whatever the code printed with
print(), followed by whatever it returned. Tables come back rendered as JSON.
Note: Only print() and returned values are reported back. echo(), cecho() and display() write to the profile's window, so the assistant will not see them.
- Example
- Asking the assistant to check where you are runs something like:
print(gmcp.Room.Info.name)
return getRoomCoordinates(getPlayerRoom())
Limits
- These exist so that code written by a model cannot take the client down:
- Code that runs for more than 10 seconds is stopped.
- Tables are rendered no more than 12 levels deep, and no more than 200,000 values are converted in total. A table that refers to itself would otherwise never finish.
- A single table is rendered with at most 20,000 keys, and a single string is cut off at 100,000 bytes.
- Long strings also count against the 200,000-value budget in proportion to their length, so a table full of large strings runs out of room in the same way a table with many keys does.
- Wherever any of these cuts something short, the reply says so in place of what was left out, so the assistant is never handed a partial answer that reads like a whole one.
- Lua will not run in a profile that is closing, being reset, or busy with a map operation - the assistant is told to try again instead.
Note: The 10-second stop is cooperative, as it has to be: it raises a Lua error, and code that catches errors round its own loop can carry on regardless. This is the same exposure any trigger, alias or timer already has - Mudlet runs everything on one thread, so while true do end freezes it wherever it is written.
Security
- The server listens on 127.0.0.1 only, so nothing off your machine can reach it. Loopback on its own is not access control, though - every other program on the computer can reach loopback too - so:
- Every request must carry the access token, compared in constant time.
- A request carrying a non-local
Originheader is refused, which stops a web page you visit from driving Mudlet through your browser.
Protocol notes
- Mudlet speaks MCP revision 2026-07-28 over Streamable HTTP. That revision is stateless: there is no
initializehandshake, noMcp-Session-Idand no ping, and every request repeats its protocol version and capabilities in_meta. A client written against an older revision opens withinitializeand is answered with an error naming the version this server speaks.
GETandDELETE- the standalone SSE stream and session teardown of revisions up to 2025-11-25 - are answered with405 Method Not Allowed, so an old client fails rather than hanging.
Builds
Note: The MCP server is off by default at build time, because it needs Qt6::HttpServer, which not every build environment installs. Official builds have it. To include it in your own build, set the WITH_MCPSERVER environment variable before configuring:
WITH_MCPSERVER=ON cmake --preset linux-debug
- Where it is not included, the AI assistant access (MCP) settings are hidden.
Events
- New or revised events that Mudlet can raise to inform a profile about changes. See Mudlet-raised events for the existing ones.
sysMapperButtonAction, PR #10196 merged
Note: merged, will be available in the next release. See https://github.com/Mudlet/Mudlet/pull/10196
Raised when the player presses any of the built-in map buttons - the main toolbar icon, the Toolbox menu entry or its keyboard shortcut, or a detached window's toolbar button - while setConfig("mapperButton", "scripted") is active. The event carries no arguments beyond its name. Use it to route the button press to your own map window's show/hide logic instead of the built-in mapper.
- Example
setConfig("mapperButton", "scripted")
registerAnonymousEventHandler("sysMapperButtonAction", function()
if myMapWindow.hidden then
myMapWindow:show()
else
myMapWindow:hide()
end
end)
sysServerGuiInstalled, PR #10278 merged
Note: merged, will be available in the next release. See https://github.com/Mudlet/Mudlet/pull/10278
Also raised - with no package name argument - when a game declines the built-in starter UI with Client.GUI {"baseui": false} over GMCP (see GMCP Extensions).
Handlers that read the package name from the event arguments should be ready for it to be absent.
UI Functions
- All functions that help you construct custom GUIs. They deal mainly with miniconsole/label/gauge creation and manipulation as well as displaying or formatting information on the screen.
MudMaster Chat Protocol (MMCP)
- 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/
- And at: https://mudstandards.org/mud/mmcp/
- See also https://wiki.mudlet.org/w/Notes_on_MMCP
Note: MMCP arrived in Mudlet 4.21. Its 18 available functions are documented in Networking Functions and its four events in Event Engine. The seven below are written but their Lua registrations are still commented out, so no script can call them yet - 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.
deny
- mmcp.deny(target)
- Denies an incoming connection request.
- Parameters
- target:
- Client name or ID.
Note: pending, not yet available in initial MMCP release.
peek
- mmcp.peek(target)
- Sends a request to the target client to peek at their connection list.
- 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.
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.
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.