# Utility API

## Utility API

General-purpose utilities for screen projection, frame timing, cursor position, FPS, key events, input simulation, and HTTP.

> All examples use `snake_case`. Every function is also accessible in `camelCase` and `PascalCase` — the engine accepts all three. Pick one and stay consistent in your scripts.

***

### utility.world\_to\_screen

```lua
local sx, sy, on_screen = utility.world_to_screen(x, y, z)
-- also accepts a Vector3
local sx, sy, on_screen = utility.world_to_screen(vec3)
```

Projects a 3D world position to 2D screen coordinates using the current view matrix. Unlike `draw.world_to_screen`, this version returns `on_screen = true` only when the projected point falls inside the screen bounds — not just in front of the camera.

```lua
local sx, sy, on_screen = utility.world_to_screen(100, 5, 200)
if on_screen then
    draw.circle_filled(sx, sy, 4, {0, 1, 0, 1})
end
```

```lua
local v = Vector3.new(100, 5, 200)
local sx, sy, on_screen = utility.world_to_screen(v)
```

***

### utility.get\_screen\_size

```lua
local w, h = utility.get_screen_size()
```

Returns the current render resolution in pixels.

```lua
local w, h = utility.get_screen_size()
local cx, cy = w / 2, h / 2
```

***

### utility.get\_mouse\_pos

```lua
local mx, my = utility.get_mouse_pos()
```

Returns the current cursor position in screen space using `GetCursorPos`.

```lua
function on_frame()
    local mx, my = utility.get_mouse_pos()
    draw.text(mx + 12, my, "cursor", {1, 1, 1, 1})
end
```

***

### utility.get\_delta\_time

```lua
local dt = utility.get_delta_time()
```

Returns seconds elapsed since the last frame, clamped to \[0.0001, 0.1]. Use this to make any movement or animation frame-rate independent:

```lua
local x = 0
local speed = 200  -- pixels per second

function on_frame()
    local dt = utility.get_delta_time()
    x = x + speed * dt

    local w, h = utility.get_screen_size()
    if x > w then x = 0 end

    draw.circle_filled(x, 100, 5, {0, 1, 1, 1})
end
```

***

### utility.get\_time

```lua
local seconds = utility.get_time()
```

Returns seconds elapsed since the engine started as a high-precision float. Uses `steady_clock` so the value is monotonic and never jumps. Useful for timed logic, cooldowns, and animation timing without dealing with millisecond conversions.

```lua
local last_check = 0

function on_frame()
    local now = utility.get_time()
    if now - last_check < 1.0 then return end
    last_check = now

    print("one second passed")
end
```

***

### utility.get\_tick\_count

```lua
local ms = utility.get_tick_count()
```

Returns `GetTickCount64()` — milliseconds elapsed since system boot. Useful for cooldowns and timed logic.

```lua
local last_action = 0
local cooldown_ms = 500

function on_frame()
    local now = utility.get_tick_count()

    if input.is_key_down(0x46) then  -- F key
        if now - last_action > cooldown_ms then
            print("action fired")
            last_action = now
        end
    end
end
```

***

### utility.get\_fps

```lua
local fps = utility.get_fps()
```

Returns a smoothed FPS value averaged over the last 60 frames.

```lua
function on_frame()
    local fps = utility.get_fps()
    draw.text(10, 10, "FPS: " .. math.floor(fps), {0.6, 1, 0.6, 1})
end
```

***

### utility.is\_valid

```lua
local valid = utility.is_valid(instance)
```

Returns `true` if the given instance userdata still points to a valid Roblox object in memory. Checks the class descriptor, name pointer, and parent to confirm the object has not been destroyed or garbage collected. Use this before accessing properties on instances that may have been removed from the game tree.

```lua
local char = player.character
if utility.is_valid(char) then
    local pos = char.Position
    print(pos.x, pos.y, pos.z)
end
```

***

### utility.on\_key

```lua
local id = utility.on_key(vk_code, mode, callback)
```

Registers a key binding that fires automatically every frame — no manual `input.is_key_down` polling needed. Returns a numeric `id` you can pass to `utility.remove_key` to unregister later.

**Modes:**

```lua
-- Toggle an ESP feature on/off with F
local esp_on = false
local esp_id = utility.on_key(0x46, "toggle", function(state)
    esp_on = state
    print("ESP: " .. (state and "ON" or "OFF"))
end)

-- React to hold/release of G
utility.on_key(0x47, "hold", function(state)
    if state then
        print("G held — activating")
    else
        print("G released")
    end
end)

-- Draw an indicator every frame while RMB is held
utility.on_key(0x02, "always", function(state)
    if state then
        draw.text(10, 10, "ADS ACTIVE", {0, 1, 0, 1}, 14)
    end
end)
```

***

### utility.remove\_key

```lua
utility.remove_key(id)
```

Unregisters one binding by the `id` returned from `utility.on_key`.

```lua
local my_id = utility.on_key(0x46, "toggle", function(state) end)
-- later...
utility.remove_key(my_id)
```

***

### utility.clear\_keys

```lua
utility.clear_keys()
```

Removes all registered key bindings at once.

***

### utility.is\_key\_toggled

```lua
local state = utility.is_key_toggled(id)
```

Returns the current toggle state (`true`/`false`) for a `"toggle"` mode binding. Returns `false` for other modes or an unknown id.

```lua
local id = utility.on_key(0x46, "toggle", function(state) end)

function on_frame()
    if utility.is_key_toggled(id) then
        draw.text(10, 10, "FEATURE ON", {0, 1, 0, 1}, 14)
    end
end
```

***

> **Important:** All input simulation functions send real OS-level input via `SendInput`. While the menu is open it captures input focus, so simulated clicks and key presses will be absorbed by the overlay instead of reaching the game. Close the menu before using these functions. In practice this means input simulation should run inside `on_frame` guarded by a toggle key or condition, not as a one-shot at script load time.

### utility.mouse\_click

```lua
utility.mouse_click(button?, x?, y?)
```

Simulates a full mouse click (down + up) via `SendInput`. Sends real input events that the game receives as genuine clicks.

* `button` — `"left"` (default), `"right"`, or `"middle"`
* `x, y` — optional screen coordinates to move the cursor to before clicking

```lua
-- left click at current cursor position
utility.mouse_click()

-- right click at a specific screen position
utility.mouse_click("right", 500, 300)

-- middle click
utility.mouse_click("middle")
```

***

### utility.mouse\_move

```lua
utility.mouse_move(x, y, absolute?)
```

Moves the mouse cursor via `SendInput`. By default the movement is relative (pixels from current position). Pass `true` as the third argument for absolute screen coordinates.

```lua
-- move 10 pixels right, 5 pixels down from current position
utility.mouse_move(10, 5)

-- move cursor to absolute screen position
utility.mouse_move(960, 540, true)
```

***

### utility.mouse\_scroll

```lua
utility.mouse_scroll(amount)
```

Simulates a mouse scroll wheel event. Positive values scroll up, negative values scroll down. One unit equals one "click" of the scroll wheel.

```lua
-- scroll up 3 clicks
utility.mouse_scroll(3)

-- scroll down 1 click
utility.mouse_scroll(-1)
```

***

### utility.key\_press

```lua
utility.key_press(vk_code, hold_ms?)
```

Simulates a full key press — sends key down, holds for `hold_ms` milliseconds (default `30`, about 2 frames at 60fps), then sends key up. The overlay stays responsive during the hold. Uses Windows virtual key codes.

```lua
-- press the spacebar (held for 30ms by default)
utility.key_press(0x20)

-- press W and hold for 200ms before releasing
utility.key_press(0x57, 200)
```

***

### utility.key\_down

```lua
utility.key_down(vk_code)
```

Sends a key down event only. The key stays held until you call `utility.key_up` with the same key code.

```lua
-- hold W down
utility.key_down(0x57)
-- ... later ...
utility.key_up(0x57)
```

***

### utility.key\_up

```lua
utility.key_up(vk_code)
```

Sends a key up event only. Use after `utility.key_down` to release a held key.

***

### utility.type\_string

```lua
utility.type_string(text, delay_ms?)
```

Types a string character by character using unicode input events. Works with any character including special symbols and non-ASCII text. Each character sends a down + up event with a small delay between characters so the target application registers each one.

* `delay_ms` — milliseconds between each character (default `5`). Set higher if characters are being dropped.

```lua
-- type into a chat box or text field
utility.type_string("hello world")

-- slower typing for applications that need more time
utility.type_string("gg ez", 15)
```

***

### utility.http\_get

```lua
local body, status = utility.http_get(url)
-- on failure:
-- body == nil, status == error string
```

Performs an HTTP/HTTPS GET and returns the response body as a string plus the HTTP status code. The UI stays responsive during the request — the Lua mutex is released while the network call is in progress.

```lua
local body, status = utility.http_get("https://pastebin.com/raw/AbCdEfGh")
if body and status == 200 then
    local fn, err = loadstring(body)
    if fn then fn() else print("compile error: " .. err) end
else
    print("fetch failed: " .. tostring(status))
end
```

***

### utility.load\_url

```lua
local ok, err = utility.load_url(url)
```

Fetches Lua source from a URL and executes it in the current state. Equivalent to `loadstring(http_get(url))()` with full error handling. Globals and functions defined in the remote script are immediately available after this returns. Returns `true` on success, or `false, error_message` on network failure, non-200 status, compile error, or runtime error.

```lua
-- One-liner — load and run a remote script
utility.load_url("https://pastebin.com/raw/AbCdEfGh")

-- With error handling
local ok, err = utility.load_url("https://pastebin.com/raw/AbCdEfGh")
if not ok then
    print("load_url failed: " .. tostring(err))
end
```

***

### Examples

HUD overlay — delta time animation + FPS counter:

```lua
local angle = 0

function on_frame()
    local dt  = utility.get_delta_time()
    local fps = utility.get_fps()
    local w, h = utility.get_screen_size()

    angle = angle + dt * 90
    if angle > 360 then angle = angle - 360 end

    local r = 40
    local cx, cy = 60, h - 60
    local rad = math.rad(angle)
    local px = cx + math.cos(rad) * r
    local py = cy + math.sin(rad) * r

    draw.circle(cx, cy, r, {1, 1, 1, 0.2})
    draw.circle_filled(px, py, 5, {0, 1, 1, 1})
    draw.text(10, 10, "FPS: " .. math.floor(fps), {0.6, 1, 0.6, 1})
end
```

Distance-based ESP with world\_to\_screen:

```lua
function on_frame()
    local players = entity.get_players()

    for _, p in ipairs(players) do
        if p.is_local or not p.is_alive then goto continue end

        local me = entity.get_local_player()
        if not me then goto continue end

        local dx = p.position.x - me.position.x
        local dy = p.position.y - me.position.y
        local dz = p.position.z - me.position.z
        local dist = math.sqrt(dx*dx + dy*dy + dz*dz)

        if dist > 500 then goto continue end

        local sx, sy, on_screen = utility.world_to_screen(
            p.head_position.x,
            p.head_position.y,
            p.head_position.z
        )
        if on_screen then
            local label = p.name .. " [" .. math.floor(dist) .. "m]"
            draw.text(sx, sy - 16, label, {1, 1, 1, 1})
        end

        ::continue::
    end
end
```

Toggle ESP with F key:

```lua
local esp_on = false

utility.on_key(0x46, "toggle", function(state)
    esp_on = state
    print("ESP: " .. (state and "ON" or "OFF"))
end)

function on_frame()
    if not esp_on then return end

    for _, p in ipairs(entity.get_players()) do
        if p.is_local or not p.is_alive then goto continue end
        local b = p:get_bounds()
        if b.valid then
            draw.box(b.x, b.y, b.w, b.h, {1, 1, 1, 1})
        end
        ::continue::
    end
end
```

Auto-jump with input simulation — toggle with H key, only runs while menu is closed:

```lua
local jumping = false

utility.on_key(0x48, "toggle", function(state)
    jumping = state
    print("Auto-jump: " .. (state and "ON" or "OFF"))
end)

function on_frame()
    if not jumping then return end

    local me = entity.get_local_player()
    if not me or not me.is_alive then return end

    local now = utility.get_time()
    if not _last_jump or now - _last_jump > 2.0 then
        utility.key_press(0x20)
        _last_jump = now
    end
end
```

Automated typing into chat — triggered by pressing F9:

```lua
utility.on_key(0x78, "hold", function(state)
    if not state then return end

    -- press / to open chat, hold for 100ms so the chat box opens
    utility.key_press(0xBF, 100)

    -- type the message with 10ms between each character
    utility.type_string("gg", 10)

    -- press Enter to send, hold briefly so it registers
    utility.key_press(0x0D, 50)
end)
```

Hold W to walk forward while X is held:

```lua
utility.on_key(0x58, "hold", function(state)
    if state then
        utility.key_down(0x57)   -- hold W
    else
        utility.key_up(0x57)     -- release W
    end
end)
```

Load a remote script on startup:

```lua
local ok, err = utility.load_url("https://pastebin.com/raw/AbCdEfGh")
if not ok then print("load_url failed: " .. tostring(err)) end
```

***

### API Reference

| Function                            | Description                               |
| ----------------------------------- | ----------------------------------------- |
| `utility.world_to_screen(x, y, z)`  | Project world position to screen          |
| `utility.get_screen_size()`         | Get render resolution                     |
| `utility.get_mouse_pos()`           | Get cursor position                       |
| `utility.get_delta_time()`          | Seconds since last frame                  |
| `utility.get_time()`                | Seconds since engine start                |
| `utility.get_tick_count()`          | System uptime in milliseconds             |
| `utility.get_fps()`                 | Smoothed FPS value                        |
| `utility.is_valid(instance)`        | Check if instance is still valid          |
| `utility.on_key(vk, mode, fn)`      | Register a key binding                    |
| `utility.remove_key(id)`            | Remove a key binding                      |
| `utility.clear_keys()`              | Remove all key bindings                   |
| `utility.is_key_toggled(id)`        | Get toggle state of a binding             |
| `utility.mouse_click(btn?, x?, y?)` | Simulate a mouse click                    |
| `utility.mouse_move(x, y, abs?)`    | Move the cursor                           |
| `utility.mouse_scroll(amount)`      | Simulate scroll wheel                     |
| `utility.key_press(vk, ms?)`        | Press and release a key (instant or held) |
| `utility.key_down(vk)`              | Hold a key down                           |
| `utility.key_up(vk)`                | Release a held key                        |
| `utility.type_string(text, ms?)`    | Type a string character by character      |
| `utility.http_get(url)`             | HTTP GET request                          |
| `utility.load_url(url)`             | Fetch and execute remote Lua              |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://project-vector-1.gitbook.io/vector-lua-engine/api/utility-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
