Skip to content

Getting Started ​

The TSUKI Deadlock cheat ships with a Lua 5.4 scripting environment for writing your own features. Scripts have access to player data, targeting, drawing, input, the menu UI, direct memory reads, and many more features.

Installing a script ​

Scripts live in:

%APPDATA%\TsukiProject\Deadlock\scripts\

Paste that path into the Run dialog (Win + R) or your File Explorer address bar to open the folder, then drop your .lua file inside.

The scripts folder in File Explorer

Open the cheat menu, click Scripts in the sidebar, then press the Reload Scripts button at the top of the page if your new file doesn't appear yet.

A script's config lives inside %APPDATA%\TsukiProject\Deadlock\scripts\config\. Each script gets its own .json file.

Your first script ​

lua
local greeted = false

function on_tick()
    if local_player():is_alive() and not greeted then
        toast("Hello from Lua!", 3)
        greeted = true
    end
end

Save as hello.lua and enable it in the Lua Scripts section, and you should see a single HUD toast.

Quick Example ​

Here's a Haze script that locks onto an enemy and throws a Sleep Dagger (ability 1) whenever mouse5 is pressed.

lua
-- Haze Auto Dagger
-- Hold mouse5 -> snap to closest enemy -> fire Sleep Dagger

name = "Haze Auto Dagger"
id = hero_id.haze

settings = {
    { key = "fov",        label = "FOV (degrees)",        type = "float", default = 15.0, min = 1.0, max = 30.0 },
    { key = "max_range",  label = "Max Range (m)",        type = "float", default = 30.0, min = 5.0, max = 100.0 },
    { key = "fire_angle", label = "Fire Threshold (deg)", type = "float", default = 1.5,  min = 0.3, max = 5.0 },
}

function on_tick()
    local lp = local_player()
    if not lp or not lp:is_alive() then return end
    if not input.is_key_held(VK.XBUTTON2) then return end
    if not lp:is_ability_ready(slot.ability1) then return end

    local target = targeting.find_closest_by_fov(
        config.get_float("fov"),
        config.get_float("max_range")
    )
    if not target or not target:is_targetable() then return end

    snap_to_target(target, { bone = bone.chest })

    local angle = targeting.get_fov(target, bone.chest)
    if angle and angle < config.get_float("fire_angle") then
        press_ability(slot.ability1)
        toast(string.format("Dagger → %s", target:hero_name() or "?"), 2)
    end
end

on_tick() runs ~250 times per second. It's called every ~4ms by default, the rate at which the cheat reads memory. You can change it under General → Overlay → Reader Rate. Most features of the cheat run on the same tick clock, so 250Hz is a sane default for most things.

Putting id = hero_id.haze at the top means this script only runs when you're on Haze.

A more complete version of this script lives in Haze Auto Dagger. It uses fire_and_hold to keep the snap locked through Haze's throw animation. The dagger doesn't leave her hand the instant you press the key, so if the snap stopped right then, your aim would drift during the windup and the dagger would miss. fire_and_hold holds the snap until the animation finishes.

Where to go next ​

  • Game Keybinds - configure in-game keys that scripts read
  • Script Structure - script lifecycle and event callbacks
  • Globals - top-level functions and namespaces
  • Player - the largest reference page; covers everything on a player
  • Examples - working scripts to learn from

Not affiliated with Valve Corporation.