> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spurdoverse.app/llms.txt
> Use this file to discover all available pages before exploring further.

# ESP

> Per-entity text, bars and icons in the user's ESP builder.

Elements you define show up in the ESP builder, where the user places and toggles them. Your
`evaluate` supplies the value for each entity.

```ts theme={null}
import esp from "@native/esp";
```

<Note>
  `evaluate` runs once per entity every tick, so keep it cheap. You don't draw anything yourself:
  return a value and the builder draws it.
</Note>

## Overview

<CardGroup cols={2}>
  <Card title="Classes" icon="users" href="#classes">
    `esp.class`, `context`.
  </Card>

  <Card title="Elements" icon="layer-group" href="#elements">
    `text`, `bar`, `icon`.
  </Card>

  <Card title="Return values" icon="arrow-right-from-bracket" href="#return-values">
    Text and bar shapes.
  </Card>

  <Card title="Element handles" icon="hand" href="#element-handles">
    `alive`, `enabled`, `preview`, `dispose`.
  </Card>
</CardGroup>

***

## Classes

### class

<br />

```ts theme={null}
esp.class(kind: "enemy" | "team" | "dropped", options?: { context?: ((entity) => Ctx) | null }): EspClass
```

The ESP of one kind of entity. Returns the same object every time for the same kind.

| Kind | Evaluates |
| :- | :- |
| `"enemy"` | Enemy `C_CSPlayerPawn`s, dead ones included. Never the local player. |
| `"team"` | Teammates, same rules. `mp_teammates_are_enemies` moves everyone to `"enemy"`. |
| `"dropped"` | Weapons, grenades and C4 lying in the world. Held weapons are drawn with their player. |

```ts theme={null}
const enemies = esp.class("enemy");
const dropped = esp.class("dropped");
```

`class` is a reserved word, so the named import needs a rename:
`import { class as espClass } from "@native/esp";`.

### context

<br />

```ts theme={null}
cls.context: ((entity) => Ctx) | null
```

Runs once per entity per tick, before the elements. Its result is the `ctx` every `evaluate` of
the class gets. A throw hides all of the class's elements on that entity for the tick. Set it to
`null` to remove it.

```ts theme={null}
const enemies = esp.class("enemy", {
    context: (pawn) => ({ hp: pawn.m_iHealth, name: pawn.controller?.m_iszPlayerName ?? "" }),
});

enemies.text({ name: "name", evaluate: (pawn, ctx) => ctx.name || null });
```

***

## Elements

Every element takes the same definition object.

| Field | |
| :- | :- |
| `name` | Identity within the class and element type. |
| `label` | Label in the builder. Default `name`. |
| `area` | Starting spot: `"top"`, `"bottom"`, `"left"`, `"right"` or `"center"`. The user can drag it elsewhere. |
| `preview` | What the builder preview shows. Same shape as the `evaluate` result. |
| `evaluate(entity, ctx)` | Returns the value for one entity this tick. |

A throw inside `evaluate` hides the element on that entity for the tick and is reported through
the global `error` event.

### text

<br />

```ts theme={null}
cls.text(definition: EspTextDefinition): EspElement
```

A line of text. Return a string or number, a [style object](#text-style), or `null` to hide it.

```ts theme={null}
esp.class("enemy").text({
    name: "hp",
    area: "top",
    preview: "100",
    evaluate: (pawn) => ({ text: pawn.m_iHealth, color: pawn.m_iHealth < 30 ? "#f44" : "#fff" }),
});
```

### bar

<br />

```ts theme={null}
cls.bar(definition: EspBarDefinition): EspElement
```

A bar. Return the fill as `0..1`, a [style object](#bar-style), or `null` to hide it.

```ts theme={null}
esp.class("enemy").bar({
    name: "armor",
    area: "left",
    preview: 1,
    evaluate: (pawn) => ({ value: pawn.m_ArmorValue, max: 100, color: "#48f" }),
});
```

### icon

<br />

```ts theme={null}
cls.icon(definition: EspIconDefinition): EspElement
```

Works like `text`, but always drawn with the `"weapon-icons"` font: the text is the glyph string.

```ts theme={null}
esp.class("dropped").icon({
    name: "weapon",
    area: "top",
    evaluate: (weapon) => weaponGlyph(weapon), // your own weapon → glyph lookup
});
```

***

## Return values

Returned keys override the user's builder settings for that entity and tick. Keys you leave out
keep what the user set.

| Return | `text` / `icon` | `bar` |
| :- | :- | :- |
| `null`, `undefined`, `false` | hidden | hidden |
| string | the text | not allowed |
| number | the text, as `String()` prints it | fill, `0..1` |
| object | [text style](#text-style) | [bar style](#bar-style) |

### Text style

For `text` and `icon`.

| Key | |
| :- | :- |
| `text` | String or number. |
| `color`, `colorAlt` | `ColorLike`. `colorAlt` switches to a gradient. |
| `colorMode` | `"solid"` or `"gradient"`. |
| `size` | Font size in pixels. |
| `font` | Text only: `"segoe"`, `"tahoma"`, `"verdana"`, `"arial"` or `"weapon-icons"`. |
| `outline` | `boolean`. |
| `visible` | `false` hides the element and ignores the other keys. |

### Bar style

| Key | |
| :- | :- |
| `value`, `max` | The bar shows `value / max`, clamped to `0..1`. `max` defaults to `1`. |
| `color`, `colorAlt` | `ColorLike`. `colorAlt` switches to a gradient. |
| `colorMode` | `"solid"`, `"gradient"`, or `"value"` (blends `color` when empty to `colorAlt` when full). |
| `thickness`, `rounding` | Pixels. |
| `divisions` | Number of segments, `0` for one solid bar. |
| `reverse`, `outline` | `boolean`. |
| `outlineThickness` | Pixels. |
| `visible` | `false` hides the element and ignores the other keys. |

***

## Element handles

`text`, `bar` and `icon` return an `EspElement`. Defining the same type and `name` again replaces
the element: the new one keeps the builder slot and the user's layout, the old handle goes dead.

| Member | |
| :- | :- |
| `alive` | `false` after `dispose()`, a replacement or unload. |
| `name`, `type` | `type` is `"text"`, `"bar"` or `"icon"`. |
| `label` | Read or rename in the builder. |
| `enabled` | Your switch, default `true`. `false` hides it everywhere and skips `evaluate`. |
| `enabledByUser` | Whether the user has it switched on in the builder. |
| `preview` | Read or replace. `undefined` removes it. |
| `dispose()` | Removes it from the builder. Also `using`. |

On a dead handle reads return `null` and writes throw. Everything is removed when the script
unloads.

```ts theme={null}
const armor = esp.class("enemy").bar({ name: "armor", evaluate: (pawn) => pawn.m_ArmorValue / 100 });

on("keydown", (e) => {
    if (e.code === "F7") armor.enabled = !armor.enabled;
});
```

***

## Example

Name, health and armor for enemies, ammo on dropped weapons.

```ts theme={null}
import esp from "@native/esp";

const enemies = esp.class("enemy", {
    context: (pawn) => ({ hp: pawn.m_iHealth, name: pawn.controller?.m_iszPlayerName ?? null }),
});

enemies.text({ name: "name", area: "top", preview: "Player", evaluate: (pawn, ctx) => ctx.name });

enemies.bar({
    name: "health",
    area: "left",
    preview: 1,
    evaluate: (pawn, ctx) => ctx.hp > 0 && { value: ctx.hp, max: 100, color: "#ff4040", colorAlt: "#40ff40", colorMode: "value" },
});

enemies.text({
    name: "armor",
    area: "right",
    preview: "100",
    evaluate: (pawn) => pawn.m_ArmorValue > 0 && { text: pawn.m_ArmorValue, color: "#48f" },
});

esp.class("dropped").text({
    name: "ammo",
    area: "bottom",
    preview: "30",
    evaluate: (weapon) => (weapon.m_iClip1 > 0 ? weapon.m_iClip1 : null),
});
```
