Modules
On this page
The require() function lets you import shared utility scripts into your plugins. This keeps common code in one place instead of duplicating it across scripts.
How It Works
Modules live under libs/ in your Lua tree (manage them in the web menu's Lua file manager). Any script can load them with require():
local utils = require("utils")require("utils")loads the module atlibs/utils.luain your tree- Whatever the module
returns becomes the value ofrequire() - Results are cached — calling
require("utils")again returns the same table without re-executing the file
Module Structure
A module is just a .lua file that returns a table of functions/values:
-- libs/utils.lua
local M = {}
function M.distance(pos1, pos2)
local dx = pos1.x - pos2.x
local dy = pos1.y - pos2.y
return math.sqrt(dx * dx + dy * dy)
end
function M.find_closest_mob(player_pos, map)
local closest = nil
local closest_dist = math.huge
for _, mob in ipairs(map:get_mobs()) do
if mob and mob:is_valid() then
local mpos = mob:get_position()
if mpos then
local dist = M.distance(player_pos, mpos)
if dist < closest_dist then
closest_dist = dist
closest = mob
end
end
end
end
return closest, closest_dist
end
return MUsing Modules in Scripts
plugin = {
name = "Mob Hunter",
version = "1.0.0",
author = "You",
description = "Hunts the closest mob using shared utilities",
load = true
}
local utils = require("utils")
function on_tick()
local player = core.object_manager.get_local_player()
if not player or not player:is_valid() then return end
local map = core.object_manager.get_current_map()
if not map or not map:is_valid() then return end
local pos = player:get_position()
local mob, dist = utils.find_closest_mob(pos, map)
if mob and dist < 300 then
local mpos = mob:get_position()
core.input.teleport_safe(mpos.x, mpos.y)
core.input.use_skill(2001004)
end
endSubmodules
Use dots in the module name to organize into subdirectories:
local combat = require("combat.targeting")
-- Loads: libs/combat/targeting.luaFile Layout
Your Lua tree: top-level .lua files are scripts; shared modules live under libs/.
my_script.lua -- a script
another_script.lua -- a script
libs/ -- shared modules go here
├── utils.lua -- require("utils")
├── cooldowns.lua -- require("cooldowns")
└── combat/
└── targeting.lua -- require("combat.targeting")
Marketplace Libraries
The modules above are your own local files. You can also install public libraries from the marketplace and require() them with an @ prefix:
local combat = require("@acme.combat")See Marketplace Libraries for publishing your own library, the libs/<handle>/ layout, and the @ convention.
Rules
Module names can only contain letters, numbers, underscores, and dots. Names like ../secrets or my module will be rejected.
- Modules cannot use
io,os,dofile, orloadfile— the same sandbox rules apply - Modules run in the global environment, not a script's sandbox — so all scripts share the same cached module instance
- Modules are cached until any script is enabled or disabled — toggling a script clears the cache so the next
require()re-reads the latest version - Modules do not need a
plugintable — they are not scripts, just libraries require()calls can go at the top of your script (outside callbacks) since they only run once at load time
Examples
Cooldown Manager Module
-- libs/cooldowns.lua
local M = {}
local timers = {}
function M.ready(key, cooldown_ms)
local now = core.get_update_time()
if not timers[key] or now - timers[key] >= cooldown_ms then
timers[key] = now
return true
end
return false
end
function M.reset(key)
timers[key] = nil
end
return MUsage:
local cd = require("cooldowns")
function on_tick()
if cd.ready("attack", 1000) then
core.input.use_skill(2001004)
end
if cd.ready("potion", 5000) then
core.input.use_item(2000001)
end
endLogging Helpers Module
-- libs/log.lua
local M = {}
function M.info(fmt, ...)
core.log(string.format(fmt, ...))
end
function M.warn(fmt, ...)
core.log_warning(string.format(fmt, ...))
end
function M.err(fmt, ...)
core.log_error(string.format(fmt, ...))
end
return MUsage:
local log = require("log")
function on_tick()
local player = core.object_manager.get_local_player()
if not player or not player:is_valid() then return end
log.info("HP: %d/%d", player:get_health(), player:get_max_health())
end