Skip to content

Core Functions

This module provides essential functions that nearly all scripts require: callbacks for executing code, utilities for logging, time management, game information access, and settings manipulation.

Callbacks 🔄

Callbacks are the primary mechanism for executing your script logic. Define these functions in your script and the core will automatically invoke them at the appropriate times.

on_tick()

Executes every game tick (approximately every 30ms). This is where most game logic belongs.

on_map_load()

Triggers when a new map loads. Called before on_tick for the new map.

on_login_tick()

Executes during the login screen, before entering the game world. Useful for automating login and character selection.

on_packet_recv(packet: in_packet) -> boolean

Intercepts incoming packets from the server. Return true to allow or false to block. Requires plugin structure. See Packet Handlers.

on_packet_send(packet: in_packet) -> boolean

Intercepts outgoing packets to the server. The packet is provided as an in_packet for read-only decoding (same as on_packet_recv). Return true to allow or false to block. Requires plugin structure. See Packet Handlers.

on_evasion(player_names: table)

Called once when evasion is first triggered by a non-whitelisted player appearing on the map. player_names is an array of strings containing the names of detected players. This fires before the evasion action (channel change, logout, etc.) begins.

lua
function on_evasion(player_names)
    for _, name in ipairs(player_names) do
        core.log_warning("Evading from: " .. name)
    end
end

on_wndproc(event: table) -> nil | boolean | number

Called for keyboard and mouse WndProc messages received by the game window. Non-input WndProc messages are not passed to Lua.

WM_MOUSEMOVE not delivered

Mouse-move messages (WM_MOUSEMOVE) fire hundreds of times per second while the cursor is over the window and are not dispatched to Lua. If you need cursor position, poll core.input.get_mouse_position() instead. All other mouse messages (clicks, wheel, X buttons) and all keyboard messages are delivered normally.

Return false to block the input message with result 0, return a number to block with that LRESULT, or return nil / true to allow the original WndProc.

If multiple scripts define on_wndproc, the first script to return false or a number blocks the message and later scripts do not receive that event.

event fields:

FieldTypeDescription
hwndnumberWindow handle as an integer
msgnumberWindows keyboard/mouse message ID
w_paramnumberRaw WPARAM value
l_paramnumberRaw LPARAM value
blockablebooleanAlways true for delivered events
xnumberMouse X coordinate from l_param for mouse messages
ynumberMouse Y coordinate from l_param for mouse messages
lua
function on_wndproc(event)
    if event.x and event.y then
        core.log("mouse: " .. event.x .. ", " .. event.y)
    end

    -- Example: block a specific input message if needed
    -- if event.msg == 0x0201 then return false end
end

on_dialog(dialog: table) -> nil | boolean | number | string

Intercepts NPC dialogs and blue boxes before core auto-handling (auto NPC / auto blue boxes). Called once per dialog — the result is cached until the dialog closes.

dialog fields:

FieldTypeDescription
kindstring"npc" for NPC dialogs, "bluebox" for blue box notifications
typenumberDialog sub-type (see table below)
textstringThe dialog message text (NPC message or blue box text)
choicestableArray of {text, index} — present when the dialog has a CT_LIST (list options). index is the game's internal selection value for each choice

type values:

KindTypeMeaning
npc0Close / prev
npc1Next / ok
npc5Text input
npc6List select (has choices)
bluebox1000Yes / no prompt
blueboxotherNotice

Return values:

ReturnEffect
nil or truePass to core — auto NPC / auto blue boxes handles it if enabled
falseBlock — do nothing, leave dialog open
6Click yes / ok / next
7Click no / close
numberSelect the choice matching this index value (requires choices)
string (type 5)Submit as text input
string (with choices)Select the first choice whose text contains this substring

TIP

For list selection, prefer returning choice.index (number) for an exact match, or a substring (string) for flexible text matching. Since 6 and 7 are reserved for yes/no, use the string method if a choice happens to have index 6 or 7.

lua
function on_dialog(dialog)
    -- Log all dialog text
    core.log("[" .. dialog.kind .. "] " .. (dialog.text or ""))

    if dialog.kind == "npc" then
        -- Type 6 (list): select by index or text
        if dialog.type == 6 and dialog.choices then
            return dialog.choices[1].index  -- select by index
            -- return "Complete"            -- or select by text substring
        end

        -- Type 5 (text input): return the string to enter
        if dialog.type == 5 then
            return "answer"  -- submits "answer" as text input
        end

        if dialog.type == 1 then
            return 6  -- click next
        end
    end

    -- return nil = let core handle it
end

WARNING

The callback fires once per dialog pointer. The result is cached — returning false will block the dialog for its entire lifetime, not just one tick. Returning nil lets core auto-handling run every tick as normal.

INFO

Callback names must match exactly as shown above. The core registers functions by name.

lua
function on_tick()
    -- Your game logic here
end

function on_map_load()
    -- Map initialization code here
end

Game Information

core.get_world_id() -> number | nil

Returns the current world ID (e.g., Kronos).


core.get_channel_id() -> number | nil

Returns the current channel ID.


core.change_channel(channel_id: number) -> boolean

Switches to the specified channel. Must be out of combat.

Returns: true if the channel change was issued, false if the call was rejected.

Throttled

Excessive channel changes in a short period are blocked and will return false without issuing a change. Always check the return value instead of assuming the swap happened.


core.is_evading() -> boolean

Returns true if currently evading.


core.is_solving_rune() -> boolean

Returns true if currently solving a rune.


core.is_in_cutscene() -> boolean | nil

Returns true if currently in a cutscene.


core.get_update_time() -> number

Returns the current game update time in milliseconds. Useful for timing operations.


core.get_system_time() -> table

Returns the current system (wall clock) time as a table.

FieldTypeDescription
yearnumberFull year (e.g. 2026)
monthnumberMonth (1-12)
daynumberDay of month (1-31)
hournumberHour (0-23)
minnumberMinute (0-59)
secnumberSecond (0-59)
msnumberMillisecond (0-999)
epochnumberMilliseconds since Unix epoch
lua
local t = core.get_system_time()
core.log(string.format("%04d-%02d-%02d %02d:%02d:%02d",
    t.year, t.month, t.day, t.hour, t.min, t.sec))

core.is_rushing() -> boolean

Returns true if currently rushing to a map (via the rusher module).


core.is_auto_selling() -> boolean

Returns true while the auto-sell flow is active — covers the full state machine (rushing to the shop map, walking, talking to the NPC, waiting for the shop dialog, and selling). Returns false when idle.

Useful for gating script logic that shouldn't run while the player is being driven to a shop and back.

lua
function on_tick()
    if core.is_auto_selling() then
        return -- let auto-sell finish before doing anything else
    end
    -- ... your logic
end

core.use_hyper_rock(map_id: number) -> boolean

Teleports to the specified map using the Hyper Teleport Rock. Returns true on success, false if context is unavailable.

Settings API ⚙️

The Settings API provides runtime access to game settings. Changes are automatically synced to the web UI and persist across sessions.

Finding Setting Paths

Developer Mode (Recommended)

  1. Open Settings in web menu
  2. Press Ctrl+Shift+D to enable Developer Mode
  3. Right-click any setting to copy its path

Path Format: category.subcategory.property

Examples: autos.auto_pot.hp.enabled, hacks.godmode, combat.kami.enabled


core.get_setting(path: string) -> value | nil

Retrieves a setting value by path.

Returns: Setting value (boolean, number, string, or table) or nil if not found. Array/object settings (like skill injection lists) are returned as Lua tables.

lua
local auto_hp = core.get_setting("autos.auto_pot.hp.enabled")
local threshold = core.get_setting("autos.auto_pot.hp.value")

-- Array settings return as Lua tables
local skills = core.get_setting("combat.skill_injection.skills")
if skills then
    for i, skill in ipairs(skills) do
        core.log("Skill ID: " .. tostring(skill.id) .. " Delay: " .. tostring(skill.delay))
    end
end

core.set_setting(path: string, value: boolean | number | string | table) -> boolean

Updates a setting value. Changes sync automatically to the web UI. Lua tables are converted to JSON arrays/objects for array settings.

Returns: true on success, false on failure.

Type Matching Required

The value type must match the setting's expected type or a Lua error will be thrown.

lua
-- ❌ Error: expects boolean, got number
core.set_setting("autos.auto_pot.hp.enabled", 123)

-- ✅ Correct
core.set_setting("autos.auto_pot.hp.enabled", true)
core.set_setting("autos.auto_pot.hp.value", 75)

-- ✅ Setting array values with tables
core.set_setting("combat.skill_injection.skills", {
    { id = 2321006, delay = 200, hits = 1, type = 0 },
    { id = 2321007, delay = 150, hits = 2, type = 1 }
})

Common Setting Paths

TIP

For the complete list of all 75 settings with types, defaults, and descriptions, see the Settings Reference.

Finding Paths

Enable Developer Mode in Settings (Ctrl+Shift+D) and click any setting badge to copy its exact path.

Setting PathTypeDescription
Autos
autos.auto_pot.hp.enabledbooleanEnable auto HP potion
autos.auto_pot.hp.valuenumberHP threshold (0-100)
autos.auto_pot.hp.keybindstringHP potion keybind
autos.auto_pot.mp.enabledbooleanEnable auto MP potion
autos.auto_pot.mp.valuenumberMP threshold (0-100)
autos.auto_pot.mp.keybindstringMP potion keybind
autos.auto_login.enabledbooleanEnable auto login
autos.auto_login.world_idnumberWorld dropdown index (see table below)
autos.auto_login.channelnumberChannel dropdown index (0 = random, 1-40 = specific)
autos.auto_login.char_indexnumberCharacter slot index
autos.evasion.typenumberEvasion type dropdown (0=Next Map CC, 1=Disable, 2=Logout, 3=Terminate)
autos.evasion.whitelisted_ignstableWhitelisted IGNs (string array)
Hacks
hacks.godmodebooleanGodmode toggle
hacks.bossing_godmodebooleanBossing godmode toggle
hacks.pet_lootbooleanPet loot toggle
hacks.speedy_fmabooleanSpeedy FMA toggle
Combat
combat.kami.enabledbooleanKami (teleport hack) toggle
combat.kami.typenumberKami type dropdown (0=Closest, 1=Random, 2=Random Speedy)
combat.kami.kami_expbooleanKami EXP toggle
combat.kami.kami_lootbooleanKami loot toggle
combat.kami.x_offsetnumberKami X offset
combat.kami.y_offsetnumberKami Y offset
combat.skill_injection.enabledbooleanEnable skill injection
combat.skill_injection.safe_modebooleanSafe mode toggle
combat.skill_injection.skillstableSkill list (see Array Settings below)
Items
items.filter_enabledbooleanEnable item filter
items.filter_modenumberFilter mode dropdown (0=blacklist, 1=whitelist)
items.filtered_itemstableFiltered item IDs (int array)
items.meso_filter_enabledbooleanEnable meso filter
items.min_meso_amountnumberMinimum meso amount
Map
map.rush_by_leveltableLevel-based rush targets (see Array Settings below)
map.spawn_pointstableCustom spawn points (see Array Settings below)
Packets
packets.streaming_enabledbooleanEnable packet streaming
packets.blocked_incoming_opcodestableBlocked incoming opcodes (int array)
packets.blocked_outgoing_opcodestableBlocked outgoing opcodes (int array)
packets.ignored_incoming_opcodestableIgnored incoming opcodes (int array)
packets.ignored_outgoing_opcodestableIgnored outgoing opcodes (int array)
Macros
macros.listtableMacro list (see Array Settings below)

Dropdown settings store a 0-based index, not the display string. Use the index values listed above.

World Selection (Auto Login)

The autos.auto_login.world_id dropdown uses these indices:

IndexWorld NameNotes
0ScaniaNA - Default world
1BeraNA
2KronosNA - Reboot (40 channels)
3HyperionNA
4NA CW HeroicNA - Classic Worlds (10 channels)
5NA CW InteractiveNA - Classic Worlds (10 channels)
6LunaEU
7SolisEU
8EU CW HeroicEU - Classic Worlds (10 channels)
9EU CW InteractiveEU - Classic Worlds (10 channels)

Example:

lua
-- Set auto login to Kronos, Channel 5, Character slot 2
core.set_setting("autos.auto_login.world_id", 2)    -- Kronos (index 2)
core.set_setting("autos.auto_login.channel", 5)      -- Channel 5 (index 5)
core.set_setting("autos.auto_login.char_index", 2)   -- 3rd character

Array Settings

Array settings are accessed as Lua tables. Use get_setting to read and set_setting to write.

Skill Injection Skills

lua
-- Each skill: { id = number, delay = number, hits = number, type = number }
-- type: 0=Generic, 1=Melee, 2=Magic, 3=Shoot, 4=Use Skill, 5=Safe Mode
local skills = core.get_setting("combat.skill_injection.skills")
core.set_setting("combat.skill_injection.skills", {
    { id = 2321006, delay = 200, hits = 1, type = 0 },
    { id = 2321007, delay = 150, hits = 2, type = 1 }
})

Rush By Level

lua
-- Each entry: { min_level = number, max_level = number, map_id = number }
local rush_list = core.get_setting("map.rush_by_level")
core.set_setting("map.rush_by_level", {
    { min_level = 10, max_level = 30, map_id = 100000000 },
    { min_level = 31, max_level = 60, map_id = 101000000 }
})

Spawn Points

lua
-- Each entry: { map_id = number, x = number, y = number, label = string }
core.set_setting("map.spawn_points", {
    { map_id = 100000000, x = -50, y = 200, label = "Henesys Center" }
})

Macros

lua
-- Each entry: { name = string, key = string, delay = number, enabled = boolean }
core.set_setting("macros.list", {
    { name = "Buff", key = "F1", delay = 1000, enabled = true }
})

Simple Arrays

lua
-- Integer arrays (filtered items, blocked opcodes, etc.)
core.set_setting("items.filtered_items", { 2000000, 2000001, 2000003 })
core.set_setting("packets.blocked_incoming_opcodes", { 0x1234, 0x5678 })

-- String arrays (whitelisted IGNs)
core.set_setting("autos.evasion.whitelisted_igns", { "FriendName1", "FriendName2" })

Custom Settings Creation 🧩

See the Menu module for the core.menu API that lets scripts create their own settings (checkboxes, sliders, dropdowns, keybinds, text inputs) in the web UI.

Logging

core.log(message: string)

Prints a white message with prefix [-].

core.log_error(message: string)

Prints a red message with prefix [!].

core.log_warning(message: string)

Prints a yellow message with prefix [?].

INFO

Use Lua's tostring() function to convert numbers and booleans to strings for logging.