Server Data Structure and Global
The Server Data API provides various global functions for managing game-wide data, events, store systems, player rankings, and server-level interactions.
Event & Offer Management
getRequiredEvent() -- Returns the required event.
getCurrentServerDailyEvent() -- Returns the current server's daily event.
getServerCurrentEvent() -- Returns the current server's event.
getIOTMItem() -- Returns the IOTM (Item of the Month) item.
addDailyOfferPurchased(player:getUserID(), changethis:getItemID()) -- Adds a daily offer purchased entry.
getRealGTItemsCount() -- Returns the total number of real GT items.
getEventOffers() -- Returns the list of current event offers.
getActiveDailyOffers() -- Returns all active daily offers.
setEvent(event_id) -- Sets the current server event.
setDailyEvent(event_id) -- Sets the current daily event.
getEvents() -- Returns a list with all events & extra data (event.id, event.title, event.description, event.message).
getDailyEvents() -- Returns a list with all daily events (event.id, event.title, event.description - no message field).
getGemEvent() -- Returns the current gem multiplier (e.g., 2 for 2x gems event).
getXPEvent() -- Returns the current XP multiplier (e.g., 3 for 3x XP event).Event Multipliers
Get active server event multipliers:
local gemMultiplier = getGemEvent()
local xpMultiplier = getXPEvent()Example:
-- Check if there's an active gem event
local gemMultiplier = getGemEvent()
if gemMultiplier > 1 then
player:onConsoleMessage("`2Active Gem Event: " .. gemMultiplier .. "x gems!")
end
-- Calculate adjusted rewards
local baseGems = 100
local adjustedGems = baseGems * getGemEvent()
player:addGems(adjustedGems)
-- Show XP event info
local xpMultiplier = getXPEvent()
if xpMultiplier > 1 then
player:onConsoleMessage("`9Current XP Bonus: " .. xpMultiplier .. "x XP!")
end
-- Display both active events
local gemMult = getGemEvent()
local xpMult = getXPEvent()
if gemMult > 1 or xpMult > 1 then
local message = "`6Active Events: "
if gemMult > 1 then
message = message .. "`2" .. gemMult .. "x Gems "
end
if xpMult > 1 then
message = message .. "`9" .. xpMult .. "x XP"
end
player:onConsoleMessage(message)
endEvent Multipliers
These functions return the active event multiplier as a number. Returns 1 when no event is active. Use these to dynamically adjust rewards based on server events.
Custom Daily Events:
local eventData = {
id = 50,
title = "Example event",
description = "Example description"
}
registerLuaDailyEvent(eventData)Custom Event Registration:
registerLuaEvent(eventData) -- Registers a custom server-wide event.Economy Management
Get item counts across the server economy:
getEcoQuantity(item_id) -- Returns total count of item in economy (players + worlds).
getEcoQuantityPlayers(item_id) -- Returns count of item in player inventories only.
getEcoQuantityWorlds(item_id) -- Returns count of item in worlds only.Economy Tracking
These functions help you track item circulation across your entire server, useful for balancing economy and detecting duplication.
Redeem Code System
Create custom redeem codes with various requirements and rewards:
local redeemData = {
redeemCode = "SPECIAL123",
obtainGems = 50,
obtainCoins = 1000,
obtainRole = 2,
redeemItems = {
{ id = 1001, count = 3 },
{ id = 2002, count = 1 },
},
maxUses = 5,
requireLevel = 10,
requireRole = 1,
requireGrowID = 1, -- (1 = true, 0 = false)
requirePlaytime = 60,
requireAccountAge = 7,
redeemTitles = {
{ titleID = 5 },
{ titleID = 9 },
}
}
local result = createRedeemCode(redeemData)
if result ~= "" then
print("Created redeem code:", result)
endFlexible Reward System
Redeem codes support gems, coins, items, titles, and roles with granular requirement controls!
Broadcast World Management
setBroadcastWorld(world_name) -- Sets broadcast world for all online players (/go command).Purchase & Store System
Purchase Events
onPurchaseItem(player, item, true/false) -- Fires the item purchase event.
onPurchaseItemReq(player, itemID) -- Fires the item purchase request event.
getStoreItems() -- Returns the list of store items.Player & World Rankings
getTopPlayerByBalance() -- Returns the top player based on balance.
getTopWorldByVisitors() -- Returns the top world based on visitors.Lua Module & Playmod System
registerLuaPlaymod(PLAYMODDATA) -- Registers a Lua-based playmod configuration.
reloadScripts() -- Reloads all Lua scripts.
getPlaymods() -- Returns list of all playmods on the server.Playmod Properties:
id- Playmod IDname- Playmod nameequipInfo- Equipment informationremoveInfo- Removal informationiconId- Icon IDskinUint- Skin uint value
Example:
local playmods = getPlaymods()
for i, playmod in ipairs(playmods) do
print("Playmod: " .. playmod.name .. " (ID: " .. playmod.id .. ")")
print(" Icon: " .. playmod.iconId)
endData Management
loadDataFromServer(data) -- Loads data from the server.
saveDataToServer(data, data2) -- Saves data to the server.
onAutoSaveRequest(function()) -- Executes on auto-save event.
savePlayer(player) -- Manually save player to database (generally not needed).
saveWorld(world) -- Manually save world to database (generally not needed).Manual Saving
The server automatically saves player and world data. Manual saves are only needed in special cases, such as when modifying offline player data (e.g., subscriptions) or making critical world changes that need immediate persistence.
Player & Global Functions
getPlayerByName(str, player_optional) -- Finds a player by name. Now supports nicked players with '/' prefix.
getPlayerByRID(rid) -- Finds a player by their RID (Remote ID).Important Note about Nickname Support:
- To find a player using their real name (even if they have a nickname), prefix with
/ - Example:
/Sebiawill find “Sebia” even if they’re using a nickname - Without
/, it searches by display name only - The optional
playerparameter is recommended if you have a player issuing the search (for permission handling)
Example:
-- Find player by display name
local players = getPlayerByName("Someone")
-- Find player by real name (bypasses nicknames)
local players = getPlayerByName("/Sebia")
-- With optional player parameter for permission handling
local target = getPlayerByName("/Sebia", player)
-- Find player by RID
local playerByRID = getPlayerByRID("1234567890ABCDEF")
if playerByRID then
print("Found player: " .. playerByRID:getName())
endCommand System Update
This new / prefix system has been applied to all default commands including /mod, /info, and others. The /mod UI command now shows both nicked and un-nicked usernames.
Item Effects Management
Global functions to manage and query item effects:
getItemEffects() -- Returns all item effects from the item manager.Returns: Array of item effects with these properties:
item_id- Item IDextra_gems- Extra gems percentage bonusextra_xp- Extra XP percentage bonusone_hit- One-hit break abilitybreak_range- Break range increasebuild_range- Build range increase
Example:
local allEffects = getItemEffects()
for i, effect in ipairs(allEffects) do
print("Item #" .. effect.item_id)
print(" Extra gems: " .. effect.extra_gems)
print(" Extra XP: " .. effect.extra_xp)
print(" One hit: " .. effect.one_hit)
print(" Break range: " .. effect.break_range)
print(" Build range: " .. effect.build_range)
endComplete Example Script
See the full example script for managing item effects below!
Complete Item Effects Management Example:
-- item_effects_test.lua - Complete example for managing item effects
print("(Loaded) item_effects_test script for GTPS Cloud")
local item = getItem(98) -- Pickaxe
-- Get current effects
local eff = item:getEffects()
print("Extra gems: " .. eff.extra_gems)
-- Set new effects (automatically saves and shows in dashboard)
item:setEffects({
extra_gems = 500,
extra_xp = eff.extra_xp,
one_hit = eff.one_hit,
break_range = eff.break_range,
build_range = eff.build_range
})
-- Verify changes
eff = item:getEffects()
print("Extra gems now: " .. eff.extra_gems)
-- Get all item effects from server
local all_effects = getItemEffects()
for i, effect in ipairs(all_effects) do
print("Item #" .. effect.item_id)
print(" extra_gems: " .. effect.extra_gems)
print(" extra_xp: " .. effect.extra_xp)
print(" one_hit: " .. effect.one_hit)
print(" break_range: " .. effect.break_range)
print(" build_range: " .. effect.build_range)
endTitles Management
getTitles() -- Returns array of all titles on the server.Returns: Array of title objects with these properties:
titleID- Unique title identifiertitleName- Title nametitleLabel- Title label texttitleDisplay- Display formattitleFlagItemID- Associated flag item ID
Example:
local titles = getTitles()
print("Server has " .. #titles .. " titles:")
for i, title in ipairs(titles) do
print(title.titleID .. ": " .. title.titleName)
print(" Label: " .. title.titleLabel)
print(" Display: " .. title.titleDisplay)
print(" Flag Item: " .. title.titleFlagItemID)
endRole Quest System
getRoleQuestDay() -- Returns today's role quest day ID (1-7).Role Quest Days:
1- Jack of all Trades Day2- Surgery Day3- Fishing Day4- Farmer Day5- Builder Day6- Chef Day7- Star Captain’s Day
Example:
local roleDay = getRoleQuestDay()
local roleDayNames = {
"Jack of all Trades Day",
"Surgery Day",
"Fishing Day",
"Farmer Day",
"Builder Day",
"Chef Day",
"Star Captain's Day"
}
print("Today is: " .. roleDayNames[roleDay])Server Information
getExpireTime() -- Returns the server's expire time.
getServerName() -- Returns the server name.
getServerID() -- Returns the server ID.
getServerPlayers() -- Returns a list of players currently on the server.
getAllPlayers() -- Get all players (use this over getServerPlayers).
getServerWorlds() -- Returns all active (loaded in-memory) worlds.
getNewsBanner() -- Returns the current news banner.
getNewsBannerDimensions() -- Returns the dimensions of the news banner.
getTodaysDate() -- Returns today's date.
getTodaysEvents() -- Returns today's events.
getCurrentEventDescription() -- Returns the description of the current event.
getCurrentDailyEventDescription() -- Returns the description of the current daily event.
getCurrentRoleDayDescription() -- Returns the description of the current role day.
getServerDefaultPort() -- Returns the server's port number.Server Management & Control
queueRestart(in_seconds, full_restart, message) -- Restarts server after delay.
-- full_restart: 0 = soft restart, 1 = full restart
-- message: optional restart message to players
deleteAccount(user_id) -- ⚠️ EXPERIMENTAL: Permanently deletes account data.
deleteWorld(world_id) -- ⚠️ EXPERIMENTAL: Permanently deletes world data.Dangerous Operations
Warning: Deletion is permanent. Deleted users/worlds show as “ERROR” in ownership data. Always backup before using!
Lua Modules System
Load other Lua scripts as modules for better code organization:
local Person = require("example_module")
local me = Person.new("Yuki")
me:say("Hello!")Creating a Module:
Add -- MODULE at the start of your module file:
-- MODULE
local person = {}
function person.new(name)
local self = {name = name}
function self:say(msg)
print(self.name .. " says: " .. msg)
end
return self
end
return personModule System
Modules are only loaded when required, not on startup. This keeps your server efficient and your code organized!
Timer Functions
Schedule delayed or repeating tasks:
timer.setTimeout(callback, delayMs) -- Execute callback once after delay.
timer.setInterval(callback, intervalMs) -- Execute callback repeatedly. Returns timer ID.
timer.clear(timerID) -- Stop a repeating timer.Example:
-- One-time delayed execution
timer.setTimeout(function()
broadcast("`2Server restart in 5 minutes!")
end, 300000) -- 5 minutes
-- Repeating timer (countdown)
local countdown = 10
local timerID = timer.setInterval(function()
if countdown > 0 then
broadcast("`4Countdown: " .. countdown)
countdown = countdown - 1
else
broadcast("`2Event started!")
timer.clear(timerID) -- Stop the timer
end
end, 1000) -- Every 1 secondTimer Best Practices
Always store interval IDs and clear them when done to prevent memory leaks. Use setTimeout for one-time delays and setInterval for recurring tasks.
File System Operations
Create, read, and manage files via Lua:
file.read(path) -- Read file contents as string.
file.write(path, content) -- Write content to file.
file.exists(path) -- Check if file exists.
file.delete(path) -- Delete a file.
dir.create(path) -- Create a directory.
dir.exists(path) -- Check if directory exists.
dir.delete(path) -- Delete a directory.Example:
local server_conf = file.read("config/conf.json")
print(server_conf)
file.write("config/random_file.txt", "hi")
local content = file.read("config/random_file.txt")
print(content)File System Safety
Be extremely careful with delete operations - you can accidentally delete critical server files!
SQL Database Support
Use SQLite databases to store custom data:
local db = sqlite.open("test1.db")
db:query("CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT)")
local ok, last_id = db:query("INSERT INTO users(name) VALUES('Nyaa')")
if ok then
print("Created new user: " .. last_id)
end
local rows = db:query("SELECT * FROM users")
for i, row in ipairs(rows) do
print(i, row.id, row.name)
end
db:close()Persistent Data Storage
SQLite provides a robust way to store structured data that persists across server restarts!
Bitwise Operations
Perform bitwise operations for flag manipulation:
bit.band(x, y) -- Bitwise AND.
bit.lshift(x, n) -- Left shift x by n positions.Example:
-- Create flag constants
local FLAG_1 = bit.lshift(1, 0) -- 1
local FLAG_2 = bit.lshift(1, 1) -- 2
local FLAG_3 = bit.lshift(1, 2) -- 4
local FLAG_4 = bit.lshift(1, 3) -- 8
-- Check if tile has specific flag
local flags = tile:getFlags()
local TILE_FLAG_IS_ON = bit.lshift(1, 6)
if bit.band(flags, TILE_FLAG_IS_ON) ~= 0 then
print("Tile is ON")
end
-- Combine multiple flags
local combined = FLAG_1 + FLAG_3 -- 5
if bit.band(combined, FLAG_1) ~= 0 then
print("FLAG_1 is set")
endFlag Checking
Use bit.band to check if specific flag bits are set. A non-zero result means the flag is active. Use bit.lshift to create flag constants.
HTTP Request Handling
Handle HTTP requests to your server via Lua:
print("HTTP Lua API running on port: " .. getServerDefaultPort())
onHTTPRequest(function(req) -- MUST return a response!
-- Access original request headers
local userAgent = req.headers["User-Agent"]
if req.method == "get" and req.path == "/hello" then
return {
status = 200,
body = "Hello back",
headers = { ["Content-Type"] = "text/plain" }
}
end
if req.method == "post" and req.path == "/echo" then
return {
status = 200,
body = "Body: " .. req.body,
headers = { ["Content-Type"] = "text/plain" }
}
end
return {
status = 404,
body = "Not found",
headers = {}
}
end)HTTP API URL Format
https://api.gtps.cloud/g-api/{server_port}/...
The callback shows the real request IP instead of localhost.
JSON Encoding
Pretty print JSON data:
json.encode(data) -- Compact encoding
json.encode(data, 4) -- Pretty print with 4-space indentationDiscord Integration
Handle Discord bot events via Lua callbacks and send messages programmatically.
Discord Event Methods
All Discord events support these common methods:
event:getAuthorID() -- Returns the Discord user ID that invoked the event
event:getChannelID() -- Returns the Discord channel ID
event:getCustomID() -- Returns the custom ID (for buttons/forms)
event:getMessageID() -- Returns the message ID associated with the eventSlash Command Event Methods:
event:getCommandName() -- Returns the slash command name
event:getParameter(name) -- Returns the value of a command parameter
event:thinking() -- Shows "Bot is thinking..." message (use event:thinking(1) for ephemeral)
event:editOriginalResponse(content, components, flags) -- Edit the original response messageBot Ready Callback
Called when the Discord bot is ready and online. Use this to register global commands:
onDiscordBotReadyCallback(function()
print("Discord bot is ready")
-- Register global slash commands
DiscordBot.globalCommandCreate("punish", "Punish player", {
{ type="string", name="player_name", description="Player name", required=true }
})
DiscordBot.globalCommandCreate("status", "Check server status", {})
end)Slash Command Callback
Handle Discord slash commands:
onDiscordSlashCommandCallback(function(e)
local player = e:getPlayer() -- If user has account linked, returns valid GTPS player
local commandName = e:getCommandName()
local channelID = e:getChannelID()
local authorID = e:getAuthorID()
print("Received slash command: " .. commandName .. " from " .. authorID)
if commandName == "punish" then
e:thinking() -- Shows "Bot is thinking..." (use e:thinking(1) for ephemeral)
local playerName = e:getParameter("player_name")
if playerName == "" then
e:editOriginalResponse("Error: You need to enter a player name.")
return
end
local foundPlayers = getPlayerByName(playerName)
if #foundPlayers == 0 then
e:editOriginalResponse("No player found with name: " .. playerName)
return
end
local targetPlayer = foundPlayers[1]
e:editOriginalResponse(
"**" .. targetPlayer:getCleanName() .. "** (ID " .. targetPlayer:getUserID() .. ")",
{ -- Components (buttons) - note the row structure
{ -- Row 1
{
type = "button",
label = "Ban 60 days",
style = "danger",
emoji = "😭",
id = "ban_usr_" .. targetPlayer:getUserID()
}
}
}
)
end
end)Reply Flags
Use these flags to modify reply message behavior:
ReplyFlags = {
CROSSPOSTED = bit.lshift(1, 0),
IS_CROSSPOST = bit.lshift(1, 1),
SUPRESS_EMBEDS = bit.lshift(1, 2),
SOURCE_MESSAGE_DELETED = bit.lshift(1, 3),
URGENT = bit.lshift(1, 4),
HAS_THREAD = bit.lshift(1, 5),
EPHEMERAL = bit.lshift(1, 6),
LOADING = bit.lshift(1, 7),
THREAD_MENTION_FAILED = bit.lshift(1, 8),
SUPRESS_NOTIFICATIONS = bit.lshift(1, 12),
IS_VOICE_MESSAGE = bit.lshift(1, 13),
HAS_SNAPSHOT = bit.lshift(1, 14),
USING_COMPONENTS_V2 = bit.lshift(1, 15)
}Message Create Callback
onDiscordMessageCreateCallback(function(event)
if event:isBot() then return end
local content = event:getContent()
local channel_id = event:getChannelID() -- String
local author_id = event:getAuthorID() -- Discord user ID
local mentioned_users = event:getMentionedUsers() -- Array of mentioned user IDs
print("Message: " .. content .. " (Channel " .. channel_id .. ")")
print("Author ID: " .. author_id)
-- Check mentioned users
if mentioned_users then
for i, user_id in ipairs(mentioned_users) do
print("Mentioned user: " .. user_id)
end
end
if content:sub(1, 6) == "-hello" then
-- Reply with button, ephemeral flag, and mention the author
event:reply(
"This is a test message with a button",
{ -- Components now use row structure
{ -- Row 1
{
type = "button",
label = "Click me!",
style = "success",
emoji = "🔓",
id = "click_click"
}
}
},
ReplyFlags.EPHEMERAL, -- Make message only visible to author
1 -- Mention the replied user (1 = yes, 0 = no)
)
end
end)DiscordMessageCreateEvent Methods:
event:getContent() -- Get message content
event:getChannelID() -- Get channel ID (string)
event:getAuthorID() -- Get author's Discord user ID (string)
event:getMentionedUsers() -- Get array of mentioned user IDs
event:isBot() -- Check if message is from a bot
event:reply(content, components, flags, mention_replied_user)Reply Signature:
event:reply(content, components, flags, mention_replied_user)
-- content: string
-- components: table (optional)
-- flags: number (optional, use ReplyFlags)
-- mention_replied_user: 0 or 1 (optional, default 0)Button Click Callback
onDiscordButtonClickCallback(function(event)
local custom_id = event:getCustomID()
local channel_id = event:getChannelID()
local author_id = event:getAuthorID()
if custom_id == "click_click" then
event:dialog({
id = "random_modal",
title = "Hello World",
components = {
{
type = "text",
label = "Enter some text",
id = "entered_text",
placeholder = "Text",
min = 3,
max = 32,
style = "short"
}
}
})
end
end)DiscordButtonClickEvent Methods:
event:getCustomID() -- Get button's custom ID
event:getChannelID() -- Get channel ID (string)
event:getAuthorID() -- Get author's Discord user ID (string)
event:reply(content, components, flags)
event:dialog(dialogData) -- Show a modal/formReply Signature:
event:reply(content, components, flags)
-- content: string
-- components: table (optional)
-- flags: number (optional, use ReplyFlags)Form Submit Callback
onDiscordFormSubmitCallback(function(event)
local custom_id = event:getCustomID()
local author_id = event:getAuthorID()
if custom_id == "random_modal" then
local entered_value = event:getValue("entered_text")
-- Send ephemeral response
event:reply(
"You entered: " .. entered_value,
nil,
ReplyFlags.EPHEMERAL
)
end
end)DiscordFormSubmitEvent Methods:
event:getCustomID() -- Get form's custom ID
event:getValue(fieldID) -- Get value of a form field
event:getChannelID() -- Get channel ID (string)
event:getAuthorID() -- Get author's Discord user ID (string)
event:reply(content, components, flags)Reply Signature:
event:reply(content, components, flags)
-- content: string
-- components: table (optional)
-- flags: number (optional, use ReplyFlags)Discord Bot Class
Send messages from your bot without requiring an event trigger:
Message Methods
DiscordBot.messageCreate(channel_id_string, message, components, flags, type, embeds)
DiscordBot.directMessageCreate(user_id_string, message, components, flags, type, embeds)
DiscordBot.messageEdit(message_id_string, channel_id_string, content, components, flags, type)
DiscordBot.messageDelete(message_id_string, channel_id_string)Parameters:
channel_id_string- Discord channel ID (string)user_id_string- Discord user ID for DMs (string)message_id_string- Discord message ID to edit/delete (string)message/content- Message content (string)components- Button/component array in row structure (optional, can be nil)flags- Message flags (optional, use ReplyFlags)type- Message type (usually 0)embeds- Embed object (optional, see Embeds section below)
Slash Command Methods
DiscordBot.globalCommandCreate(name, description, parameters)Parameters:
name- Command name (string)description- Command description (string)parameters- Array of parameter definitions (see example above)
Guild Member Methods
DiscordBot.guildMemberSetNickname(guild_id, user_id, nick)
DiscordBot.guildMemberAddRole(guild_id, user_id, role_id)
DiscordBot.guildMemberRemoveRole(guild_id, user_id, role_id)
DiscordBot.guildMemberGetRoles(guild_id, user_id, callback)Parameters:
guild_id- Discord server/guild ID (string)user_id- Discord user ID (string)role_id- Discord role ID (string)nick- New nickname (string)callback- Function to receive role IDs when usingguildMemberGetRoles
Get Member Roles:
-- Get roles via callback (less efficient, use event method if available)
DiscordBot.guildMemberGetRoles("1400135437183483977", "936325029354942475", function(roles)
for i, roleID in ipairs(roles) do
print("Role: " .. roleID) -- roleID is a string
end
end)Role IDs Are Strings
All Discord role IDs returned by getRoles() methods are strings, not numbers. This is due to Lua’s integer limitations with large Discord IDs.
Efficiency Note
Using DiscordBot.guildMemberGetRoles() is not very efficient. If you have access to the event (like in onDiscordMessageCreateCallback), use event:getRoles() instead for better performance!
Get Roles from Event (More Efficient):
onDiscordMessageCreateCallback(function(e)
local roles = e:getRoles()
for i, roleID in ipairs(roles) do
print("Role: " .. roleID) -- roleID is a string
end
end)Other Examples:
-- Send a message to a specific channel when player logs in
onPlayerLoginCallback(function(player)
DiscordBot.messageCreate(
"1400135437183483980",
player:getName() .. " has joined the server!",
nil,
0,
0
)
end)
-- Send a direct message to a specific user
DiscordBot.directMessageCreate(
"936325029354942475",
"Hello! Your verification code is: 12345",
nil,
0,
0
)
-- Send a message with buttons (row structure)
DiscordBot.messageCreate(
"1400135437183483980",
"Click the button below to claim your reward!",
{ -- Components now use row structure
{ -- Row 1
{
type = "button",
label = "Claim Reward",
style = "success",
emoji = "🎁",
id = "claim_reward_btn"
},
{
type = "button",
label = "View Info",
style = "primary",
emoji = "ℹ️",
id = "info_btn"
}
},
{ -- Row 2
{
type = "button",
label = "Cancel",
style = "danger",
emoji = "❌",
id = "cancel_btn"
}
}
},
0,
0
)
-- Edit a message
DiscordBot.messageEdit(
"1234567890123456789", -- message_id
"1400135437183483980", -- channel_id
"This message has been edited!",
nil, -- no components
0,
0
)
-- Delete a message
DiscordBot.messageDelete(
"1234567890123456789", -- message_id
"1400135437183483980" -- channel_id
)
-- Send ephemeral notification when player deposits
onPlayerLoginCallback(function(player)
local discordID = player:getDiscordID()
if discordID and discordID ~= "" then
DiscordBot.directMessageCreate(
discordID,
"Welcome back, " .. player:getName() .. "!",
nil,
ReplyFlags.EPHEMERAL,
0
)
end
end)Component Rows
Important: Components now support rows. The old flat component format is no longer supported!
components = {
{ -- Row 1
{ type = "button", label = "Button 1", style = "primary", id = "btn1" },
{ type = "button", label = "Button 2", style = "success", id = "btn2" }
},
{ -- Row 2
{ type = "button", label = "Button 3", style = "danger", id = "btn3" }
}
}Embeds
Embeds are rich message cards that can be added to messages. Embeds are the last parameter for message methods:
DiscordBot.messageCreate(
"1400135437183483980", -- channel_id
"", -- message content (can be empty when using embeds)
{ -- components (buttons)
{ -- Row 1
{
type = "button",
label = "Verify Account",
style = "success",
emoji = "🔒",
id = "verify_btn"
},
{
type = "button",
label = "Sync Roles",
style = "primary",
emoji = "📊",
id = "sync_btn"
}
},
{ -- Row 2
{
type = "button",
label = "Change Password",
style = "danger",
emoji = "🔑",
id = "password_btn"
}
}
},
0, -- flags
0, -- type
{ -- embeds
title = "GTPS Account Menu",
description = "Manage your account settings & change password if you forgot your password.",
color = 5763719, -- Decimal color value
author = {
name = "My Server",
icon = "https://cdn-icons-png.flaticon.com/512/3150/3150115.png"
},
fields = {
{ name = "Top Players", value = "user1\nuser2\nuser3" },
{ name = "Server Status", value = "Online" }
}
}
)Embed Fields:
title- Embed title (string)description- Embed description (string)color- Embed color as decimal number (use online converter for hex to decimal)author- Author object withnameand optionalicon(URL)fields- Array of field objects withnameandvaluefooter- Footer object withtextand optionalicon(URL)thumbnail- Thumbnail object withurlimage- Image object withurltimestamp- ISO 8601 timestamp stringurl- URL that title links to
Guild Member Management
-- Set nickname
DiscordBot.guildMemberSetNickname(
"936325029354942475", -- guild_id
"123456789012345678", -- user_id
"NewNickname"
)
-- Add role
DiscordBot.guildMemberAddRole(
"936325029354942475", -- guild_id
"123456789012345678", -- user_id
"987654321098765432" -- role_id
)
-- Remove role
DiscordBot.guildMemberRemoveRole(
"936325029354942475", -- guild_id
"123456789012345678", -- user_id
"987654321098765432" -- role_id
)Important Notes
Usually set type to 0. Components must use the new row structure, and embeds are optional.
Discord Bot Integration
Create interactive Discord bots with buttons, modals, forms, slash commands, and rich embeds directly from Lua! Send messages proactively without waiting for events.
World Menu Management
World Menu Worlds
addWorldMenuWorld(worldID, displayName, color, priority) -- Adds a world to the world menu.
removeWorldMenuWorld(worldID) -- Removes a world from the world menu.
hideWorldMenuDefaultSpecialWorlds(0/1) -- Hides or shows default special worlds (1 = hide, 0 = show).World Menu Buttons
registerWorldMenuButton(text, id) -- Registers a custom button in the world menu.
unregisterWorldMenuButton(id) -- Removes a custom button from the world menu.Example:
-- Add a custom world menu button
registerWorldMenuButton("View Server Stats", "stats_button")
-- Handle button click in dialog callback
onPlayerDialogResponseCallback(function(world, player, data)
if data["buttonClicked"] == "stats_button" then
player:onConsoleMessage("`2Server Stats: ...")
-- Show stats
end
end)
-- Remove button when no longer needed
unregisterWorldMenuButton("stats_button")Server Persistence (Key-Based)
loadDataFromServer(key) -- Loads a Lua table using a key from the server.
saveDataToServer(key, dataTable) -- Saves a Lua table to the server using a specific key.
loadStringFromServer(key) -- Loads a string value from the server.
saveStringToServer(key, value) -- Saves a string value to the server.UI & Event Registration
registerLuaEvent(eventData) -- Registers a custom server-wide event.
addSidebarButton(buttonJson) -- Adds a button to the player's sidebar UI using a JSON definition.
addSocialPortalButton(buttonDef, callback) -- Adds a button to the social portal with an assigned callback.