Lua Cheat Sheet

A bunch of useful commands you can use as a reference.

Each command is prepended by /lua so you can quickly copy the command and invoke it in the in-game chat while playing.

-- Useful commands:

-- Moderator Guide

-- If the server is broken and you can't join to restart the server,
-- connect to the server like this: https://lurkers.io/?command=restartserver
-- Requires mod privileges. Supports any command.

-- Moderator tools to kick / ban / mute players.
--
--`SHIFT+RMB` on a player = open context menu
--`RMB` on a player in scoreboard = open context menu

-- Kick someone
/kick Player123

-- Ban someone for 2 hours
/ban Player123 2

-- Reloads bans from the filesystem
/updatebans

-- Unban player by nickname
/unban Player123

-- Kill a player
/kill Player123

-- Mute a player (shadowmute)
/mute Player123
/unmute Player123

-- Add / remove player roles
-- * `dev` - has all permissions
-- * `mod` - has moderator permissions
-- * `sup` - has basic moderation permissions
/addrole {player} {role}
/removerole {player} {role}

-- Suicide
/suicide

-- give 20 saplings to plant when we run out of wood on the map
/give birchsapling 20

-- Restart server (ONLY USE IF SERVER IS BROKEN / FROZEN!!)
/restartserver

-- Schedule server restart
/schedulerestart 60 "Restarting in 60 seconds"

-- Set server to shut down automatically when it becomes empty and hide from server list
/set io.lurkers.game.Constants autoRestartWhenEmpty true
/set io.lurkers.server.GameServerHeadless isPrivate true
--- alternatively, restart the server when match ends
/lua function nextMap() Game:runCommand("schedulerestart 10 \"Scheduled update.\"") end

-- Change variables and sync it with clients
/set io.lurkers.game.Constants gameSpeedMultiplier 0.5 true
/set io.lurkers.game.Constants lightingEnabled true true
/set io.lurkers.game.Constants maxZoomLevelPlaying 4 true
/set io.lurkers.server.Server maxPeers 48 false

-- Lua commands

-- Disable voting
/lua Game:updateConfigs({
votingEnabled = "false",
})

-- Disable npc auto spawning
/lua Game:updateConfigs({autoSpawningEnabled = "false"})

-- Log your position
/lua Game:addMessage(LuaEntity:getPlayer():getPosition())

-- Teleport your player to another random player
/lua LuaEntity:getPlayer():setPosition(Peer:getRandomPeer():getPlayer():getPosition())

-- Teleport your player to an entity by ID
/lua LuaEntity:getPlayer():setPosition(LuaEntity:getEntityById(1752174493):getPosition())

-- Spawn zombie at your position
/lua LuaEntity:spawnPhysicalEntity("Zombie", LuaEntity:getPlayer():getPosition())

-- Spawn human with base AI at your position
/lua
 human = LuaEntity:spawnPhysicalEntity("Human", LuaEntity:getPlayer():getPosition())
 LuaEntity:setBaseAI(human)

-- Various AI movement commands
/lua human.inputController:move(Keys.A) -- move left
/lua human.inputController:move(Keys.D) -- move right
/lua human.inputController:move(Keys.W) -- move up
/lua human.inputController:move(Keys.S) -- move down
/lua human.inputController:moveTowards(LuaEntity:getPlayer())
/lua human.inputController:moveAwayFrom(LuaEntity:getPlayer())
/lua human.inputController:moveTowardsPosition(Vector2:new())
/lua human.inputController:moveAwayFromPosition(Vector2:new())
/lua human.inputController:stop()

-- Spawn a vehicle at your position (and configure physics first)
/set io.lurkers.game.Constants tickDuration 16 true
/set io.lurkers.game.Constants timeStep 0.016 true
/set io.lurkers.game.Constants velocityIterations 16 true
/set io.lurkers.game.Constants positionIterations 19 true
/lua LuaEntity:spawnPhysicalEntity("Vehicle", LuaEntity:getPlayer():getPosition():add(0, 4))

-- Spawn marker at your position
/lua LuaEntity:spawnPhysicalEntity("Marker", LuaEntity:getPlayer():getPosition())

-- Spawn 100 zombies at your position
/lua for i = 1, 100 do LuaEntity:spawnPhysicalEntity("Zombie", LuaEntity:getPlayer():getPosition()) end

-- Spawn 20 entities, 5 per second at your position
/lua plr=LuaEntity:getPlayer(); for i = 1, 20 do
    Timer:startTimer(function() LuaEntity:spawnPhysicalEntity("Human", plr:getPosition())  end, i/5.0)
end

-- Spawn an armed NPC army with zombie AI
/lua
    local plr = LuaEntity:getPlayer()
    Teams:create("Raiders");
    Timer:startTimer(function()
        local spawnPosition = Vector2:new()
        spawnPosition:set(plr:getPosition())
        spawnPosition.x = spawnPosition.x + 20 + math.random(40)
        spawnPosition.y = Level:getAutogeneratorSurface(spawnPosition.x, 3).y
        local inventories = {
            { { type = "StoneAxe", quantity = 1 } },
            { { type = "Shotgun", quantity = 9999 } },
            { { type = "MachineGun", quantity = 9999 } },
            { { type = "Rifle", quantity = 9999 } }
        }
        local inventory = inventories[math.random(#inventories)]
        local living = LuaEntity:prepareNewPhysicalEntity("Human", spawnPosition, inventory)
        local names = {"John", "Jane", "Mike", "Sarah", "Alex", "Emily", "Tom", "Lisa", "Chris", "Anna"}
        living:setNickname(names[math.random(#names)])
        living:setTeam(Teams:get("Raiders"))
        living:randomiseTextureIndex(10)
        LuaEntity:setZombieAI(living)
        living:register()
    end, 1, 1, 10)

-- Spawn a humanoid trader
/lua
    local plr = LuaEntity:getPlayer()
    local spawnPosition = Vector2:new()
    spawnPosition:set(plr:getPosition())
    local inventory = {
        { type = "Wheel", quantity = 1 },
        { type = "Vehicle", quantity = 1 },
    }
    local living = LuaEntity:prepareNewPhysicalEntity("Trader", spawnPosition, inventory)
    local names = {"Croy"}
    --[[local names = {"Croy", "John", "Jane", "Mike", "Sarah", "Alex", "Emily", "Tom", "Lisa", "Chris", "Anna"}]]
    living:setNickname(names[math.random(#names)] .. " The Mechanic")
    --[[living:setNickname(names[math.random(#names)] .. " The Trader")]]
    living:setHealth(400)
    living:setTextureIndex(35)
    LuaEntity:setBaseAI(living)
    living:register()
    local timer = Timer:startTimer(function()
        if math.random(0, 1) == 1 then return end
        local chatPrompts = {
            "Only the finest wares!",
            "Guaranteed return policy if you are not satisfied!",
            "My vehicles have a 100% flawless track record!",
        }
        living:showEmojiChat(chatPrompts[math.random(#chatPrompts)])
    end, 4, 90, -2, "traderChat")
    LuaEntity:addDisposeListener(living, function()
        timer:cancel()
    end)


-- Spawn 20 zombies with AI on Zombies team
/lua Teams:create("Zombies"); plr=LuaEntity:getPlayer(); for i = 1, 20 do
    Timer:startTimer(function()
        zombie = LuaEntity:spawnPhysicalEntity("Zombie", plr:getPosition())
        zombie:setTeam(Teams:get("Zombies"))
        LuaEntity:setZombieAI(zombie)
    end, i/5.0)
end

-- Spawn 5 fast zombies with AI on your team
/lua plr=LuaEntity:getPlayer(); for i = 1, 5 do
    Timer:startTimer(function()
        zombie = LuaEntity:spawnPhysicalEntity("FastZombie", plr:getPosition())
        zombie:setTeam(plr:getTeam())
        LuaEntity:setZombieAI(zombie)
    end, i/5.0)
end

-- Give everyone bazookas! >:D
/lua
    Game:addAnnouncement("[#00ff00ff]Free bazookas!", false)
    peers = Peer:getPeers()
    for i=0,peers.size-1 do
        living = peers:get(i):getLiving()
        if living ~= nil then
            luaEntity = LuaEntity:getEntityById(living:getId())
            luaEntity:giveItem("Bazooka", 1)
            luaEntity:giveItem("Rocket", 20)
        end
    end

-- Event: Spawn 4 iron blocks at center of bedwars map every 60 seconds!
/lua
    Timer:startTimer(function()
        Game:addAnnouncement("[#ee55aaff]Free resources in center!", false)
        Level:setBlocks("IronBlock", 15, 14, 1, 1)
    end, 60, 60, 10)

-- Override start inventory
/lua
    function getHumanStartInventory()
        local inventory = {
            {
                type = "Shotgun",
                quantity = 6
            },
            {
                type = "ShotgunAmmo",
                quantity = 30
            }
        }
        return inventory
    end

-- Give everyone zombies
/lua
    peers = Peer:getPeers()
    for i=0,peers.size-1 do
        living = peers:get(i):getLiving()
        luaEntity = LuaEntity:getEntityById(living:getId())
        zombie = LuaEntity:spawnPhysicalEntity("Zombie", luaEntity:getPosition())
        zombie:setTeam(luaEntity:getTeam())
        LuaEntity:setZombieAI(zombie)
    end

-- Spawn zombie at 0, 0
/lua LuaEntity:spawnPhysicalEntity("Zombie", Vector2:new())

-- Spawn 10 zombies with AI
/lua for i = 1, 10 do local zombie = LuaEntity:spawnPhysicalEntity('Zombie', LuaEntity:getPlayer():getPosition());  LuaEntity:setZombieAI(zombie) end

-- spawn arrow volley!
/lua
    local spawn = Vector2:new()
    spawn.x = -20
    spawn.y = -186
    for i = 1, 20 do
        spawn.x = spawn.x + 2
        spawn.y = spawn.y + 3
        local entity = LuaEntity:prepareNewPhysicalEntity(
            "Arrow",
            spawn,
            { { type = "Coin", quantity = 1 } }
        )
        entity.speed = 20 + math.random(20)
        entity.angle = 250 + math.random(30)
        entity:register()
    end

-- spawn grenade at your position every 5 seconds
/lua
    local spawn = Vector2:new()
    spawn.x = LuaEntity:getPlayer():getPosition().x
    spawn.y = LuaEntity:getPlayer():getPosition().y
    Timer:startTimer(function()
        local entity = LuaEntity:prepareNewPhysicalEntity(
            "Grenade",
            spawn
        )
        entity.speed = 0
        entity.angle = 180
        entity:register()
    end, 1, 5, 9999999)

-- spawn grenade at your position
/lua
    local spawn = Vector2:new()
    spawn.x = LuaEntity:getPlayer():getPosition().x
    spawn.y = LuaEntity:getPlayer():getPosition().y
    local entity = LuaEntity:prepareNewPhysicalEntity(
        "Grenade",
        spawn
    )
    entity.speed = 0
    entity.angle = 180
    entity:register()

-- Spawn bergobrine?
/lua
    local living = LuaEntity:prepareNewPhysicalEntity(
        "Bergobrine",
        LuaEntity:getPlayer():getPosition(),
        { { type = "ObsidianAxe", quantity = 1 }, { type = "Awaystone", quantity = 1 } }
    )
    living:setTextureIndex(32)
    LuaEntity:setAI(living, "BergobrineAI")
    living:register()

-- Spawn a sheep with AI
/lua for i = 1, 1 do local entity = LuaEntity:spawnPhysicalEntity('Sheep', LuaEntity:getPlayer():getPosition());  LuaEntity:setSheepAI(entity) end
-- Spawn a group of animals
/lua for i = 1, 1 do
        Teams:create("Gaia")
        local spawnAnimal = function(type)
            local pos = Vector2:new()
            pos.x = LuaEntity:getPlayer():getPosition().x - 20 + math.random(40)
            pos.y = LuaEntity:getPlayer():getPosition().y + 10
            local entity = LuaEntity:spawnPhysicalEntity(type, pos);
            LuaEntity:setAI(entity, "AnimalAI")
            entity:setTeam(Teams:get("Gaia"))
        end
        spawnAnimal("Boar")
        spawnAnimal("Wolf")
        spawnAnimal("Fox")
        spawnAnimal("Deer")
    end


/lua for i = 1, 1 do
        local spawnAnimal = function(type)
            local pos = Vector2:new()
            pos.x = LuaEntity:getPlayer():getPosition().x - 20 + math.random(40)
            pos.y = LuaEntity:getPlayer():getPosition().y + 10
            local entity = LuaEntity:spawnPhysicalEntity(type, pos);
            LuaEntity:setAI(entity, "AnimalAI")
        end
        spawnAnimal("Boar")
        spawnAnimal("Wolf")
        spawnAnimal("Fox")
    end

-- Spawn a fish with AI
/lua for i = 1, 1 do local entity = LuaEntity:spawnPhysicalEntity('Fish', LuaEntity:getPlayer():getPosition());  LuaEntity:setAI(entity, "FishAI") end

-- Save the level
/lua Level:save()

-- Kill your player
/lua LuaEntity:die(LuaEntity:getPlayer())

-- Kill entity by ID
/lua LuaEntity:die(LuaEntity:getEntityById(699548541))

-- Give coins to your player
/lua LuaEntity:getPlayer():giveItem("Coin", 1000)

-- Give 100 birch sapling to your player (convenience command)
/give BirchSapling

-- Give ores and wood to your player
/lua LuaEntity:getPlayer():giveItem("CoalBlock", 1000); LuaEntity:getPlayer():giveItem("IronBlock", 1000);  LuaEntity:getPlayer():giveItem("GoldBlock", 1000);  LuaEntity:getPlayer():giveItem("MithrilBlock", 1000); LuaEntity:getPlayer():giveItem("WoodBlock", 1000);

-- Create and join team
Teams:create("Elite")
LuaEntity:getPlayer():getPeer():setTeam(Teams:get("Elite"))

-- Spawn moving platform
/lua local player = LuaEntity:getPlayer()
    local position = player:getPosition()
    local x = position.x
    local y = position.y - 2
    local xOffset = -1
    for i = 1, 20 do
        Timer:startTimer(function()
            x = x + xOffset
            Level:setBlocks("DirtBlock", x, y, 3, 0)
            Level:setBlocks("AirBlock", x + 3, y, 2, 0)
        end, i/2.0)
    end

-- remove block at your position
/lua local player = LuaEntity:getPlayer()
    local position = player:getPosition()
    local x = math.floor(position.x)
    local y = math.floor(position.y)
    Level:setBlocks("AirBlock", x, y, 0, 0)

-- Spawn bedwars bridge
/lua
    local x = 17
    local y = 10
    local width = 60
    local height = 4
    Level:setBlocks("BrickBackgroundBlock", x - (width/2), y, width, height)
    Level:setBlocks("SteelBlock", x - (width/2), y, width, 0)
    Level:setBlocks("SteelBlock", x - (width/2), y+height, width, 0)

-- Restart map with timer
/lua Timer:startCounterTimer(function() Game:addMessage("Restarting map, hold on..."); Timer:cancelAllTimers(); Level:restart();  end, 10, 0, 0, "Changing map in")

-- Restart the level
/lua Level:restart()

-- Spawn a LLM AI bot that interfaces with a LM Studio inference server
/lua local aiBot = require("scripts/modules/ai_bot"); aiBot.spawn();
/lua local aiBot = require("scripts/modules/ai_bot"); aiBot.url="http://localhost:1234/v1/chat/completions"; aiBot.instructions="Respond like you're a programmer"; aiBot.spawn();
ngrok http 1234
/lua local aiBot = require("scripts/modules/ai_bot"); aiBot.url="http://e76d-84-208-127-40.ngrok-free.app/v1/chat/completions";
/lua local aiBot = require("scripts/modules/ai_bot"); aiBot.instructions = "Enter instructions here"

-- Change gamemode
/lua changeScript("bedwars", "maps/bedwars")
/lua changeScript("bedwars_map_rotation", "maps/bedwars")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaBrickCity")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaDeadPlanet")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaDuelPyramid")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaFallenStar")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaGoldArena")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaGoldenHeart")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaRatRace")
/lua changeScript("bedwars_map_rotation", "maps/Circle2")
/lua changeScript("bedwars_map_rotation", "maps/abandoned_city_bobbius-Aincrad")
/lua changeScript("bedwars_map_rotation", "maps/AstroidField_sniiper-Aincrad")
/lua changeScript("bedwars_map_rotation", "maps/Dogcat_sniiper-Aincrad")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaForgottenWorld_parasite-Aincrad")
/lua changeScript("bedwars_map_rotation", "maps/ravine_sniiper-Aincrad")
/lua changeScript("bedwars_map_rotation", "maps/BedwarsParaMagmaVolcano_parasite-Aincrad")
/lua nextMap()
/lua changeScript("zombie_survival", "maps/zombie_survival")
/lua changeScript("zombie_survival_new", "maps/zombie_survival")
/lua changeScript("sandbox", "maps/sandbox")
/lua changeScript("survival", "maps/survival")
/lua changeScript("survival_persistent", "maps/survival_persistent")
/lua changeScript("team_deathmatch", "maps/team_deathmatch")
/lua changeScript("capture_the_flag", "maps/capture_the_flag")
/lua changeScript("battle_royale", "maps/battle_royale")

/lua changeScript("deathmatch", "maps/deathmatch")
/lua changeScript("zombie_survival_player_only", "maps/zombie_survival")

-- Set the time to night time
/lua Level:getDayNightCycle():setHour(21)

-- Set the day night cycle time progression
/lua Level:getDayNightCycle():setTimeProgressionMultiplier(0)

-- Kick a player
/kick Player

-- Remove all blocks by type
/lua Level:removeAllBlocksByType("StoneBlock")

-- Save the map to a PNG image server-side (requires DEV role)
/savemapscreenshot              -- no lighting, current chunks only
/savemapscreenshot true         -- render lighting, current chunks only
/savemapscreenshot false true   -- no lighting, load all chunks
/savemapscreenshot true true    -- render lighting, load all chunks
/savemapscreenshot true true -1024 -512 1024 256    -- render lighting, load all chunks in AABB

-- Convert an image from a URL (or local file) to blocks
/imagetoblocks "https://media.discordapp.net/attachments/1061179499955355709/1151742565394153472/pixil-frame-0_27_fix.png?ex=6555a059&is=65432b59&hm=ee432ff4efad4a2a5b9f148016cc7519657e1ca565c1395fc03f6611917e3043&=&width=172&height=172" 0 30

-- Fill chat with random messages
/lua fill_chat = dofile("scripts/utils/fill_chat.lua")

-- Get out of JS script gamemode (lua commands won't work)
/js Level.change("maps/abandoned_city_bobbius-Aincrad", "bedwars_map_rotation.lua")

Modding

Modding support is currently limited. You can override the internal game assets (images, sounds, json, scripts etc) from the desktop jar by copying them to the same folder where the jar is located. The game will check files in the local filesystem before loading internal files.

Note: The directory paths must still match the ones from the internal file system.

Note: Only works in dev mode.

If there is enough demand, I may make it possible for servers to sync assets with clients during runtime.