Internal API Reference
Most of the Lua API is served by TSUKI itself and works in every script. The functions in this section are served by the internal, an optional component that has to be running. When it is not running they return nil and your script keeps going.
To use them, add needs_internal = true to your script_info:
script_info = {
name = "my_script",
needs_internal = true,
}Everything else in the API keeps working as before. The flag only adds.
What the flag gates
Without needs_internal = true these return nil and write one line to C:\TSUKI\Deadlock\logs\tsuki.log naming the script and the function (once per function, not once per call):
p:get_stats()p:get_ability_value(slot, name)p:get_hit_events([since_seq])p:get_hit_stats()p:get_property(name)entities.row:get(name)trace.line(from, to [, opts])trace.get(id)hud.class_count(name)
The script still loads, shows in the menu and ticks. Nothing errors. The log line does not reach the in-app console, so a missing flag looks like a function that returns nil forever.
aim.* needs the internal running but does not check the flag. Declare it anyway if you use them.
Is the internal running
| Function | Returns |
|---|---|
internal.is_loaded() | true when the internal is present |
internal.is_alive() | true when it is present and responding (its heartbeat moved in the last second) |
internal.version() | Build number, 0 when nothing is loaded |
Any script can call these. Gate on is_alive before trusting numbers; is_loaded stays true for a component that is present but stuck.
function on_tick()
local me = local_player()
if not me or not me:is_alive() or not internal.is_loaded() then return end
-- ...
endOr fall back instead of stopping:
local dmg = fallback
if internal.is_loaded() then
local st = me:get_stats()
if st and st.bullet_damage and st.bullet_damage > 0 then dmg = st.bullet_damage end
endWhen a call returns nil
Every feed returns nil rather than a placeholder. Never 0, never a table of zeros. Check in this order:
internal.is_alive()is false.needs_internal = trueis missing fromscript_info. Look for the line intsuki.log.- Nothing asked recently. The stat feed only runs while some script called
p:get_stats()in the last 2 seconds. The ability value, property and trace feeds only work on names you have asked for. - A cap is full: 24 ability value pairs, 32 property pairs, 32 traces, shared by every loaded script.
- It is the first call for a new request. The first call registers it and returns
nil; the value lands on a later tick.
aim.silent and aim.shoot return false instead of nil when the internal is absent.
Refresh rates
| Feed | Refresh |
|---|---|
| Stats | 100 ms |
| Ability values | 250 ms |
| Entity properties | 250 ms |
| Traces | 50 ms |
| Hit events | On each hit |
Checking a name from a script
tsuki.api() returns every registered name with its host (external or internal) and needs_internal flag. tsuki.api_info(name) returns one entry or nil. The name must match exactly, prefix included: "p:get_stats", not "get_stats".
local i = tsuki.api_info("p:get_stats")
-- i.host = "internal", i.needs_internal = truePages
| Page | Covers |
|---|---|
| Stats | p:get_stats(): resolved resists, shields, barrier, and your own weapon numbers |
| Ability Values | p:get_ability_value(slot, name): the resolved number the tooltip shows |
| Hit Events | p:get_hit_events() and p:get_hit_stats(): per hit damage events and a running tally |
| Entity Properties | p:get_property(name) and row:get(name): read a game field by name |
| Traces | trace.line() and trace.get(): what a line hits |
| Aim | aim.silent, aim.shoot, aim.can_reach, aim.get_solution, aim.diag |
| HUD | hud.class_count(name): how many interface panels carry a class, for reading the game's own cast indicator |
Everything else is in the API Reference.