# Vector Lua Engine

The Vector Lua Engine lets you write scripts that run inside the cheat. Scripts can read game state, draw to the screen, add menu elements, and run background tasks — all through a safe, sandboxed Lua 5.1 environment.

***

### Naming convention

Every function in the API is registered under three naming styles simultaneously. You can use whichever you prefer — just stay consistent within a script.

| Style        | Example                |
| ------------ | ---------------------- |
| `snake_case` | `entity.get_players()` |
| `camelCase`  | `entity.getPlayers()`  |
| `PascalCase` | `entity.GetPlayers()`  |

All examples in this documentation use `snake_case`.

***

### Callbacks

Scripts respond to engine events by defining global functions. The engine calls them automatically.

#### on\_frame

Called every render frame. All drawing must happen here.

```lua
function on_frame()
    draw.text(10, 10, "script running", {1, 1, 1, 1})
end
```

#### on\_player\_added

Called when a player joins the game.

```lua
function on_player_added(player)
    print(player.name .. " joined")
end
```

#### on\_player\_removed

Called when a player leaves the game.

```lua
function on_player_removed(player)
    print(player.name .. " left")
end
```

***

### Available globals

| Global    | Description                                      |
| --------- | ------------------------------------------------ |
| `draw`    | 2D rendering — lines, boxes, text, circles       |
| `entity`  | Player list, local player, player properties     |
| `game`    | DataModel, instances, camera, input, parts       |
| `camera`  | Camera position, look vector, FOV                |
| `input`   | Key state, mouse position, mouse movement        |
| `part`    | Write part properties (position, size, velocity) |
| `menu`    | Add UI elements, read/write values               |
| `thread`  | Background timer-based callbacks                 |
| `utility` | Screen projection, delta time, FPS, tick count   |
| `Vector3` | 3D vector constructor                            |
| `print`   | Logs to the script console                       |

***

### Minimal working script

```lua
-- Setup menu elements once at script load
menu.add_tab("My Script", "M")
menu.add_group("My Script", "General")
menu.add_checkbox("My Script", "General", "enabled", "Enable", true)

-- on_frame runs every render frame
function on_frame()
    if not menu.get("enabled") then return end

    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 b = p:get_bounds()
        if not b.valid then goto continue end

        draw.box(b.x, b.y, b.w, b.h, {1, 1, 1, 1})
        draw.health_bar(b.x - 5, b.y, b.h, p.health, p.max_health)
        draw.text(b.x, b.y - 16, p.name, {1, 1, 1, 1})

        ::continue::
    end
end
```

***

### Environment

The engine opens a restricted subset of the Lua 5.1 standard library:

| Available                                                | Removed                              |
| -------------------------------------------------------- | ------------------------------------ |
| `table`, `string`, `math`, `bit`, `os`, `io, loadstring` | `loadfile`, `dofile`, `load`         |
| `os.time`, `os.date`, `os.clock`                         | `os.execute`, `os.exit`, `os.remove` |
| `io.open`, `io.read`, `io.write`                         | `io.popen`                           |
| `tostring`, `tonumber`, `type`, `pairs`, `ipairs`        | `string.dump`, `collectgarbage`      |

***

### Script lifecycle

```
Script loaded
    └─ Top-level code runs once
        └─ Menu elements registered
        └─ Threads created (if any)
        └─ Callbacks defined

Every frame
    └─ on_frame() called (if defined)

Player joins
    └─ on_player_added(player) called (if defined)

Player leaves
    └─ on_player_removed(player) called (if defined)

Script unloaded
    └─ All threads stopped automatically
    └─ Menu elements cleared
```

***

### Tips

* Register menu elements at the top level of your script, outside `on_frame`. They only need to be created once.
* Create threads at the top level or with a nil-guard inside `on_frame`. Never call `thread.create` unconditionally inside `on_frame` — it runs every frame.
* Use `utility.get_delta_time()` for any time-based animation or movement so it stays frame-rate independent.
* Use `:get_bounds()` for box ESP. Use `:get_bone_screen()` for specific bone positions. Use `:get_bones_screen()` when you need multiple bones — it batches the reads.
* `p.health`, `p.position`, and `p.head_position` are live memory reads. Cache them into locals if you read them more than once per frame.

```lua
-- good: read once, use multiple times
local hp     = p.health
local max_hp = p.max_health
local ratio  = hp / max_hp
draw.health_bar(b.x - 5, b.y, b.h, hp, max_hp)
draw.text(b.x, b.y - 16, math.floor(hp) .. " / " .. math.floor(max_hp), {1,1,1,1})
```


---

# 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/introduction/vector-lua-engine.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.
