Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ZTzTopia/GTProxy/llms.txt

Use this file to discover all available pages before exploring further.

Your First Script

Let’s create a simple script that welcomes you when you connect to a world.

Step 1: Create the Script File

Create a new file in the scripts/ directory called welcome.lua:
-- welcome.lua
logger.info("Welcome script loaded!")

event.on("server:Connect", function(ctx)
    logger.info("Connected to game server")
end)

event.on("OnSpawn", function(ctx)
    if ctx:has_packet() then
        local pkt = ctx:get_packet()
        
        local log = LogPacket.new()
        log.msg = "`2Welcome to the world, `` " .. pkt.name .. "!"
        send.to_client(log)
    end
end)

Step 2: Start GTProxy

When you start GTProxy, you should see:
[info] Welcome script loaded!

Step 3: Join a World

When you join any world, you’ll see a welcome message in the game!

Understanding the Script

Let’s break down what the script does:

1. Initialization Message

logger.info("Welcome script loaded!")
This runs when the script loads, confirming it’s active.

2. Server Connection Event

event.on("server:Connect", function(ctx)
    logger.info("Connected to game server")
end)
This event fires when GTProxy connects to the Growtopia server.

3. Player Spawn Event

event.on("OnSpawn", function(ctx)
    if ctx:has_packet() then
        local pkt = ctx:get_packet()
        
        local log = LogPacket.new()
        log.msg = "`2Welcome to the world, `` " .. pkt.name .. "!"
        send.to_client(log)
    end
end)
This event fires when a player spawns. We:
  1. Check if the context has a packet
  2. Get the packet data
  3. Create a new LogPacket with a welcome message
  4. Send it to the client
The backtick syntax (`2, “) is Growtopia’s color code system:
  • `2 = green text
  • “ = white text

Adding a Custom Command

Let’s add a /hello command:
command.register("hello", "Say hello", function(ctx)
    local player = world:get_local_player()
    if player then
        ctx:reply("`2Hello, `` " .. player.name .. "!")
    else
        ctx:reply("`4Error: ``Not in a world")
    end
    return true
end)
Now you can type /hello in-game and receive a personalized greeting!

Common Patterns

Pattern 1: Packet Interception

Intercept and modify packets:
event.on("server:SendToServer", function(ctx)
    local pkt = ctx:parse()
    
    -- Modify the packet
    if pkt.net_id then
        pkt.net_id = 999
    end
    
    -- Cancel the original and send modified version
    ctx:cancel()
    send.to_server(pkt)
end)

Pattern 2: Scheduled Tasks

Run code periodically:
scheduler.schedule_periodic(5000, function()
    local player = world:get_local_player()
    if player then
        logger.info("Position: ({}, {})", player.position.x, player.position.y)
    end
    return true  -- Continue running
end)

Pattern 3: Item Database Lookup

Look up item information:
command.register("item", "Get item info", function(ctx)
    if #ctx.args < 1 then
        ctx:reply("Usage: /item <id>")
        return false
    end
    
    local item_id = tonumber(ctx.args[1])
    local item = item_database:get_item(item_id)
    
    if item then
        ctx:reply("Item {}: {}", item.item_id, item.item_name)
    else
        ctx:reply("Item not found")
    end
    
    return true
end)

Best Practices

if ctx:has_packet() then
    local pkt = ctx:get_packet()
    -- Safe to use pkt
end
-- Good
local local_player = world:get_local_player()
local player_position = local_player.position

-- Bad
local p = world:get_local_player()
local pos = p.position
local task_id = scheduler.schedule_periodic(1000, function()
    -- Do work
    
    -- Stop when condition is met
    if should_stop then
        return false
    end
    
    return true
end)
-- Good
logger.info("Player {} at ({}, {})", player.name, pos.x, pos.y)

-- Less readable
logger.info("Player " .. player.name .. " at (" .. pos.x .. ", " .. pos.y .. ")")

Next Steps

Logger API

Learn about logging functions

Events API

Handle packet and connection events

Commands API

Register custom commands

Examples

Explore real-world scripts

Build docs developers (and LLMs) love