Multi-Session Functions
Functions for working with multiple MUD connections. The multi-session API allows plugins to manage and communicate across multiple simultaneous MUD connections.
Session Information
getSession
Get information about the current session.
getSession()Returns: table | null - Session information object or null if no session.
| Property | Type | Description |
|---|---|---|
| id | string | Unique session identifier |
| name | string | Session display name |
| host | string | MUD server hostname |
| port | number | MUD server port |
| connected | boolean | Whether the session is connected |
| active | boolean | Whether this is the currently active session |
Example:
local session = getSession()
if session then
print("Session: " .. session.name)
print("Connected to: " .. session.host .. ":" .. session.port)
print("Status: " .. (session.connected and "Connected" or "Disconnected"))
endgetSessionId
Get the current session’s unique identifier.
getSessionId()Returns: string | null - The session ID or null if no session.
Example:
local id = getSessionId()
if id then
print("Current session ID: " .. id)
endgetAllSessions
Get information about all sessions.
getAllSessions()Returns: table - Array of session information objects (same format as getSession()).
Example:
local sessions = getAllSessions()
print("Active sessions: " .. #sessions)
for i, session in ipairs(sessions) do
local status = session.connected and "Connected" or "Disconnected"
local active = session.active and " [ACTIVE]" or ""
print(i .. ". " .. session.name .. " - " .. status .. active)
endgetSessionById
Get session information by its unique ID.
getSessionById(sessionId)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | The session ID to look up |
Returns: table | null - Session information object or null if not found.
Example:
local session = getSessionById("abc123")
if session then
print("Found session: " .. session.name)
endgetSessionByName
Get session information by its display name.
getSessionByName(name)| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | The session name to look up |
Returns: table | null - Session information object or null if not found.
Example:
local session = getSessionByName("Main Character")
if session then
print("Session ID: " .. session.id)
print("Connected: " .. tostring(session.connected))
endisActiveSession
Check if the current session is the active (focused) session.
isActiveSession()Returns: boolean - true if this is the active session, false otherwise.
Example:
if isActiveSession() then
-- Only show notifications for active session
print("New message received!")
else
-- Could trigger system notification instead
log("Message received in background session")
endCross-Session Commands
sendToSession
Send a command to a session by name.
sendToSession(sessionName, command)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionName | string | Yes | The session name to send to |
| command | string | Yes | The command to send |
Returns: boolean - true if the command was sent successfully.
Example:
-- Send command to specific character
sendToSession("Healer", "cast heal tank")
sendToSession("Tank", "rescue mage")sendToSessionId
Send a command to a session by its unique ID.
sendToSessionId(sessionId, command)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionId | string | Yes | The session ID to send to |
| command | string | Yes | The command to send |
Returns: boolean - true if the command was sent successfully.
Example:
local targetId = "session-abc123"
sendToSessionId(targetId, "follow leader")sendToAll
Send a command to all connected sessions.
sendToAll(command)| Parameter | Type | Required | Description |
|---|---|---|---|
| command | string | Yes | The command to send to all sessions |
Returns: number - The number of sessions the command was sent to.
Example:
-- Make all characters follow
local count = sendToAll("follow leader")
print("Sent follow command to " .. count .. " sessions")
-- Group recall
sendToAll("recall")sendToOthers
Send a command to all sessions except the current one.
sendToOthers(command)| Parameter | Type | Required | Description |
|---|---|---|---|
| command | string | Yes | The command to send |
Returns: number - The number of sessions the command was sent to.
Example:
-- Tell other characters to follow you
sendToOthers("follow " .. getVariable("myName"))
-- Group command excluding self
sendToOthers("assist tank")Cross-Session Variables
Variables in another session can be either session-level (Settings > Variables) or plugin-specific (a particular plugin’s private variable).
getSessionVariable
Get a variable’s value from another session.
-- Get session-level variable
getSessionVariable(sessionName, variableName)
-- Get a specific plugin's variable from that session
getSessionVariable(sessionName, variableName, pluginId)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionName | string | Yes | The session name |
| variableName | string | Yes | The variable name to retrieve |
| pluginId | string | No | If provided, gets that plugin’s private variable |
Returns: any - The variable value, or nil if not found.
Example:
-- Get session-level variable (Settings > Variables)
local healerMana = getSessionVariable("Healer", "currentMana")
if healerMana and healerMana < 100 then
utilprint("$Y[WARNING]$W Healer is low on mana: " .. healerMana)
end
-- Get a specific plugin's variable from another session
-- First, find the plugin ID
local combatPlugin = findPluginByName("Combat Tracker")
if combatPlugin then
local tankTarget = getSessionVariable("Tank", "current_target", combatPlugin.id)
if tankTarget then
utilprint("$C[INFO]$W Tank is targeting: " .. tankTarget)
end
endsetSessionVariable
Set a variable’s value in another session.
-- Set session-level variable
setSessionVariable(sessionName, variableName, value)
-- Set a specific plugin's variable in that session
setSessionVariable(sessionName, variableName, value, pluginId)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionName | string | Yes | The session name |
| variableName | string | Yes | The variable name to set |
| value | any | Yes | The value to set |
| pluginId | string | No | If provided, sets that plugin’s private variable |
Returns: boolean - true if the variable was set successfully.
Example:
-- Set session-level variables for coordination
setSessionVariable("Tank", "currentTarget", "Ancient Dragon")
setSessionVariable("Healer", "healPriority", "Tank")
setSessionVariable("DPS", "assistTarget", "Tank")
-- Set a specific plugin's variable remotely
local myPluginId = getPluginId()
setSessionVariable("Healer", "heal_request", "Tank", myPluginId)getAllSessionVariables
Get a variable’s value from all sessions.
getAllSessionVariables(variableName)| Parameter | Type | Required | Description |
|---|---|---|---|
| variableName | string | Yes | The variable name to retrieve from all sessions |
Returns: table - A table mapping session IDs to {name, value} pairs.
Example:
-- Get health from all characters for a group display
local healthData = getAllSessionVariables("currentHealth")
utilprint("$G[GROUP STATUS]$W")
for sessionId, data in pairs(healthData) do
local color = data.value > 500 and "$G" or data.value > 200 and "$Y" or "$R"
utilprint(" " .. color .. data.name .. "$W: " .. data.value .. " HP")
endCross-Session Events
onGlobal
Subscribe to events from all sessions. Returns an unsubscribe function.
onGlobal(event, callback)| Parameter | Type | Required | Description |
|---|---|---|---|
| event | string | Yes | The event name to subscribe to |
| callback | function | Yes | Function called when the event fires |
Returns: function - Call this function to unsubscribe.
Example:
-- Listen for combat events from any session
local unsub = onGlobal("combat:start", function(data)
print("Combat started in session: " .. data.sessionName)
end)
-- Later, to unsubscribe:
unsub()broadcast
Broadcast an event to all sessions.
broadcast(event, data?)| Parameter | Type | Required | Description |
|---|---|---|---|
| event | string | Yes | The event name to broadcast |
| data | any | No | Optional data to send with the event |
Example:
-- Notify all sessions of group formation
broadcast("group:formed", {
leader = "Tank",
members = {"Tank", "Healer", "DPS1", "DPS2"}
})
-- Simple event broadcast
broadcast("combat:start")emitToSession
Send an event to a specific session.
emitToSession(sessionName, event, data?)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionName | string | Yes | The session to send the event to |
| event | string | Yes | The event name |
| data | any | No | Optional data to send with the event |
Returns: boolean - true if the event was sent successfully.
Example:
-- Tell healer to heal a specific target
emitToSession("Healer", "heal:request", {
target = "Tank",
priority = "high"
})Cross-Session GMCP
getSessionGMCP
Get GMCP data from another session.
getSessionGMCP(sessionName, packageName?)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionName | string | Yes | The session name |
| packageName | string | No | Optional GMCP package name. If omitted, returns all GMCP data. |
Returns: any - The GMCP data, or null if not available.
Example:
-- Get healer's current vitals
local vitals = getSessionGMCP("Healer", "Char.Vitals")
if vitals then
print("Healer HP: " .. vitals.hp .. "/" .. vitals.maxhp)
end
-- Get all GMCP data from a session
local allGmcp = getSessionGMCP("Tank")getAllSessionGMCP
Get GMCP data for a specific package from all sessions.
getAllSessionGMCP(packageName)| Parameter | Type | Required | Description |
|---|---|---|---|
| packageName | string | Yes | The GMCP package name to retrieve |
Returns: table - A table mapping session IDs to {name, data} pairs.
Example:
-- Get vitals from all characters
local allVitals = getAllSessionGMCP("Char.Vitals")
for sessionId, info in pairs(allVitals) do
local v = info.data
print(info.name .. ": " .. v.hp .. "/" .. v.maxhp .. " HP")
endSession Switching
switchToSession
Switch the active session to another session.
switchToSession(sessionName)| Parameter | Type | Required | Description |
|---|---|---|---|
| sessionName | string | Yes | The session name to switch to |
Returns: boolean - true if the switch was successful.
Example:
-- Switch to healer when health is low
if myHealth < 100 then
switchToSession("Healer")
endMulti-Session Use Cases
Group Health Monitor Widget
A visual widget showing all party members’ health across sessions.
plugin = {
name = "Group Health Monitor",
version = "1.0",
description = "Visual health bars for all characters"
}
local widgetId = nil
function init()
utilprint("$G[Group Monitor]$W Initializing...")
-- Create the health display widget
widgetId = createWidget({
name = "group-health",
title = "Party Health",
width = 220,
height = 200,
x = 10,
y = 10
})
-- Initial draw
updateGroupHealth()
-- Update on any GMCP vitals change from any session
onGlobal("gmcp:Char.Vitals", function(data)
updateGroupHealth()
end)
-- Also update on MSDP health changes
onMSDPChangeGlobal("HEALTH", function(sessionId, value, oldValue)
updateGroupHealth()
end)
showWidget(widgetId)
end
function updateGroupHealth()
clearWidget(widgetId)
-- Draw background
drawRect(0, 0, 220, 200, "#1a1a2e")
drawText("Party Health", 10, 20, "bold 14px Arial", "#ffffff")
local allVitals = getAllSessionGMCP("Char.Vitals")
local y = 40
for sessionId, info in pairs(allVitals) do
local v = info.data
if v and v.hp and v.maxhp then
local pct = v.hp / v.maxhp
local barWidth = 180
-- Health bar background
drawRect(10, y, barWidth, 25, "#333333")
-- Health bar fill (color based on %)
local barColor = "#22c55e" -- green
if pct < 0.25 then
barColor = "#ef4444" -- red
elseif pct < 0.5 then
barColor = "#f59e0b" -- yellow
end
drawRect(10, y, barWidth * pct, 25, barColor)
-- Character name and HP text
local hpText = info.name .. ": " .. v.hp .. "/" .. v.maxhp
drawText(hpText, 15, y + 17, "12px Arial", "#ffffff")
y = y + 35
end
end
-- If no data, show message
if y == 40 then
drawText("No party members found", 10, 60, "12px Arial", "#888888")
drawText("Connect more sessions", 10, 80, "12px Arial", "#666666")
end
endMulti-Box Follow System
Automatically makes all alt characters follow when the leader moves.
plugin = {
name = "Auto Follow",
version = "1.0",
description = "Alts automatically follow the leader"
}
local isLeader = false
local leaderName = "Tank" -- Change to your main character's session name
function init()
local currentSession = getSession()
isLeader = currentSession and currentSession.name == leaderName
if isLeader then
utilprint("$G[Follow]$W This is the LEADER session")
setupLeader()
else
utilprint("$Y[Follow]$W This is a FOLLOWER session")
setupFollower()
end
end
function setupLeader()
-- When leader moves, broadcast to followers
onGMCPUpdate("Room.Info", function(data)
local myName = getVariable("character_name") or leaderName
-- Tell all other sessions to follow
broadcast("follow:move", {
leader = myName,
room = data.num or data.id
})
end)
-- Command to make everyone follow
addAlias("^#gather$", "", function()
local myName = getVariable("character_name") or leaderName
sendToOthers("follow " .. myName)
utilprint("$G[Follow]$W Gathering all characters...")
end)
end
function setupFollower()
-- Listen for leader movement
onGlobal("follow:move", function(data)
local myName = getVariable("character_name")
if myName ~= data.leader then
Send("follow " .. data.leader)
end
end)
-- Auto-follow when entering the game
addTrigger("Welcome to", function()
addTimer(2000, function()
local leaderSession = getSessionByName(leaderName)
if leaderSession and leaderSession.connected then
Send("follow " .. leaderName)
utilprint("$G[Follow]$W Auto-following " .. leaderName)
end
end, false)
end)
endCoordinated Combat System
Multi-character combat coordination with role-based commands.
plugin = {
name = "Combat Coordinator",
version = "1.0",
description = "Coordinate attacks across multiple characters"
}
-- Define character roles
local roles = {
Tank = { session = "Tank", commands = { engage = "kill", taunt = "rescue" } },
Healer = { session = "Healer", commands = { heal = "cast heal", buff = "cast bless" } },
DPS1 = { session = "Rogue", commands = { attack = "backstab", special = "circle" } },
DPS2 = { session = "Mage", commands = { attack = "cast fireball", special = "cast meteor" } }
}
function init()
utilprint("$G[Combat]$W Coordinator loaded!")
utilprint("$C[Commands]$W #attack <target> | #assist | #retreat | #heal <name>")
-- Coordinated attack command
addAlias("^#attack (.+)$", "", function(line, matches)
local target = matches[2]
coordinateAttack(target)
end)
-- Everyone assist the tank
addAlias("^#assist$", "", function()
local tankTarget = getSessionVariable("Tank", "current_target")
if tankTarget then
coordinateAttack(tankTarget)
else
utilprint("$R[Combat]$W Tank has no target!")
end
end)
-- Emergency retreat
addAlias("^#retreat$", "", function()
utilprint("$R[Combat]$W RETREAT!")
sendToAll("flee")
addTimer(1000, function()
sendToAll("recall")
end, false)
end)
-- Heal a specific character
addAlias("^#heal (.+)$", "", function(line, matches)
local target = matches[2]
sendToSession("Healer", "cast heal " .. target)
utilprint("$G[Combat]$W Healer targeting " .. target)
end)
-- Monitor for low health across all sessions
onGlobal("gmcp:Char.Vitals", function(data)
if data.hp and data.maxhp then
local pct = data.hp / data.maxhp
if pct < 0.3 then
-- Auto-heal when someone gets low
local charName = data.__sessionName or "unknown"
utilprint("$R[Combat]$W " .. charName .. " health critical! Auto-healing...")
sendToSession("Healer", "cast heal " .. charName)
end
end
end)
end
function coordinateAttack(target)
utilprint("$G[Combat]$W Coordinating attack on: " .. target)
-- Store target for reference
setVariable("group_target", target)
broadcast("combat:target", { target = target })
-- Tank engages first
sendToSession(roles.Tank.session, roles.Tank.commands.engage .. " " .. target)
-- DPS waits a moment then attacks
addTimer(1500, function()
sendToSession(roles.DPS1.session, roles.DPS1.commands.attack .. " " .. target)
sendToSession(roles.DPS2.session, roles.DPS2.commands.attack .. " " .. target)
end, false)
-- Healer assists tank
sendToSession(roles.Healer.session, "assist " .. roles.Tank.session)
endGold/Loot Sharing System
Track and share gold across all characters.
plugin = {
name = "Gold Tracker",
version = "1.0",
description = "Track gold across all characters"
}
function init()
utilprint("$Y[Gold]$W Tracker loaded!")
-- Track gold gains
addTrigger("You receive (%d+) gold", function(line, matches)
local gold = tonumber(matches[2])
local currentGold = getVariable("total_gold") or 0
setVariable("total_gold", currentGold + gold)
-- Broadcast gold update
broadcast("gold:update", {
session = getSession().name,
gained = gold,
total = currentGold + gold
})
end, true)
-- Command to see all gold
addAlias("^#gold$", "", function()
utilprint("$Y[Gold Status]$W")
local sessions = getAllSessions()
local totalGold = 0
for i, s in ipairs(sessions) do
local gold = getSessionVariable(s.name, "total_gold") or 0
totalGold = totalGold + gold
utilprint(" " .. s.name .. ": $Y" .. gold .. "$W gold")
end
utilprint(" $G───────────────$W")
utilprint(" Total: $Y" .. totalGold .. "$W gold")
end)
-- Command to transfer gold
addAlias("^#sendgold (%w+) (%d+)$", "", function(line, matches)
local target = matches[2]
local amount = matches[3]
-- Find target in same room (you'd need to verify this)
Send("give " .. amount .. " gold " .. target)
utilprint("$Y[Gold]$W Sending " .. amount .. " gold to " .. target)
end)
endSession Status Dashboard
A comprehensive status widget showing all session states.
plugin = {
name = "Session Dashboard",
version = "1.0",
description = "Overview of all connected sessions"
}
local widgetId = nil
function init()
widgetId = createWidget({
name = "session-dashboard",
title = "Sessions",
width = 250,
height = 180,
x = 10,
y = 220
})
-- Update every 5 seconds
addTimer(5000, updateDashboard, true)
-- Also update on session events
onGlobal("session:connected", updateDashboard)
onGlobal("session:disconnected", updateDashboard)
updateDashboard()
showWidget(widgetId)
end
function updateDashboard()
clearWidget(widgetId)
drawRect(0, 0, 250, 180, "#0f172a")
drawText("Session Status", 10, 20, "bold 14px Arial", "#ffffff")
local sessions = getAllSessions()
local y = 45
for i, s in ipairs(sessions) do
-- Connection indicator
local statusColor = s.connected and "#22c55e" or "#ef4444"
drawCircle(20, y, 6, statusColor)
-- Session name
local nameColor = s.active and "#60a5fa" or "#94a3b8"
drawText(s.name, 35, y + 4, "13px Arial", nameColor)
-- Active indicator
if s.active then
drawText("[ACTIVE]", 180, y + 4, "10px Arial", "#60a5fa")
end
-- Connection info
if s.connected then
local info = s.host .. ":" .. s.port
drawText(info, 35, y + 18, "10px Arial", "#64748b")
else
drawText("Disconnected", 35, y + 18, "10px Arial", "#ef4444")
end
y = y + 40
end
-- Summary line
local connected = 0
for _, s in ipairs(sessions) do
if s.connected then connected = connected + 1 end
end
drawText(connected .. "/" .. #sessions .. " connected", 10, 165, "11px Arial", "#64748b")
end