Overview
This page documents the Lua-facing API exposed by Nocturne's scripting engine. It covers the globals, modules, and callbacks you can use to read game state, do math, and draw a polished overlay.
Quick start
Hello, overlay
-- file: hello.lua
function on_frame()
overlay.text(30, 40, "Nocturne ready", 0xFF10A5E9)
end
Load the file. On each frame the text is drawn at (30,40) with ARGB color 0xFF10A5E9.
Simple panel
function on_frame()
overlay.panel_begin("demo", "Demo Panel", 260, 120)
overlay.text(12, 12, "inside a draggable panel", 0xFF111827)
overlay.panel_end()
end
Panels are draggable and their position/size is auto‑saved per script.
Callbacks
function on_frame() endCalled once per rendered frame. Do reads and drawing here.
function on_button(id) endOptional. Invoked when a button‑type setting is triggered from the host UI.
function on_settings_applied() endOptional. Called after your script's settings are loaded or changed. Use it to refresh cached values.
Console & logging
print(...) is overridden to write to Nocturne's integrated console.
print("loaded", _VERSION)
Memory API
mem.read(address, size) -> string|nilReads raw memory from the target process the engine is attached to. Returns a byte string or nil on failure. No write API is exposed for safety.
SDK (game) API
These calls require that the engine has attached successfully to the game process. If not attached, they return nil or empty tables.
sdk (module)
sdk.get_local_controller() -> Controller|nilsdk.get_all_controllers() -> { Controller, ... }sdk.get_pawn_from_handle(handle) -> Pawn|nilsdk.get_view_matrix() -> number[16](row‑major 4x4)
Controller
controller:get_team() -> integercontroller:get_name() -> string|nilcontroller:get_pawn() -> Pawn|nil
Pawn
pawn:get_health() -> integerpawn:get_origin() -> { x, y, z }pawn:is_ducked() -> booleanpawn:get_duck_amount() -> numberpawn:get_bone_position(index) -> { x, y, z }|nilpawn:get_aim_punch() -> { pitch, yaw }
Snapshot API
Provides a single‑frame view of game state as seen by the host (includes screen size and a smoothed view matrix).
snapshot.get() -> table|nilsnapshot.get_players() -> { entities... }snapshot.get_view_matrix() -> number[16]snapshot.get_screen_size() -> { w, h }snapshot.get_local_aim_punch() -> { pitch, yaw }
snapshot.get() schema
| Field | Type | Description |
|---|---|---|
view | number[16] | 4x4 view matrix (row‑major) |
screen_w, screen_h | number | Screen size in pixels |
local_team | integer | Local player's team |
local_aim_punch | { pitch, yaw } | Recoil punch |
entities | array | List of entity tables (players) |
Entity fields
| Field | Type | Description |
|---|---|---|
origin | { x, y, z } | World position |
health | integer | HP |
team | integer | Team id (1..3) |
handle | integer | Pawn handle |
name | string? | Optional readable name |
visible | boolean | LOS flag |
ducked | boolean | Crouched state |
duck_amount | number | 0..1 crouch amount |
is_local | boolean | True if this is the local player |
World‑to‑Screen
world_to_screen(vec | x, y, z) -> { x, y }|nilProjects a world point to screen space using the snapshot view matrix and current screen size. Returns nil if the point is behind the camera or snapshot is unavailable.
local head = { x = pos.x, y = pos.y, z = pos.z + 72 }
local p = world_to_screen(head)
if p then overlay.circle(p.x, p.y, 3, 0xFFEAB308) end
Overlay drawing
All drawing happens either on the background canvas (screen space) or inside the most recent open panel. If you draw without panel_begin, your primitives are placed on the background and are not draggable.
Colors
Any color parameter accepts either:
- Number:
0xAARRGGBB(preferred) or0xRRGGBBAA - Table:
{ r=255, g=255, b=255, a=255 }
Panels
overlay.panel_begin(id, title[, width, height])overlay.panel_end()
Panels are draggable and resizable. Position & size persist per script as settings; passing width, height sets an initial size.
Primitives
overlay.text(x, y, text, color[, size])overlay.line(x1, y1, x2, y2, color[, thickness=1])overlay.rect(x, y, w, h, color[, thickness=1])overlay.rect_filled(x, y, w, h, color)overlay.circle(x, y, r, color[, thickness=1])overlay.circle_filled(x, y, r, color)
overlay.polyline(points, color[, thickness=1[, closed=false]])overlay.triangle(x1,y1,x2,y2,x3,y3,color[, thickness=1])overlay.triangle_filled(x1,y1,x2,y2,x3,y3,color)overlay.poly_filled(points, color)overlay.bezier_cubic(x1,y1,cx1,cy1,cx2,cy2,x2,y2,color[, thickness=1[, segments=0]])
For points, pass an array of {x=.., y=..}.
Engine behavior
overlay.clear()is a no‑op. The engine clears once per frame to allow multiple scripts to draw together.- Panel state is auto‑saved under keys like
panel.<id>.posx,posy,sizex,sizey.
Settings API
Define settings (schema) in Lua, then read/write their values. The host UI renders appropriate controls and persists values per script. When settings change or load, on_settings_applied() is called if present.
Define
settings.define(def)Common fields: id (string, required), label (string), type ("bool" | "int" | "float" | "combo" | "button" | "text" | "color")
| Type | Extra fields |
|---|---|
bool | default (boolean) |
int | default, min, max, step? |
float | default, min, max, step? |
combo | options (array of strings), default_index? (1‑based) |
text | default (string) |
color | default as table {r,g,b,a} |
button | no value; triggers on_button(id) |
Read / write
settings.get(id) -> value|nilsettings.set(id, value)
-- define once (top-level)
settings.define{ id="esp.enabled", label="ESP", type="bool", default=true }
settings.define{ id="esp.color", type="color", default={r=46,g=204,b=113,a=255} }
function on_frame()
if settings.get("esp.enabled") then
local c = settings.get("esp.color")
overlay.text(16, 16, "ESP ON", c)
end
end
Examples
1) Nameplates using snapshot
function on_frame()
for i, e in ipairs(snapshot.get_players()) do
if not e.is_local and e.name then
local p = world_to_screen{ x=e.origin.x, y=e.origin.y, z=e.origin.z + (e.ducked and 54 or 72) }
if p then
overlay.text(p.x - 40, p.y - 8, e.name, e.visible and 0xFF10B981 or 0xFF64748B)
end
end
end
end
2) Draggable mini‑HUD panel
settings.define{ id="hud.show", type="bool", label="HUD", default=true }
function on_frame()
if not settings.get("hud.show") then return end
overlay.panel_begin("hud", "Mini HUD", 220, 90)
local s = snapshot.get()
if s then
overlay.text(12, 12, string.format("Screen: %dx%d", s.screen_w, s.screen_h), 0xFF111827)
overlay.text(12, 34, "Team: "..tostring(s.local_team), 0xFF111827)
end
overlay.panel_end()
end
3) Polyline crosshair (background)
function on_frame()
local s = snapshot.get_screen_size(); if not s then return end
local cx, cy = s.w/2, s.h/2
overlay.polyline({ {x=cx-8,y=cy}, {x=cx+8,y=cy} }, 0xFFE11D48, 2)
overlay.polyline({ {x=cx,y=cy-8}, {x=cx,y=cy+8} }, 0xFFE11D48, 2)
end
Complete Reference
Signatures are stable unless otherwise noted. All functions are safe‑to‑fail and return nil if prerequisites are missing.
Globals
print(...)→ logs to consolemem.read(address, size)→string|nilworld_to_screen(vec|x,y,z)→{x,y}|nil
Modules
sdk: game entities & view matrixsnapshot: frame state & screen sizeoverlay: drawing and panelssettings: user‑configurable values
Error handling
Lua errors inside callbacks are caught and printed to the console. Drawing silently ignores bad inputs (e.g., missing panel, malformed point list).