Menus and HUD drawing
Plugin menu pages
samp.ui.menu.register(page)
Requires ui.menu. Registers or replaces a page with the same ID and returns nothing. Invalid pages or controls are ignored rather than raising in most validation cases.
samp.ui.menu.register({
id = "main",
title = "Example",
controls = {
{ type = "switch", id = "enabled", title = "Enabled", value = true }
}
})| Page field | Type | Rules |
|---|---|---|
id | string | Required, non-empty, at most 64 bytes. |
title | string | Required, non-empty, at most 128 bytes. |
controls | array | At most 32 controls; IDs must be unique on the page. |
A plugin may register at most 8 pages. Every control requires type, id (maximum 64 bytes), and title (maximum 128 bytes).
| Type | Additional fields |
|---|---|
section | No additional fields. |
text | text: string, may be empty, maximum 512 bytes. |
button | No additional fields; activation emits a control change. |
switch | value: boolean, required. |
slider | min=0, max=1, step=0.1, value=min; all finite, magnitude at most 1,000,000, with max > min and step > 0; value is clamped. |
choice | value: string; options contains 1–32 unique { value, label }; value must match an option; values up to 512 bytes, labels up to 128. |
text_input | value="", placeholder="", max_length=512; maximum length is an integer 1..512, and value must fit. |
Changes emit ui.control_changed with pluginId, pageId, controlId, and a typed value. See Event payloads.
HUD phase
All samp.draw functions require ui.draw and may only be called synchronously inside draw.hud. They queue at most 512 draw commands per plugin per frame. They return nothing, except world_to_screen.
Colors are ARGB integers: 0xAARRGGBB. When normalized=true, coordinates use the 0..1 display range; otherwise they are screen coordinates. General coordinates must be finite with magnitude at most 100,000.
samp.draw.text(options)
| Field | Default | Rules |
|---|---|---|
x, y | 0 | Coordinates. |
text | — | Required string, maximum 1,024 bytes. |
size | 16 | Finite, > 0 and <= 512. |
color | 0xFFFFFFFF | ARGB. |
normalized | false | Boolean. |
samp.draw.line(options)
Fields: x1=0, y1=0, x2=0, y2=0, color=0xFFFFFFFF, thickness=1 (>0..100), and normalized=false.
samp.draw.rect(options)
Same as line, plus filled=false. thickness remains required to be valid even for a filled rectangle.
samp.draw.circle(options)
Fields: x=0, y=0, radius=1, color=0xFFFFFFFF, filled=false, thickness=1 (>0..100), and normalized=false. Radius must be positive and at most 100,000; in normalized mode it must be at most 1.
samp.draw.progress_bar(options)
Fields: x1=0, y1=0, x2=0, y2=0, value=0, color=0xFFFFFFFF, background_color=0x66000000, and normalized=false. x2 > x1, y2 > y1, and value is in 0..1.
samp.draw.image(options)
| Field | Default | Rules |
|---|---|---|
x1, y1, x2, y2 | 0 | x2 > x1, y2 > y1. |
resource | — | Required safe package-relative image path, maximum 256 bytes. |
alpha | 1 | Finite 0..1. |
normalized | false | Boolean. |
Supported formats are PNG, WebP, JPEG, and JPG. A source file is at most 16 MiB; decoded dimensions are at most 1024×1024. Each plugin may cache 16 images and 16 MiB of decoded image data; the runtime-wide decoded budget is 64 MiB. At most one previously uncached image begins loading per frame.
samp.draw.world_to_screen(position)
Accepts Vector3. Returns nil when the game is unavailable or the point cannot be projected in front of the camera. Otherwise returns:
{
x = number,
y = number,
depth = number,
width = number,
height = number
}