0% found this document useful (0 votes)
5 views18 pages

Kobalt Lua API

The Kobalt Lua API document outlines the Lua scripting capabilities available when LUA_SUPPORT_ENABLED is activated, detailing runtime compatibility, script directory, and main binding files. It includes information on script metadata, event registration, various API functions for player, weapon, and movement interactions, as well as clantag management. Additionally, it provides examples and return conventions for functions, along with constants and types used within the API.

Uploaded by

mrysf5734
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views18 pages

Kobalt Lua API

The Kobalt Lua API document outlines the Lua scripting capabilities available when LUA_SUPPORT_ENABLED is activated, detailing runtime compatibility, script directory, and main binding files. It includes information on script metadata, event registration, various API functions for player, weapon, and movement interactions, as well as clantag management. Additionally, it provides examples and return conventions for functions, along with constants and types used within the API.

Uploaded by

mrysf5734
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Kobalt Lua API

This document describes the active Lua scripting API exposed by Kobalt when
LUA_SUPPORT_ENABLED is enabled.

Status after CS2 audit


• Runtime: Lua 5.4 through sol2.
• Script directory: %APPDATA%\Kobalt\scripts\.
• Main binding files: src/scripting/[Link], src/scripting/[Link],
src/scripting/LuaManager.h.
• CS2 architecture: player state is split between CCSPlayerController
and C_CSPlayerPawn; player APIs resolve controller indices to pawn han-
dles internally.
• Schema access: player, entity, weapon, movement, globals, and bones
reads use existing schema-backed wrappers and safe null checks.
• Clantag: scripts can set a custom static clantag instead of the built-in
Kobalt animation.
• Frame stages: on_frame_stage now dispatches and receives the integer
EClientFrameStage value.
• Disabled legacy block: the old disabled #if 0 weapon/convar/globals/bones
block is still present as dead code, but active implementations now exist
for weapon, cvars, globals, and bones.

Script metadata
Optional metadata can be placed at the top of a script:
-- @author YourName
-- @version 1.0
-- @description Short script description

Quick example
local white = { r = 255, g = 255, b = 255, a = 255 }
local red = { r = 255, g = 80, b = 80, a = 255 }

[Link]("on_paint", function()
if not engine.is_in_game() then
return
end

for _, idx in ipairs(entity.get_players()) do


if player.is_alive(idx) and player.is_enemy(idx) then
local x, y, z = player.get_origin(idx)
local ok, sx, sy = render.world_to_screen(x, y, z + 72)
if ok then

1
[Link](sx, sy, player.get_name(idx), red)
end
end
end
end)

client.log_success("Lua script loaded")

Clantag example
[Link]("MY TAG")
clantag.set_show_without_username(true)
client.log_success("Custom clantag enabled")

Return conventions
• Invalid index: most entity/player/weapon functions return -1 for invalid
entity handles.
• Missing numeric value: functions return 0 or 0.0 when no valid source
exists.
• Missing vectors/angles: functions return 0, 0, 0.
• Missing strings: functions return an empty string.
• Booleans: functions return false when unavailable.

Events
Register callbacks with:
[Link](event_name, callback)
[Link](event_name)
The alias API is also available:
environment.register_callback(event_name, callback)
environment.unregister_callback(event_name)

Event names
• on_paint / paint: called during render; use for drawing/UI.
• on_createmove / createmove: called from CreateMove; movement but-
ton edits are valid here.
• on_frame_stage / frame_stage: called after frame-stage post-original
work; callback receives stage.
• on_game_event / game_event: generic game event callback; receives
LuaGameEvent.
• on_player_hurt / player_hurt: receives LuaGameEvent for player hurt.
• on_player_death / player_death: receives LuaGameEvent for player
death.

2
• on_round_start / round_start: receives LuaGameEvent for round start.
• on_round_end / round_end: receives LuaGameEvent for round end.
• on_override_view / override_view: receives LuaViewSetup.
• on_unload / unload: called during script unload.
• on_player_chat / player_chat: registered name is exposed; dispatch
depends on hook coverage.
• on_console_input / console_input: registered name is exposed; dis-
patch depends on hook coverage.
• on_string_cmd / string_cmd: registered name is exposed; dispatch de-
pends on hook coverage.

Frame-stage constants
Use these with on_frame_stage or engine.get_frame_stage():
• engine.FRAME_NET_UPDATE_POSTDATAUPDATE_START
• engine.FRAME_NET_UPDATE_POSTDATAUPDATE_END
• engine.FRAME_NET_FULL_FRAME_UPDATE_ON_REMOVE
• engine.FRAME_RENDER_START
• engine.FRAME_RENDER_END
• engine.FRAME_NET_UPDATE_END
• engine.FRAME_NET_CREATION
• engine.FRAME_RESTORE_SERVER_STATE
• engine.FRAME_SIMULATE_END
Example:
[Link]("on_frame_stage", function(stage)
if stage == engine.FRAME_RENDER_START then
[Link]("render start")
end
end)

Types
LuaVec2
Fields:
• x: number
• y: number

LuaVec3
Fields:
• x: number
• y: number
• z: number

3
LuaAngle
Fields:
• pitch: number
• yaw: number
• roll: number

LuaColor
Fields are floats in the 0.0..1.0 range:
• r: number
• g: number
• b: number
• a: number

Color tables
Most older render functions accept integer color tables:
{ r = 255, g = 255, b = 255, a = 255 }

LuaTexture
Returned by texture setup functions.
Fields are internal; use with [Link].

LuaGameEvent
Methods:
• event:get_name() -> string
• event:get_bool(key, default?) -> bool
• event:get_int(key, default?) -> integer
• event:get_uint64(key, default?) -> integer
• event:get_float(key, default?) -> number
• event:get_string(key, default?) -> string
• event:set_bool(key, value)
• event:set_int(key, value)
• event:set_uint64(key, value)
• event:set_float(key, value)
• event:set_string(key, value)

LuaViewSetup
Methods:
• view:get_fov() -> number
• view:set_fov(value)

4
• view:get_viewmodel_fov() -> number
• view:set_viewmodel_fov(value)
• view:get_origin() -> x, y, z
• view:set_origin(x, y, z)
• view:get_angles() -> pitch, yaw, roll
• view:set_angles(pitch, yaw, roll)

LuaConVar
Returned by [Link](name) or [Link].
Methods:
• convar:valid() -> bool
• convar:get_name() -> string
• convar:get_string() -> string
• convar:get_float() -> number
• convar:get_int() -> integer
• convar:get_bool() -> bool
• convar:set_string(value) -> bool
• convar:set_float(value) -> bool
• convar:set_int(value) -> bool
• convar:set_bool(value) -> bool

client
• [Link](message): log info text to the Lua console.
• client.log_error(message): log error text.
• client.log_warning(message): log warning text.
• client.log_success(message): log success text.
• [Link](command): execute an unrestricted client command.
• client.get_time() -> number: ImGui time in seconds.
• client.get_frametime() -> number: ImGui frame delta.
• client.get_screen_size() -> width, height: current render-space
display size.
• client.play_sound(path, volume?) -> bool: play a .wav file from
disk or a VSound path.

clantag
The clantag API controls the same clantag/name-prefix path as the menu iden-
tity feature. [Link](text) enables the clantag changer and replaces the
default Kobalt animation with the supplied static text.
• [Link](text) -> bool: sanitize, truncate, enable, and apply a cus-
tom clantag. Returns false when the sanitized text is empty.
• [Link]() -> string: current custom clantag text.

5
• clantag.get_active() -> string: currently active tag frame being
sent/displayed.
• [Link](): clear custom text and disable the clantag changer.
• clantag.set_enabled(enabled): enable/disable the clantag changer.
• clantag.is_enabled() -> bool: current clantag changer state.
• clantag.set_show_without_username(enabled): when enabled, prefix
the clantag onto the real name if no custom username is set.
• clantag.get_show_without_username() -> bool
• clantag.MAX_LENGTH: maximum stored clantag length, currently 31.

engine
• engine.is_in_game() -> bool
• engine.is_connected() -> bool
• engine.get_max_clients() -> integer
• engine.get_local_player_index() -> integer: local controller entity
index.
• engine.get_view_angles() -> pitch, yaw, roll: current base com-
mand view angles.
• engine.get_tick_count() -> integer
• engine.execute_client_cmd(command)
• engine.chat_print(message)
• engine.get_level_name() -> string
• engine.camera_in_thirdperson() -> bool
• engine.get_netvar_offset(module, class, field) -> integer
• engine.get_frame_stage() -> integer: current frame stage during
frame-stage dispatch, otherwise -1.

entity
• entity.get_players() -> table<int>: controller entity indices.
• entity.get_highest_index() -> integer
• entity.get_origin(index) -> x, y, z
• entity.get_team(index) -> integer
• entity.get_health(index) -> integer
• entity.get_max_health(index) -> integer
• entity.get_by_index(index) -> integer: returns index if valid, else
-1.
• entity.get_class_name(index) -> string
• entity.is_valid(index) -> bool

entitylist
• entitylist.get_local_player_controller() -> integer
• entitylist.get_local_player_pawn() -> integer
• entitylist.get_game_rules() -> lightuserdata | nil

6
• entitylist.get_entities() -> table<int>
• entitylist.get_entities(callback)
• entitylist.get_entities(class_name, include_derived?) ->
table<int>
• entitylist.get_entities(class_name, include_derived?, callback)
Callback form avoids returning a full table:
entitylist.get_entities("C_CSPlayerPawn", true, function(index)
[Link]("pawn " .. tostring(index))
end)

player
All player functions take a controller entity index unless noted.
• player.get_name(index) -> string
• player.get_health(index) -> integer
• player.get_armor(index) -> integer
• player.has_helmet(index) -> bool
• player.has_defuser(index) -> bool
• player.get_team(index) -> integer
• player.is_alive(index) -> bool
• player.is_scoped(index) -> bool
• player.is_defusing(index) -> bool
• player.get_origin(index) -> x, y, z
• player.get_eye_pos(index) -> x, y, z
• player.get_velocity(index) -> x, y, z
• player.get_velocity_2d(index) -> number
• player.is_enemy(index) -> bool
• player.get_money(index) -> integer
• player.get_active_weapon(index) -> integer: active weapon entity
index.
• player.get_pawn(index) -> integer: pawn entity index for a
controller.
• player.get_eye_angles(index) -> pitch, yaw, roll
• player.get_local() -> integer: local controller index.
• player.get_local_pawn() -> integer: local pawn index.

weapon
Most weapon functions take a weapon entity index from player.get_active_weapon(index).
• weapon.get_clip1(weapon_index) -> integer
• weapon.get_name(weapon_index) -> string
• weapon.get_inaccuracy(weapon_index) -> number
• weapon.get_spread(weapon_index) -> number
• weapon.get_type(weapon_index) -> integer

7
• weapon.get_max_clip1(weapon_index) -> integer
• weapon.is_reloading(weapon_index) -> bool
• weapon.is_knife(weapon_index) -> bool
• weapon.is_grenade(weapon_index) -> bool
• weapon.get_damage(weapon_index) -> integer
• weapon.get_range(weapon_index) -> number
• weapon.get_penetration(weapon_index) -> number
Constants:
• weapon.TYPE_KNIFE
• weapon.TYPE_PISTOL
• weapon.TYPE_SMG
• weapon.TYPE_RIFLE
• weapon.TYPE_SHOTGUN
• weapon.TYPE_SNIPER
• weapon.TYPE_MG
• weapon.TYPE_GRENADE
• weapon.TYPE_C4

movement
Movement writes only make sense during on_createmove.
State reads:
• movement.is_on_ground() -> bool
• movement.is_ducking() -> bool
• movement.get_flags() -> integer
• movement.get_move_type() -> integer
• movement.get_velocity() -> x, y, z
• movement.get_speed() -> number
• movement.get_speed_3d() -> number
• movement.get_origin() -> x, y, z
Button reads/writes:
• movement.get_buttons() -> integer
• movement.is_button_pressed(flag) -> bool
• movement.set_button(flag, enabled)
• movement.set_buttons(buttons)
• [Link](enabled)
• [Link](enabled)
Flags:
• movement.FL_ONGROUND
• movement.FL_DUCKING
• movement.FL_WATERJUMP
• movement.FL_ONTRAIN

8
Command buttons:
• movement.IN_ATTACK
• movement.IN_JUMP
• movement.IN_DUCK
• movement.IN_FORWARD
• movement.IN_BACK
• movement.IN_USE
• movement.IN_MOVELEFT
• movement.IN_MOVERIGHT
• movement.IN_ATTACK2
• movement.IN_RELOAD
• movement.IN_SPRINT
• movement.IN_ZOOM
Move types:
• movement.MOVETYPE_NONE
• movement.MOVETYPE_WALK
• movement.MOVETYPE_FLY
• movement.MOVETYPE_FLYGRAVITY
• movement.MOVETYPE_NOCLIP
• movement.MOVETYPE_OBSERVER
• movement.MOVETYPE_LADDER

globals
• globals.get_tick_interval() -> number
• globals.get_tick_count() -> integer
• globals.get_curtime() -> number
• globals.get_realtime() -> number
• globals.get_frame_time() -> number
• globals.get_frame_count() -> integer
• globals.get_server_tick() -> integer
• globals.get_choked_commands() -> integer
• globals.get_max_clients() -> integer
• globals.get_map_name() -> string
• globals.is_freeze_time() -> bool

bones
All bones functions take a player controller index.
• bones.get_position(player_index, bone_index) -> x, y, z
• bones.get_position_by_name(player_index, bone_name) -> x, y,
z
• bones.get_head(player_index) -> x, y, z
• bones.get_count(player_index) -> integer

9
Constants:
• [Link]
• [Link]
• [Link]
• [Link]
• bones.LEFT_UPPER_ARM
• bones.LEFT_LOWER_ARM
• bones.LEFT_HAND
• bones.RIGHT_UPPER_ARM
• bones.RIGHT_LOWER_ARM
• bones.RIGHT_HAND
• bones.LEFT_UPPER_LEG
• bones.LEFT_LOWER_LEG
• bones.LEFT_ANKLE
• bones.RIGHT_UPPER_LEG
• bones.RIGHT_LOWER_LEG
• bones.RIGHT_ANKLE

render
These draw on the foreground draw list and generally take color tables.
• [Link](x, y, text, color)
• [Link](x, y, w, h, color, rounding?)
• render.rect_filled(x, y, w, h, color, rounding?)
• [Link](x1, y1, x2, y2, color, thickness?)
• [Link](x, y, radius, color, segments?)
• render.circle_filled(x, y, radius, color, segments?)
• render.world_to_screen(x, y, z) -> ok, sx, sy
• render.get_text_size(text) -> LuaVec2
• render.screen_size() -> LuaVec2
• render.setup_texture(path) -> LuaTexture
• render.setup_texture_from_memory(bytes) -> LuaTexture
• render.setup_texture_rgba(bytes, width, height) -> LuaTexture
• render.setup_texture_rgba(table, width, height) -> LuaTexture
• [Link](texture, x, y, w, h, color?)
• [Link](texture, pos, size, color?)
• render.rect_filled_fade(x, y, w, h, c1, c2, c3, c4)
• render.poly_line(points, color, closed?, thickness?)
• [Link](points, color)

draw
These draw on the background draw list and use integer color arguments.
• [Link](x1, y1, x2, y2, r, g, b, a?, thickness?)

10
• [Link](x, y, w, h, r, g, b, a?, rounding?, thickness?)
• draw.rect_filled(x, y, w, h, r, g, b, a?, rounding?)
• draw.rect_filled_multicolor(x, y, w, h, r1, g1, b1, a1, r2,
g2, b2, a2, r3, g3, b3, a3, r4, g4, b4, a4)
• [Link](x, y, radius, r, g, b, a?, segments?, thickness?)
• draw.circle_filled(x, y, radius, r, g, b, a?, segments?)
• [Link](x1, y1, x2, y2, x3, y3, r, g, b, a?, thickness?)
• draw.triangle_filled(x1, y1, x2, y2, x3, y3, r, g, b, a?)
• [Link](x1, y1, x2, y2, x3, y3, x4, y4, r, g, b, a?,
thickness?)
• draw.quad_filled(x1, y1, x2, y2, x3, y3, x4, y4, r, g, b,
a?)
• [Link](x, y, text, r, g, b, a?)
• draw.text_centered(x, y, text, r, g, b, a?)
• [Link](points, r, g, b, a?, closed?, thickness?)
• draw.convex_poly_filled(points, r, g, b, a?)
• draw.bezier_cubic(x1, y1, x2, y2, x3, y3, x4, y4, r, g, b,
a?, thickness?, segments?)
• draw.get_screen_size() -> width, height
• draw.world_to_screen(x, y, z) -> ok, sx, sy

input
• input.is_key_pressed(vk_code) -> bool: high bit from GetAsyncKeyState;
true while key is held.
• input.is_key_down(vk_code) -> bool: low bit from GetAsyncKeyState;
true on transition.
• input.get_mouse_pos() -> x, y: OS cursor position.
Constants include:
• input.VK_LBUTTON
• input.VK_RBUTTON
• input.VK_MBUTTON
• input.VK_XBUTTON1
• input.VK_XBUTTON2
• input.VK_SHIFT
• input.VK_CONTROL
• input.VK_MENU
• input.VK_SPACE
• input.VK_ESCAPE
• input.VK_INSERT
• input.VK_DELETE
• input.VK_HOME
• input.VK_END
• input.VK_TAB
• input.VK_RETURN

11
• input.VK_BACK
• input.VK_UP
• input.VK_DOWN
• input.VK_LEFT
• input.VK_RIGHT
• input.VK_F1 through input.VK_F12

math_ex
• math_ex.calc_angle(x1, y1, z1, x2, y2, z2) -> pitch, yaw
• math_ex.normalize_angle(angle) -> number
• math_ex.distance_3d(x1, y1, z1, x2, y2, z2) -> number
• math_ex.distance_2d(x1, y1, x2, y2) -> number
• math_ex.clamp(value, min, max) -> number
• math_ex.lerp(a, b, t) -> number
• math_ex.calc_fov(viewPitch, viewYaw, aimPitch, aimYaw) ->
number
• math_ex.calc_fov(viewPitch, viewYaw, viewRoll, aimPitch,
aimYaw, aimRoll) -> number
• math_ex.angle_vectors(pitch, yaw, roll?) -> forward, right,
up
• math_ex.vector_angles(x, y, z) -> pitch, yaw, roll
• math_ex.random_float(min, max) -> number
• math_ex.random_int(min, max) -> integer

config
Configuration access is by internal config variable name.
• config.get_bool(name) -> bool
• config.set_bool(name, value) -> bool
• config.get_float(name) -> number
• config.set_float(name, value) -> bool
• config.get_int(name) -> integer
• config.set_int(name, value) -> bool
• config.get_string(name) -> string
• config.set_string(name, value) -> bool

cvars
• [Link](name) -> LuaConVar
• [Link](name) -> bool
• cvars.<name> -> LuaConVar through metatable lookup.
Example:
local sv_cheats = [Link]("sv_cheats")
if sv_cheats:valid() then

12
[Link]("sv_cheats = " .. tostring(sv_cheats:get_int()))
end

environment
• environment.get_user_name() -> string
• environment.get_game_directory() -> string
• environment.get_script_name() -> string
• environment.color_print(message, color?)
• environment.find_pattern(module, pattern) -> lightuserdata |
nil
• environment.find_export(module, export_name) -> lightuserdata
| nil
• environment.register_callback(event_name, callback)
• environment.unregister_callback(event_name)

ui
The ui namespace wraps ImGui. Use from on_paint.

Windows
• ui.begin_window(title, closable?, flags?) -> visible, open
• ui.end_window()
• ui.set_next_window_pos(x, y, cond?)
• ui.set_next_window_size(w, h, cond?)
• ui.set_next_window_bg_alpha(alpha)
• ui.set_next_window_focus()
• ui.get_window_pos() -> x, y
• ui.get_window_size() -> w, h
• ui.get_content_region_avail() -> w, h

Child windows
• ui.begin_child(id, w?, h?, border?, flags?) -> bool
• ui.end_child()

Style
• ui.push_style_color(idx, r, g, b, a?)
• ui.pop_style_color(count?)
• ui.push_style_var(idx, value)
• ui.push_style_var2(idx, x, y)
• ui.pop_style_var(count?)
• ui.push_item_width(width)
• ui.pop_item_width()
• ui.push_font(font_index?)

13
• ui.pop_font()

Layout
• [Link]()
• [Link]()
• [Link](w, h)
• [Link](width?)
• [Link](width?)
• ui.same_line(offset?, spacing?)
• ui.new_line()
• ui.begin_group()
• ui.end_group()
• ui.set_cursor_pos(x, y)
• ui.set_cursor_pos_x(x)
• ui.set_cursor_pos_y(y)
• ui.get_cursor_pos() -> x, y
• ui.get_cursor_screen_pos() -> x, y

Text and controls


• [Link](text)
• ui.text_colored(text, r, g, b, a?)
• ui.text_disabled(text)
• ui.text_wrapped(text)
• ui.label_text(label, text)
• ui.bullet_text(text)
• [Link](label, w?, h?) -> bool
• ui.small_button(label) -> bool
• ui.invisible_button(id, w, h) -> bool
• ui.arrow_button(id, dir) -> bool
• [Link](label, value) -> bool
• ui.radio_button(label, active) -> bool
• ui.progress_bar(fraction, w?, h?, overlay?)
• [Link]()

Inputs
• ui.input_text(label, value, flags?) -> string
• ui.input_text_multiline(label, value, w?, h?) -> string
• ui.input_int(label, value) -> integer
• ui.input_float(label, value, format?) -> number
• ui.slider_int(label, value, min, max) -> integer
• ui.slider_float(label, value, min, max, format?) -> number
• ui.v_slider_int(label, w, h, value, min, max) -> integer
• ui.v_slider_float(label, w, h, value, min, max) -> number
• ui.drag_int(label, value, speed?, min?, max?) -> integer

14
• ui.drag_float(label, value, speed?, min?, max?) -> number

Color
• ui.color_edit3(label, r, g, b) -> table
• ui.color_edit4(label, r, g, b, a) -> table
• ui.color_picker(label, r, g, b, a) -> table
• ui.color_button(id, r, g, b, a?, w?, h?) -> bool

Combo/list/tree/tab/popup
• [Link](label, current, items, max_height?) -> integer
• [Link](label, current, items, height_items?) -> integer
• [Link](label, selected, flags?, w?, h?) -> bool
• ui.tree_node(label) -> bool
• ui.tree_node_ex(label, flags?) -> bool
• ui.tree_pop()
• ui.collapsing_header(label, flags?) -> bool
• ui.set_next_item_open(open, cond?)
• ui.begin_tab_bar(id, flags?) -> bool
• ui.end_tab_bar()
• ui.begin_tab_item(label, flags?) -> bool
• ui.end_tab_item()
• ui.open_popup(id)
• ui.begin_popup(id, flags?) -> bool
• ui.begin_popup_modal(name, flags?) -> bool
• ui.end_popup()
• ui.close_current_popup()
• ui.begin_popup_context_item(id?) -> bool
• ui.begin_popup_context_window(id?) -> bool

Tooltips and item state


• ui.begin_tooltip()
• ui.end_tooltip()
• ui.set_tooltip(text)
• [Link](text)
• ui.is_item_hovered(flags?) -> bool
• ui.is_item_active() -> bool
• ui.is_item_focused() -> bool
• ui.is_item_clicked(button?) -> bool
• ui.is_item_visible() -> bool
• ui.is_item_edited() -> bool
• ui.is_item_activated() -> bool
• ui.is_item_deactivated() -> bool
• ui.is_item_deactivated_after_edit() -> bool
• ui.is_any_item_hovered() -> bool

15
• ui.is_any_item_active() -> bool
• ui.is_any_item_focused() -> bool
• ui.get_item_rect_min() -> x, y
• ui.get_item_rect_max() -> x, y
• ui.get_item_rect_size() -> w, h

Scroll/focus/utilities
• ui.set_keyboard_focus_here(offset?)
• ui.set_scroll_here_x(ratio?)
• ui.set_scroll_here_y(ratio?)
• ui.get_scroll_x() -> number
• ui.get_scroll_y() -> number
• ui.get_scroll_max_x() -> number
• ui.get_scroll_max_y() -> number
• ui.set_scroll_x(value)
• ui.set_scroll_y(value)
• ui.push_id(id)
• ui.push_id_int(id)
• ui.pop_id()
• ui.get_id(id) -> integer
• ui.calc_text_size(text) -> w, h
• ui.get_frame_height() -> number
• ui.get_frame_height_with_spacing() -> number
• ui.get_text_line_height() -> number
• ui.get_text_line_height_with_spacing() -> number
• ui.get_time() -> number
• ui.get_frame_count() -> integer
• ui.get_io_display_size() -> w, h

Common UI constants
The namespace exposes ImGui window flags, tree flags, style colors, style vars,
condition flags, and directions. Examples:
• ui.WindowFlags_NoTitleBar
• ui.WindowFlags_NoResize
• ui.WindowFlags_AlwaysAutoResize
• ui.TreeNodeFlags_DefaultOpen
• ui.Col_Text
• ui.Col_WindowBg
• ui.StyleVar_Alpha
• ui.StyleVar_WindowRounding
• ui.Cond_Always
• ui.Cond_FirstUseEver
• ui.Dir_Left
• ui.Dir_Right

16
• ui.Dir_Up
• ui.Dir_Down

menu
• menu.set_background(path) -> bool
• menu.set_background_from_memory(bytes) -> bool
• menu.set_background_rgba(bytes, width, height) -> bool
• menu.set_background_gif(path) -> bool
• menu.set_background_gif_from_memory(bytes) -> bool
• menu.clear_background()
• menu.has_background() -> bool
• menu.set_background_alpha(alpha)
• menu.get_background_alpha() -> number
• menu.set_background_scale(mode): "fit", "fill", or "stretch".
• menu.get_background_size() -> width, height
• menu.is_open() -> bool

CS2-specific guidance
• Controller vs pawn: use entity.get_players() for controller indices,
then player.get_pawn(index) if you need the pawn entity index.
• Frame-stage work: run expensive model/entity queries on specific
stages, not every on_paint call.
• CreateMove work: only mutate movement buttons from on_createmove.
• Schema-backed reads: prefer exposed helpers over hardcoded offsets. If
you must use offsets, call engine.get_netvar_offset(module, class,
field) and handle 0 as failure.
• Rendering coordinates: screen size and world-to-screen are render-
space; this matches stretched-resolution handling.

Minimal ESP example


local function color(r, g, b, a)
return { r = r, g = g, b = b, a = a or 255 }
end

[Link]("paint", function()
local red = color(255, 60, 60)

for _, idx in ipairs(entity.get_players()) do


if player.is_alive(idx) and player.is_enemy(idx) then
local hx, hy, hz = bones.get_head(idx)
local ok, sx, sy = render.world_to_screen(hx, hy, hz + 8)
if ok then
local name = player.get_name(idx)

17
local hp = player.get_health(idx)
[Link](sx, sy, [Link]("%s [%d]", name, hp), red)
end
end
end
end)

Minimal frame-stage example


[Link]("frame_stage", function(stage)
if stage ~= engine.FRAME_RENDER_START then
return
end

local local_pawn = player.get_local_pawn()


if local_pawn ~= -1 then
[Link]("local pawn: " .. tostring(local_pawn))
end
end)

18

You might also like