Core Functions
Overviewโ
This module contains a collection of essential functions that you will probably need sooner or later in your scripts. This module includes utilities for logging, callbacks, time management, and accessing game information.
Callbacks - Brief Explanation
This is essentially the most important part of scripting, since most of your code must be ran inside a callback.What is a Callback?
A callback is a function that you write, which you then pass to the game engine or framework. The engine doesn't execute this function immediately. Instead, it "calls back" to your function at a specific time or when a particular event occurs in the game.
Think of it like leaving your phone number with a friend (the game engine) and asking them to call you (execute your function) when a certain event happens.
Why Use Callbacks?
Callbacks allow your game to respond to events without constantly checking for them. This makes your code more efficient and easier to manage. Instead of writing code that keeps asking, "Has the player pressed a button yet? Has an enemy appeared yet?" you can simply tell the game engine, "When this happens, run this function." So, all games use callbacks to run, and same with WoW.
Imagine you're waiting for a package to be delivered. You don't stand by the door all day waiting for it (which would be like constantly checking in a loop). Instead, you might continue with your day, and when the doorbell rings (the event), you go to answer it (the callback function is executed).
What was explained is what is a callback in general in the context of videogames. In our case, we have multiple events that our callbacks will be listening to. These are the following:
-
On Update โ This is the callback that you will use to run your logic most of the time. The code placed inside this callback is called at a reduced speed, relative to the speed of
On Render. It's ideal for logic that doesn't need to be executed every frame. In a game where 95% of spells have a global cooldown, 50% of spells are cast, and units move at 7 yards per second, you don't need to read all the information and check everything every frame. Doing so at 120 FPS means you're, for example, checking the position of all units 120 times per second, which is unnecessary. That's whereOn Updatecomes in. -
On Render โ This is a callback used only for rendering graphics, like rectangles, circles, etc. (See graphics). It is the most important and central callback, placed within the game inside DirectX in a part called
EndScene. Every time DirectX is about to render something, this callback is called. That's why it's calledOn Render, and it's the callback that's called the most times of allโexactly once per frame. This allows the game to draw the graphics and call your callback so that you can draw at the same speed, neither one frame more nor less, ensuring it feels natural within the game. While you could place your logic here, common sense suggests otherwise. -
On Render Menu โ This is a callback used only for rendering menu elements. (See Menu Elements)
-
On Render Control Panel โ This is a very specialized callback that will be used ONLY to handle the control panel elements. (See Control Panel)
-
On Spell Cast โ This callback will only trigger if a spell is cast, so it might be useful to control some specific cooldowns or how your spells (or other game objects) are being cast.
-
On Legit Spell Cast โ This callback will only trigger if a spell is MANUALLY cast by the player.
As you will see in the following examples, all callbacks expect you to pass a function. This function must contain all the code that will be read in the case that the event that the callback is listening to is triggered.
You can pass it anonymously:
core.register_on_render_callback(function()
-- your render code here
end)
Or you can pass a defined function:
local function all_my_render_code_function()
-- your render code here
end
core.register_on_render_callback(all_my_render_code_function)
On render callback was used just as an example, but this behaviour is the same for all available callbacks.
Callback Functions ๐โ
core.register_on_pre_tick_callbackโ
Syntax
core.register_on_pre_tick_callback(callback: function)
Parameters
callback:function- The function to be called before each game tick.
Registers a callback function to be executed before each game tick.
Example Usage
core.register_on_pre_tick_callback(function()
-- Code to execute before each game tick
end)
core.register_on_update_callbackโ
Syntax
core.register_on_update_callback(callback: function)
Parameters
callback:function- The function to be called on each frame update.
Registers a callback function to be executed on each frame update.
Example Usage
core.register_on_update_callback(function()
-- Code to execute every frame
end)
core.register_on_render_callbackโ
Syntax
core.register_on_render_callback(callback: function)
Parameters
callback:function- The function to be called during the render phase.
Registers a callback function to be executed during the render phase.
Example Usage
local function on_render()
-- Rendering code here
end
core.register_on_render_callback(on_render)
core.register_on_render_menu_callbackโ
Syntax
core.register_on_render_menu_callback(callback: function)
Parameters
callback:function- The function to render custom menu elements.
Registers a callback function to render custom menu elements.
Avoid calling game functions within this callback. It should be used solely for rendering menus and variables.
Example Usage
local function render_menu()
-- Menu rendering code here
end
core.register_on_render_menu_callback(render_menu)
core.register_on_render_control_panel_callbackโ
Syntax
core.register_on_render_control_panel_callback(callback: function)
Parameters
callback:function- The function to render control panel elements.
Registers a callback function to render control panel elements.
Example Usage
local function render_control_panel()
-- Control panel rendering code here
end
core.register_on_render_control_panel_callback(render_control_panel)
core.register_on_render_window_callbackโ
Syntax
core.register_on_render_window_callback(callback: function)
Parameters
callback:function- The function to be called during window rendering.
Registers a callback function to be executed during window rendering phase.
Example Usage
core.register_on_render_window_callback(function()
-- Window rendering code here
end)
core.register_on_spell_cast_callbackโ
Syntax
core.register_on_spell_cast_callback(callback: function)
Parameters
callback:function- The function to be called when any spell is cast.
Registers a callback function that is invoked whenever any spell is cast in the game, including spells cast by the player, allies, and enemies.
Callback Data Structure
The callback receives a data table with the following fields:
| Field | Type | Description |
|---|---|---|
spell_id | number | Unique identifier for the spell |
caster | game_object|nil | The game object that cast the spell |
target | game_object|nil | The game object targeted by the spell |
spell_cast_time | number | The time when the spell was cast |
Example Usage
local function on_spell_casted(data)
-- Access spell data
local spell_name = core.spell_book.get_spell_name(data.spell_id)
core.log(string.format("Spell cast detected: %s", spell_name))
end
core.register_on_spell_cast_callback(on_spell_casted)
core.register_on_legit_spell_cast_callbackโ
Syntax
core.register_on_legit_spell_cast_callback(callback: function)
Parameters
callback:function- The function to be called when the local player casts a spell, including unsuccessful attempts.
Registers a callback function that is invoked when the local player casts a spell, including unsuccessful attempts.
Example Usage
local function on_legit_spell_cast(data)
-- Handle local player's spell cast
end
core.register_on_legit_spell_cast_callback(on_legit_spell_cast)
The "data" parameter is filled with the ID of the spell that was just casted. You can check the way this callback works by adding a core.log(tostring(data)) call inside the function called by the callback.
Logging - An Important Tool ๐ฅโ
Use Logs In Your Code!
Adding debug logs is a very powerfull tool that you should use in all your plugins. This will help you find bugs and typos very easily. One option that we recommend is that you add a debug local variable (boolean) at the top of your code. When true, the debug for your code will be enabled. For example:local debug = false
local function my_logics()
local is_check_1_ok = true
if not is_check_1_ok then
if debug then
core.log("Check 1 is not ok! .. aborting logics because of it - -")
end
return false
end
local is_check_2_ok = true
if not is_check_2_ok then
if debug then
core.log("Check 2 is not ok! .. aborting logics because of it - -")
end
return false
end
if debug then
core.log("All checks were ok! .. Running logics succesfully!")
end
return true
end
Obviously, this is a very simple example without any real logic or functionality, but it was showcased here just so you see the recommended workflow. All these prints will only work if your debug variable is true, which is something you can change in less than a second.
Logging - Functions ๐โ
core.logโ
Syntax
core.log(message: string)
Parameters
message:string- The message to log.
Logs a standard message.
Example Usage
core.log("This is a standard log message.")
Use LUA's in-built strings function to format your logs. For example, to pass from boolean or number to string, you would have to use the tostring() function. Example: Logging the cooldown of a spell:
local function print_spell_cd(spell_id)
local local_player = core.object_manager.get_local_player()
if not local_player then
return
end
local spell_cd = core.spell_book.get_spell_cooldown(spell_id)
core.log("Remaining Spell (ID: " .. tostring(spell_id) .. ") CD: " .. tostring(spell_cd) .. "s")
end
core.log_errorโ
Syntax
core.log_error(message: string)
Parameters
message:string- The error message to log.
Logs an error message.
Example Usage
core.log_error("An error has occurred.")
core.log_warningโ
Syntax
core.log_warning(message: string)
Parameters
message:string- The warning message to log.
Logs a warning message.
Example Usage
core.log_warning("This is a warning message.")
core.log_fileโ
Syntax
core.log_file(message: string)
Parameters
message:string- The message to log to a file.
Logs a message to a file.
Access to core.log_file may be restricted due to security considerations.
File Logging for Third-Party Developers
For third-party developers who need file logging capabilities, you can use core.create_log_file and core.write_log_file from the File I/O module:
-- Create and write to a custom log file
core.create_log_file("combat.log")
core.write_log_file("combat.log", "Addon started\n")
core.write_log_file("combat.log", "Target acquired: " .. tostring(unit_name) .. "\n")
For the quickest and easiest logging solution, we recommend using the izi.log helper functions from the izi library. It handles file creation and management automatically, so you don't have to manually build your log files every time.
For more details on file operations, see File I/O.
Time and Performance Functions โฑ๏ธโ
core.get_pingโ
Syntax
core.get_ping() -> number
number: The current network ping.
Retrieves the current network ping.
Example Usage
local ping = core.get_ping()
core.log("Current ping: " .. ping .. " ms")
core.timeโ
Syntax
core.time() -> number
number: The time in seconds since the PS injection happened.
Dont use this time to work with server info like buff_end_time, spell_cast_end_time, they work in milliseconds and only with core.game_time()
Returns the time elapsed since the script was injected.
Example Usage
local script_time = core.time()
core.log("Time since script injection: " .. script_time .. " s")
core.game_timeโ
Syntax
core.game_time() -> number
number: The time in milliseconds since the game started.
This is the time that should be used to work with game info like buff_end_time, spell_cast_end_time, etc...
Returns the time elapsed since the game started.
Example Usage
local game_time = core.game_time()
core.log("Game time elapsed: " .. game_time .. " ms")
core.delta_timeโ
Syntax
core.delta_time() -> number
number: The time in milliseconds since the last frame.
Returns the time elapsed since the last frame.
Example Usage
local dt = core.delta_time()
-- Use dt for frame-dependent calculations
core.cpu_timeโ
Syntax
core.cpu_time() -> number
number: The CPU time used.
Retrieves the CPU time used.
Example Usage
local cpu_time = core.cpu_time()
core.log("CPU time used: " .. cpu_time)
core.cpu_ticksโ
Syntax
core.cpu_ticks() -> number
number: The current CPU tick count.
Retrieves the current CPU tick count. Useful for high-precision performance profiling.
Example Usage
local start_ticks = core.cpu_ticks()
-- ... code to profile ...
local end_ticks = core.cpu_ticks()
local elapsed = (end_ticks - start_ticks) / core.cpu_ticks_per_second()
core.log("Operation took: " .. elapsed .. " seconds")
core.cpu_ticks_per_secondโ
Syntax
core.cpu_ticks_per_second() -> number
number: The number of CPU ticks per second.
Retrieves the number of CPU ticks per second. Use this in conjunction with core.cpu_ticks() for accurate performance measurements.
Example Usage
local ticks_per_second = core.cpu_ticks_per_second()
core.log("CPU ticks per second: " .. ticks_per_second)
Game Information Functions ๐บ๏ธโ
core.get_map_idโ
Syntax
core.get_map_id() -> number
number: The current map ID.
Retrieves the ID of the current map.
Example Usage
local map_id = core.get_map_id()
core.log("Current map ID: " .. map_id)
core.get_map_nameโ
Syntax
core.get_map_name() -> string
string: The name of the current map.
Retrieves the name of the current map.
Example Usage
local map_name = core.get_map_name()
core.log("Current map: " .. map_name)
core.get_cursor_positionโ
Syntax
core.get_cursor_position() -> vec2
vec2: The current cursor position.
Retrieves the current cursor position on the screen.
Example Usage
local cursor_pos = core.get_cursor_position()
core.log(string.format("Cursor position: (%.2f, %.2f)", cursor_pos.x, cursor_pos.y))
core.get_instance_idโ
Syntax
core.get_instance_id() -> integer
integer: The ID of the current instance.
Retrieves the ID of the current instance.
core.get_instance_nameโ
Syntax
core.get_instance_name() -> string
string: The name of the current instance.
Retrieves the name of the current instance.
core.get_instance_typeโ
Syntax
core.get_instance_type() -> string
string: The type of the current instance.
Retrieves the type of the current instance (e.g., "raid", "dungeon", "arena", "battleground", "none").
Example Usage
local instance_type = core.get_instance_type()
if instance_type == "raid" then
core.log("Currently in a raid!")
end
core.get_difficulty_idโ
Syntax
core.get_difficulty_id() -> integer
integer: The ID of the current instance difficulty.
Retrieves the ID of the current instance difficulty.
core.get_difficulty_nameโ
Syntax
core.get_difficulty_name() -> string
string: The name of the current instance's difficulty.
Retrieves the name of the current instance's difficulty (e.g., "Normal", "Heroic", "Mythic").
core.get_keystone_levelโ
Syntax
core.get_keystone_level() -> integer
integer: The level of the Mythic+ keystone.
Returns the Mythic+ keystone level of the current dungeon, if applicable.
core.get_height_for_positionโ
Syntax
core.get_height_for_position(position: vec3) -> number
Parameters
position:vec3- The 3D coordinates for which to get the height.
number: The height value at the given position.
Returns the height at the given position in the game world.
core.get_game_versionโ
Syntax
core.get_game_version() -> string
string: The current game version.
Returns the current game version. Possible values: "Retail", "Classic", "Classic Era", "Classic Pandaria", "Classic Tbc", "Titan".
Example Usage
local version = core.get_game_version()
if version == "Retail" then
core.log("Running on Retail!")
elseif version == "Classic" then
core.log("Running on Classic!")
end
core.get_game_regionโ
Syntax
core.get_game_region() -> string
string: The current game region.
Returns the current game region. Possible values: "West", "China".
Example Usage
local region = core.get_game_region()
core.log("Playing in region: " .. region)
core.is_main_menu_openโ
Syntax
core.is_main_menu_open() -> boolean
boolean:trueif the main menu is open,falseotherwise.
Checks if the main menu is currently open.
Example Usage
if core.is_main_menu_open() then
core.log("Main menu is open")
end
HTTP Functions ๐โ
The HTTP module allows you to make asynchronous HTTP requests for fetching remote data such as JSON, text, or images.
core.http_getโ
Syntax
-- Without headers
core.http_get(url: string, callback: function)
-- With headers
core.http_get(url: string, headers: table, callback: function)
Parameters
url:string- The URL to fetch.headers(optional):table<string, string>- HTTP headers to send with the request.callback:function- Function called when the request completes.
Callback Parameters
| Parameter | Type | Description |
|---|---|---|
http_code | integer | HTTP status code (200, 404, etc). Transport failure may be 0. |
content_type | string | Server content type |
response_data | string | Raw response body (binary safe) |
response_headers | string | Response headers dump |
Performs an asynchronous HTTP GET request. This API is generally used to fetch remote data (JSON, text, images, etc).
Example Usage - Simple Request
core.http_get("https://httpbin.org/get", function(http_code, content_type, response_data, response_headers)
core.log("Status: " .. http_code)
core.log("Response: " .. response_data)
end)
Example Usage - With Headers
core.http_get("https://httpbin.org/get", {
["Authorization"] = "Bearer token123",
["User-Agent"] = "MyApp/1.0",
["Accept"] = "application/json"
}, function(http_code, content_type, response_data, response_headers)
core.log("Status: " .. http_code)
core.log("Response: " .. response_data)
end)
Example Usage - Download and Load Texture
core.http_get("https://example.com/image.png", function(http_code, content_type, response_data, response_headers)
if http_code == 200 and response_data and #response_data > 0 then
local texture_id, width, height = core.graphics.load_texture(response_data)
if texture_id then
core.log("Texture loaded! ID: " .. texture_id .. ", Size: " .. width .. "x" .. height)
end
end
end)
Inventory ๐โ
See Inventory Helper for more info.
core.inventory.get_items_in_bagโ
Syntax
core.inventory.get_items_in_bag(id: integer) -> table<item_slot_info>
Parameters
id:integer- The bag ID.
table<item_slot_info>: A table containing the item data.
The item slot info contains 2 members:
.slot_id-> the id of the slot.object-> the item itself (game_object)
This function returns all the items in the bag with the ID that you pass as parameter. This is a low-level function, and we recommend, like always, to use our LUA libraries that we crafted so the development is easier for everyone. For more info, check out the Inventory Helper library.
Bag IDs:
-2for the keyring-4for the tokens bag0= backpack,1to4for the bags on the character
While bank is opened:
-1for the bank content5to11for bank bags (numbered left to right, was 5-10 prior to TBC expansion, 2.0 game version)
Check https://wowwiki-archive.fandom.com/wiki/BagId for more info.
Game UI Functions ๐ฎโ
For game UI related functions such as loot window, battlefield status, cursor position, and more, see the dedicated Game UI documentation.
File I/O Functions ๐โ
For file operations including reading/writing data files, log files, and accessing game files, see the dedicated File I/O documentation.
Additional Notes ๐โ
- Performance Monitoring: Utilize the time and CPU functions to monitor and optimize your script's performance.
- Event Handling: Register appropriate callbacks to handle events effectively within your script.
- Logging Best Practices: Consistently log important information for easier debugging and maintenance.