Skip to content

World structure

Here you will learn how to work with the world structure.


Basic World Info

lua
world:getID() -- Unique world ID.
world:getWorldName() -- World name (string).
world:getName() -- Alias for world name (same as getWorldName in most cases).

world:getOwner() -- Returns owner object or nil if unowned.

Players in the World

lua
world:getPlayers() -- Returns an array of player objects currently in world.

world:getPlayersCount()
-- By default: number of VISIBLE players.
-- If you want to include invisible players too:
-- world:getPlayersCount(1)

world:getVisiblePlayersCount() -- Only visible players.

Example:

lua
for _, player in ipairs(world:getPlayers()) do
    player:onConsoleMessage("Hello from Lua!")
end

Movement & Position

lua
world:setPlayerPosition(player, x, y)
-- Teleports player to tile coordinates (x, y).

Drops & Items in World

lua
world:getDroppedItems() -- All dropped items in the world.
world:getTileDroppedItems(tile) -- Drops on a specific tile.
world:removeDroppedItem(dropUID) -- Remove a drop by UID.

Access & Ownership

lua
world:hasAccess(player) -- True if player can access the world (lock, perms, etc).
world:hasTileAccess(player, tile) -- True if player can edit/affect this tile.

world:setOwner(user_id) -- Set owner by account ID.
world:removeOwner() -- Remove owner (world becomes unowned).

world:getWorldLock() -- Returns the world lock tile or nil if world is not locked.

⚠️ setOwner / removeOwner ignore World Locks.
If a World Lock exists, it will auto-update its color (green/red) for the owner.


Gem Handling & Loot (Updated)

lua
world:onLoot(player, tile, gem_count)
-- Recommended for farmables:
--  - Automatically adjusts gem count based on buffs (ancestral, items, events).
--  - Handles seed drops and other default loot logic.
--  - Progresses quests that require breaking blocks / collecting gems.

local new_gems_count = world:adjustGems(player, tile, gem_count, show_effects)
-- Manually adjust gem rewards based on buffs/effects.
-- show_effects:
--  1 -> show visual effects (e.g. ancestral particles)
--  0 -> no visual effects

For farming, prefer world:onLoot(...) instead of world:spawnGems.

world:spawnGems(x, y, amount, player) still exists, but is considered low-level / legacy for farmables.


XP & Gem Events (Global)

These are global functions, but you’ll often use them from world-related scripts.

lua
setGemEvent(multiplier)
-- Starts/updates a global gem event.
-- If multiplier is 0 or 1, the event is stopped.

getGemEvent()
-- Returns current gem multiplier (e.g. 1, 2, 3, ...).

setXPEvent(multiplier)
-- Same concept but for XP.

getXPEvent()
-- Returns current XP multiplier.

Weather & World Type

lua
world:setWeather(weather_id)
-- Permanently changes the default weather in this world.

world:getWorldType()
-- Returns world type.
-- Different blasts/generation types have different values.
-- Worlds created via Lua can also use custom types.

XP & Killing Players

lua
world:addXP(player, amount) -- Give XP to a player (respects events, buffs, etc).
world:kill(player) -- Kill the player.

World Size & Tiles

lua
world:getWorldSizeX() -- Width in tiles.
world:getWorldSizeY() -- Height in tiles.

world:getTile(x, y) -- Returns tile object at tile coordinates (x, y).
world:getTiles() -- (Global helper in some scripts) get all tiles.
world:getTilesByActionType(actionType) -- Find tiles with specific action type.

(Tile methods themselves are documented in the Tile structure page.)


World Creation & Generation

Create a new world from scratch

lua
local w = World.new("TESTWORLD", 25, 25, 0)
-- name, sizeX, sizeY, worldType
-- worldType:
--   0   = normal world
--   255 = dungeon world
--   other values = custom types

Create a new world from a template file

lua
local w = World.newFromTemplate("TESTWORLD", "GROWMINES_1.dat")
-- name, template_file_name

Saving vs deleting worlds

lua
-- Make world accessible in-game:
w:save()

-- Only used temporarily and not saved:
w:delete() -- Removes from memory only, NOT from database.

Notes:

  • If a world with the same name already exists, w:save() will replace it.
  • Use worldExists(name) to check if a world already exists.
  • Not calling w:delete() on an unsaved world will leak memory until server restart.

Active Worlds

lua
local worlds = getActiveWorlds()
-- Returns a list/array of loaded worlds currently in memory.

You can loop them like:

lua
for _, w in ipairs(getActiveWorlds()) do
    print(w:getWorldName())
end

Redeem Codes

lua
world:redeemCode(player, "mycode")
-- Makes the player redeem a code, as if entered in the in-game dialog.

Internally this uses player:doAction(...).
You typically just call world:redeemCode(player, code).


NPC Helpers

lua
world:createNPC("Punch NPC", x, y)
world:findNPCByName("Punch NPC") -- Returns array of NPC objects.
world:removeNPC("Punch NPC")
world:setClothing(npc, item_id)

npc:getUserID() -- Unique ID per NPC.
npc:getNetID()  -- Network ID.
npc:getPosX()
npc:getPosY()

Example: NPC punch using raw packets

lua
local STATE_PACKET_FLAGS = {
    STANDING = bit.lshift(1, 5),
    PUNCHING = bit.lshift(1, 9)
}

local function send_npc_punch_effect(world, npc)
    local wr = BinaryWriter("")
    wr:WriteInt32(4) -- Game packet type
    wr:WriteUInt8(0) -- PACKET_STATE
    wr:WriteUInt8(0)
    wr:WriteUInt8(0)
    wr:WriteUInt8(0)
    wr:WriteInt32(npc:getNetID())
    wr:WriteInt32(0)
    wr:WriteInt32(bit.bor(STATE_PACKET_FLAGS.PUNCHING, STATE_PACKET_FLAGS.STANDING))
    wr:WriteFloat(0)
    wr:WriteInt32(0)
    wr:WriteFloat(npc:getPosX())
    wr:WriteFloat(npc:getPosY())
    wr:WriteFloat(0)
    wr:WriteFloat(0)
    wr:WriteFloat(0)
    wr:WriteUInt32(npc:getPosX() / 32 + 3)
    wr:WriteUInt32(npc:getPosY() / 32)
    wr:WriteUInt32(0)
    wr:WriteUInt8(0)

    for _, player in ipairs(world:getPlayers()) do
        player:sendRawPacket(wr:GetCurrentString())
    end
end

And using it in a command:

lua
onPlayerCommandCallback(function(world, player, fullCommand)
    if fullCommand == "spawnnpc" then
        world:createNPC("Punch NPC", player:getPosX(), player:getPosY())
        return true
    end

    if fullCommand == "tt" then
        local found = world:findNPCByName("Punch NPC")
        for _, npc in ipairs(found) do
            local tile = world:getTile(npc:getPosX() / 32 + 3, npc:getPosY() / 32)
            if tile ~= nil then
                send_npc_punch_effect(world, npc)
                world:punchTile(tile, npc) -- Pass npc/player for better performance
            end
        end
        return true
    end

    return false
end)

Chat, Effects & Game Helpers

lua
world:onCreateChatBubble(x, y, text, netid)
-- Creates a chat bubble at (x, y) with given text and speaker netID.

world:onCreateExplosion(x, y, radius, power)
-- Visual explosion and effect at tile coordinates.

world:isGameActive() -- True/false for world mini-game state (if applicable).
world:onGameWinHighestScore() -- Highest score or related game result, if supported.

world:sendPlayerMessage(player, "something")
-- Send world message to a player.
-- Can also be used to trigger player commands depending on content.

GTPS Cloud Documentation