Quick Start
This guide walks you through creating your first Lua script for GTPS Cloud, from uploading to testing.
1. Creating Your First Script
Where to Put Your Scripts
Upload your Lua scripts in the Lua tab in your server panel. Scripts are loaded automatically when the server starts.
File Naming Rules
- ✅ Use alphanumeric characters:
my_script.lua,event-handler.lua - ✅ Underscores
_and hyphens-are allowed - ❌ No spaces or special characters:
,my script.luaevent@handler.lua
Example Files
welcome_message.lua
custom-commands.lua
anti_cheat.lua
event_handler.lua2. Your First Script: Welcome Message
Create a new file called welcome.lua and add this code:
-- Welcome message script
print("Welcome script loaded!")
onPlayerLoginCallback(function(player)
player:onConsoleMessage("`2Welcome to the server, " .. player:getName() .. "!``")
end)What this does:
- Prints to server console when script loads
- Shows a console message when player logs in
3. Testing Your Script
Upload & Load
- Upload your script in the Lua tab in the panel
- Use the
/rscommand in-game to reload
Reloading Scripts
Use the /rs command in-game to reload all Lua scripts without restarting:
/rsThis is perfect for rapid development and testing!
Debugging with Print
Use print() to output debug information to your server console:
print("Script loaded successfully")
print("Player name:", player:getName())
print("Current gems:", player:getGems())4. Adding a Custom Command
Let's create a command that gives players gems:
-- gems_command.lua
onPlayerCommandCallback(function(world, player, fullCommand)
if fullCommand == "gems" then
player:addGems(100)
player:onConsoleMessage("`2You received 100 gems!``")
return true -- Command handled
end
return false -- Let other scripts handle it
end)Usage: Type /gems in-game to receive 100 gems.
Important: Return true when your script handles the command, false otherwise.
5. Working with Dialogs
Dialogs are the UI windows in Growtopia. Here's an example:
local convertCommand = {
command = "cv",
roleRequired = Roles.ROLE_DEFAULT,
description = "Open Convert Menu"
}
registerLuaCommand(convertCommand)
local function showConvertDialog(player)
local dialog = "set_default_color|\n"
dialog = dialog .. "set_bg_color|20,20,40,255|\n"
dialog = dialog .. "add_spacer|small|\n"
dialog = dialog .. "add_label_with_icon|big|`wLock Converter Menu |left|7070|\n"
dialog = dialog .. "add_custom_break|\n"
dialog = dialog .. "add_spacer|small|\n"
dialog = dialog .. "add_smalltext|`w--------------------------------------------------------------|\n"
dialog = dialog .. "add_label_with_icon|small|`w" .. player:getItemAmount(WORLD_LOCK_ID) .. "|left|" .. WORLD_LOCK_ID .. "|\n"
dialog = dialog .. "add_label_with_icon|small|`w" .. player:getItemAmount(DIAMOND_LOCK_ID) .. "|left|" .. DIAMOND_LOCK_ID .. "|\n"
dialog = dialog .. "add_label_with_icon|small|`w" .. player:getItemAmount(BLUE_GEM_LOCK) .. "|left|" .. BLUE_GEM_LOCK .. "|\n"
dialog = dialog .. "add_label_with_icon|small|`w" .. player:getItemAmount(BLACK_GEM_LOCK) .. "|left|" .. BLACK_GEM_LOCK .. "|\n"
dialog = dialog .. "add_smalltext|`w--------------------------------------------------------------|\n"
dialog = dialog .. "add_custom_break|\n"
dialog = dialog .. "add_spacer|small|\n"
dialog = dialog .. "text_scaling_string|aaaaaaaaaaaaaaaaaa|\n"
dialog = dialog .. "add_button_with_icon|convert_dl|`wBlue Gem Lock|staticYellowFrame|7188|||left|\n"
dialog = dialog .. "add_button_with_icon|convert_bgl|`wBlack Gem Lock|staticYellowFrame|20628|||left|\n"
dialog = dialog .. "add_button_with_icon|break_bbgl|`wBreak|staticYellowFrame|20628|||left|\n"
dialog = dialog .. "add_custom_break|\n"
dialog = dialog .. "add_spacer|small|\n"
dialog = dialog .. "add_label_with_icon|small|`wQuick Chat|left|11230|\n"
dialog = dialog .. "add_custom_break|\n"
dialog = dialog .. "add_spacer|small|\n"
dialog = dialog .. "text_scaling_string|aaaaaaaaaaaaaaaaaa|\n"
dialog = dialog .. "add_button_with_icon|speak_bgl|`wShow BGL|staticYellowFrame|7670|||left|\n"
dialog = dialog .. "add_button_with_icon|speak_bbgl|`wShow BBGL|staticYellowFrame|7670|||left|\n"
dialog = dialog .. "add_button_with_icon|speak_cheer|`wCheer|staticYellowFrame|7670|||left|\n"
dialog = dialog .. "add_button_with_icon|speak_total_wl|`wTotal WL|staticYellowFrame|7670|||left|\n"
dialog = dialog .. "add_custom_break|\n"
dialog = dialog .. "add_spacer|small|\n"
dialog = dialog .. "end_dialog|show_convert_dialog|Close||\n"
player:onDialogRequest(dialog)
end
onPlayerCommandCallback(function(world, player, fullCommand)
local command, args = fullCommand:match("^(%S+)%s*(.*)")
if command == convertCommand.command then
showConvertDialog(player)
return true
end
return false
end)For more dialog commands, see Dialog UI Syntax.
6. Next Steps
Now that you have the basics, explore these topics:
- Player Structure - Work with player data, inventory, currency
- World Structure - Manipulate worlds, tiles, and drops
- Callback Structure - All available event callbacks
- Event Tutorial - Create custom server events
- Server Structure - Server-wide functions and economy tracking
Tips & Best Practices
✅ Always test with /rs - No need to restart the server for script changes
✅ Use descriptive variable names - playerGems is better than g
✅ Comment your code - Help your future self understand what you wrote
✅ Return true/false correctly - In callbacks that handle commands/dialogs, return true when handled
✅ Check for nil - Always verify objects exist before using them:
local world = player:getWorld()
if world ~= nil then
-- Safe to use world
end❌ Don't forget to return in callbacks - Missing returns can cause issues
❌ Avoid infinite loops - They will freeze your server
Server Configuration
While scripts don't need configuration, you may need to set up:
- Server Configuration - In the panel under Configuration.
- Role Manager - Create and manage custom roles
- Item & Resource Manager - Add custom items
These are managed in your server panel.