rawframe.api_version ()
Returns the current Lua API version number.
Returns
number — API version.
Example
local v = rawframe.api_version()
print("API v" .. tostring(v)) Explore and test Rawframe's Lua API functions across all namespaces.
Returns the current Lua API version number.
number — API version.
local v = rawframe.api_version()
print("API v" .. tostring(v)) Returns the engine version string.
string — Engine version (e.g. "0.25.0").
print("Engine: " .. rawframe.engine_version()) Writes a message to the engine log output.
| Name | Type | Description |
|---|---|---|
| message | string | Message to log. |
void
rawframe.log("Hello from Lua!") Returns true if running on the server.
boolean
if rawframe.is_server() then
print("Server-side code")
end Returns true if running on the client.
boolean
if rawframe.is_client() then
print("Client-side code")
end Registers a callback that fires when the mod is hot-reloaded.
| Name | Type | Description |
|---|---|---|
| callback | function | Called on hot-reload. |
void
rawframe.on_reload(function()
print("Mod reloaded!")
end) Spawns a new entity in the world from a prefab path or a template table. Returns the entity handle on success.
| Name | Type | Description |
|---|---|---|
| prefab | string | Path to a prefab asset or a registered prefab name. |
| position | Vec3? | World position to spawn the entity. Defaults to origin. |
| rotation | Quat? | Initial rotation. Defaults to identity. |
entity — The spawned entity handle, or nil on failure.
-- Spawn a crate at a specific position
local pos = Vec3.new(10, 0, 5)
local crate = entity.create("props/crate", pos)
if crate then
print("Spawned entity:", crate)
end Returns the first entity with the given name, or nil if not found.
| Name | Type | Description |
|---|---|---|
| name | string | The entity name to search for. |
entity? — Matching entity or nil.
local flag = entity.find("CaptureFlag_Blue")
if flag then
entity.set_position(flag, Vec3.new(0, 1, 50))
end Destroys an entity and all of its children. The entity handle becomes invalid after this call.
| Name | Type | Description |
|---|---|---|
| entity | entity | The entity handle to destroy. |
void
-- Destroy an entity after a delay
local box = entity.create("props/box", Vec3.new(0, 1, 0))
timer.delay(5.0, function()
entity.destroy(box)
print("Box destroyed.")
end) Creates a deep copy of an entity including all components and children.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to clone. |
entity
local copy = entity.clone(original_ent) Teleports an entity to a given world-space position. Physics body is updated synchronously.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| position | Vec3 | New world-space position. |
void
-- Teleport player to spawn
local player = game.get_player(1)
local spawn = Vec3.new(0, 5, 0)
entity.set_position(player, spawn) Returns the current world-space position of an entity as a Vec3.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
Vec3 — World position, or nil if the entity is invalid.
local player = game.get_player(1)
local pos = entity.get_position(player)
print(string.format("Player at %.1f, %.1f, %.1f", pos.x, pos.y, pos.z)) Sets the world-space rotation of an entity. Physics body orientation is updated synchronously.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| rotation | Quat | New world-space rotation quaternion. |
void
-- Face a prop north (+Z direction)
local rot = Quat.from_axis_angle(Vec3.new(0, 1, 0), 0)
entity.set_rotation(prop, rot) Sets the entity rotation using a quaternion (x, y, z, w).
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The rotation quat value. |
void
entity.set_rotation_quat(ent, 0, 0.707, 0, 0.707) Returns the current world-space rotation of an entity as a Quat.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
Quat — World rotation quaternion, or nil if the entity is invalid.
local rot = entity.get_rotation(vehicle)
local forward = Vec3.rotate(Vec3.new(0, 0, 1), rot)
print("Vehicle forward:", forward) Sets the local scale of an entity. Does not affect physics body dimensions — use physics.create_body to define the collision shape.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| scale | Vec3 | New local scale vector. |
void
-- Double the size of a collectible
entity.set_scale(pickup, Vec3.new(2, 2, 2)) Returns the local scale of an entity as a Vec3.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
Vec3 — Local scale vector.
local scale = entity.get_scale(entity)
print("Scale:", scale.x, scale.y, scale.z) Sets the mesh component of an entity to a previously loaded mesh.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The mesh value. |
void
entity.set_mesh(ent, "models/barrel.gltf") Sets a skinned (animated) mesh on the entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The skinned mesh value. |
void
entity.set_skinned_mesh(ent, "models/character.gltf") Loads a 3D mesh asset and assigns it to the entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| path | string | Path to the mesh asset. |
void
entity.load_mesh(ent, "models/crate.gltf") Loads a texture asset and applies it to the entity material.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| path | string | Path to the texture asset. |
void
entity.load_texture(ent, "textures/wood.ktx2") Attaches a string tag to an entity. Tags are used to categorise entities for queries and hook filtering.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| tag | string | Tag string to attach. |
void
entity.set_tag(chest, "lootable")
entity.set_tag(chest, "interactable") Removes a previously added tag from an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| tag | string | Tag string to remove. |
void
-- Mark chest as looted
entity.remove_tag(chest, "lootable") Returns whether an entity currently has a specific tag attached.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| tag | string | Tag string to check. |
bool — True if the entity has the tag.
if entity.has_tag(entity, "enemy") then
character.damage(entity, 10, "fire")
end Returns a table of all entities that currently have a given tag. Efficient ECS query — safe to call each tick.
| Name | Type | Description |
|---|---|---|
| tag | string | Tag to search for. |
table — Array of matching entity handles.
local enemies = entity.find_by_tag("enemy")
print(#enemies, "enemies alive") Parents one entity to another, making the child inherit the parent's transform. Pass nil to detach from any parent.
| Name | Type | Description |
|---|---|---|
| child | entity | Entity to reparent. |
| parent | entity | nil | New parent entity, or nil to detach. |
void
-- Attach a hat to a player's head bone
local hat = entity.create("items/hat")
entity.set_parent(hat, player) Returns the parent entity of a child entity, or nil if it has no parent.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
entity? — The parent entity, or nil.
local parent = entity.get_parent(wheel)
if parent then
print("Wheel belongs to vehicle:", parent)
end Returns a table of all direct child entities of the given entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
table — Array of child entity handles.
local children = entity.get_children(vehicle)
for _, child in ipairs(children) do
print("Child:", child)
end Sets the debug name of an entity. Useful for logging and editor identification.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| name | string | New name string. |
void
local boss = entity.create("enemies/boss")
entity.set_name(boss, "FinalBoss_Arena1") Returns the debug name of an entity as a string.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
string — The entity name, or an empty string.
print("Entity name:", entity.get_name(entity)) Sets the render layer of an entity for visibility filtering.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The layer value. |
void
entity.set_layer(ent, value) Returns the render layer of an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
any
local val = entity.get_layer(ent) Assigns LOD (level-of-detail) distances to an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The lod group value. |
void
entity.set_lod_group(ent, { 25, 50, 100 }) Returns the current LOD level of an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
any
local lod = entity.get_lod_level(ent) Removes LOD group from an entity.
void
entity.remove_lod_group(ent) Shows or hides an entity. Hidden entities are not rendered but still participate in physics and logic.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| visible | bool | True to show, false to hide. |
void
-- Hide a pickup until a player is nearby
entity.set_visible(gem, false)
timer.delay(2.0, function()
entity.set_visible(gem, true)
end) Returns whether an entity is currently visible in the scene.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
bool — True if visible, false if hidden.
if not entity.is_visible(trap) then
entity.set_visible(trap, true)
end Sets the color.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The color value. |
void
entity.set_color(ent, value) Returns the color.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
any
local val = entity.get_color(ent) Sets the opacity/transparency of an entity (0.0-1.0).
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The opacity value. |
void
entity.set_opacity(ent, 0.5) Freezes or unfreezes an entity, preventing physics simulation.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity handle. |
| value | any | The frozen value. |
void
entity.set_frozen(ent, true) Returns all entities whose position is within a given radius of a world point.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | World-space center of the sphere. |
| radius | number | Search radius in metres. |
| tag | string? | Optional tag filter. |
table — Array of entity handles inside the sphere.
local nearby = entity.find_in_sphere(pos, 10, "enemy")
for _, e in ipairs(nearby) do
character.damage(e, 50, "explosion")
end Returns all entities whose position falls within an axis-aligned bounding box.
| Name | Type | Description |
|---|---|---|
| min | Vec3 | Minimum corner of the AABB. |
| max | Vec3 | Maximum corner of the AABB. |
| tag | string? | Optional tag filter. |
table — Array of entity handles inside the box.
local in_zone = entity.find_in_box(Vec3.new(-5,0,-5), Vec3.new(5,10,5))
print(#in_zone, "entities in zone") Returns entities within a cone defined by an origin, direction, range, and half-angle.
| Name | Type | Description |
|---|---|---|
| origin | Vec3 | Cone apex position. |
| direction | Vec3 | Normalised forward direction of the cone. |
| range | number | Maximum distance along the cone axis. |
| half_angle | number | Half-angle of the cone in degrees. |
table — Entities within the cone.
local seen = entity.find_in_cone(origin, forward, 20, 45)
for _, e in ipairs(seen) do print("In view:", e) end Returns the single closest entity to a world point, optionally filtered by tag.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | Query position. |
| tag | string? | Optional tag filter. |
entity? — The nearest entity, or nil if none exist.
local nearest_enemy = entity.find_nearest(pos, "enemy")
if nearest_enemy then
npc.follow(bot, nearest_enemy)
end Returns all entities that have been assigned the given class string.
| Name | Type | Description |
|---|---|---|
| class | string | Class name to query. |
table — Array of matching entity handles.
local pickups = entity.find_by_class("Pickup")
print(#pickups, "pickups remaining") Returns the number of entities within a sphere without allocating a results table.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | Sphere centre. |
| radius | number | Radius in metres. |
| tag | string? | Optional tag filter. |
number — Count of entities inside the sphere.
local n = entity.get_count_in_sphere(pos, 5, "enemy")
if n > 3 then trigger_alert() end Stores an arbitrary key-value attribute on an entity. Values can be number, string, or boolean.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| key | string | Attribute key. |
| value | number | string | boolean | Value to store. |
void
entity.set_attribute(chest, "loot_tier", 3)
entity.set_attribute(chest, "opened", false) Retrieves a stored attribute value from an entity by key.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| key | string | Attribute key. |
any — The stored value, or nil if the key does not exist.
local tier = entity.get_attribute(chest, "loot_tier")
print("Tier:", tier) Returns a shallow copy of all attributes set on an entity as a key-value table.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
table — All attribute key-value pairs.
local attrs = entity.get_attributes(chest)
for k, v in pairs(attrs) do print(k, v) end Removes a previously stored attribute from an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| key | string | Attribute key to remove. |
void
entity.remove_attribute(chest, "loot_tier") Registers a callback that fires whenever a specific attribute on an entity is changed.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| key | string | Attribute key to watch. |
| callback | function | Called with (entity, key, new_value, old_value). |
void
entity.on_attribute_changed(door, "locked", function(e, k, new, old)
print("Door lock changed:", old, "->", new)
end) Returns all descendant entities (children, grandchildren, etc.) of an entity recursively.
| Name | Type | Description |
|---|---|---|
| entity | entity | Root entity. |
table — Flat array of all descendant entity handles.
local parts = entity.get_descendants(vehicle)
for _, p in ipairs(parts) do print("Part:", entity.get_name(p)) end Assigns a class string to an entity. Classes group entities for find_by_class queries.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| class | string | Class name to assign. |
void
entity.set_class(pickup, "Pickup") Returns the class string of an entity, or nil if none is set.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
string? — Class name or nil.
print("Class:", entity.get_class(e)) Returns all entities whose name matches the given string. Unlike entity.find, returns every match.
| Name | Type | Description |
|---|---|---|
| name | string | Name to search for. |
table — Array of matching entity handles.
local checkpoints = entity.find_by_name("Checkpoint")
print(#checkpoints, "checkpoints found") Returns the total number of alive entities in the world, optionally filtered by tag.
| Name | Type | Description |
|---|---|---|
| tag | string? | Optional tag filter. |
number — Entity count.
local enemy_count = entity.count("enemy")
if enemy_count == 0 then game.set_state("RoundEnd") end Creates and attaches a child entity to a named bone of a skeletal mesh entity.
| Name | Type | Description |
|---|---|---|
| parent | entity | Parent entity with a skeletal mesh. |
| bone | string | Bone name to attach to. |
| prefab | string | Asset path or prefab name of the child entity. |
| offset | Vec3? | Local position offset from the bone. |
entity — The newly created child entity.
local gun = entity.create_attachment(soldier, "hand_r", "weapons/rifle") Returns the current world position of a named bone attachment point on a skeletal mesh entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a skeletal mesh. |
| bone | string | Bone name. |
Vec3 — World-space position of the bone.
local muzzle = entity.get_attachment_world_pos(soldier, "muzzle")
audio.play("sounds/gunshot", muzzle) Casts a ray from origin in a direction and returns the first hit. Useful for hit-detection, line-of-sight checks, and terrain queries.
| Name | Type | Description |
|---|---|---|
| origin | Vec3 | World position where the ray starts. |
| direction | Vec3 | Normalised direction vector. |
| max_dist | number? | Maximum distance to test. Default: 1000. |
| filter | table? | Optional layer mask table, e.g. { layer = "world" }. |
RayHit? — Table with fields: entity, position (Vec3), normal (Vec3), distance (number). nil if no hit.
local origin = entity.get_position(player)
local dir = Vec3.new(0, -1, 0)
local hit = physics.raycast(origin, dir, 100)
if hit then
print("Hit entity:", hit.entity)
print("At distance:", hit.distance)
end Registers a callback that fires when two bodies start colliding.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
physics.on_collision(ent, function(other, point, normal)
print("Hit!", other)
end) Unregisters a collision start callback.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
physics.off_collision(ent) Registers a callback that fires every frame while bodies overlap.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
physics.on_collision_stay(ent, function(other)
print("Still touching")
end) Unregisters a collision stay callback.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
physics.off_collision_stay(ent) Removes all collision callbacks from an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to clear callbacks from. |
void
physics.clear_collision_callbacks(ent) Adds a Jolt physics body to an entity. Defines the collision shape, mass, friction, and motion type.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to attach the body to. |
| def | table | Body definition: shape ("box"|"sphere"|"capsule"|"mesh"), size (Vec3), mass (number), motion_type ("dynamic"|"static"|"kinematic"), friction, restitution. |
void
local box = entity.create("props/crate")
physics.create_body(box, {
shape = "box",
size = Vec3.new(1, 1, 1),
mass = 50,
motion_type = "dynamic",
friction = 0.6,
restitution = 0.2,
}) Removes the physics body from an entity. The entity continues to exist visually but will no longer participate in physics simulation.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity whose physics body should be removed. |
void
-- Ghost mode: remove physics
physics.destroy_body(player) Applies an instantaneous impulse to a physics body.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| impulse | Vec3 | Impulse vector. |
void
physics.add_impulse(body, vec3.new(0, 100, 0)) Returns the current linear velocity of a physics body as a Vec3.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a RigidBody component. |
Vec3 — Current linear velocity (m/s).
local vel = physics.get_velocity(vehicle)
local speed = Vec3.length(vel)
if speed > 40 then
print("Over speed limit!")
end Directly sets the linear velocity of a physics body. Overrides any existing momentum.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a RigidBody component. |
| velocity | Vec3 | New linear velocity vector (m/s). |
void
-- Knock player back on damage
local kb_dir = Vec3.normalize(Vec3.new(1, 0.5, 0))
physics.set_velocity(player, Vec3.scale(kb_dir, 15)) Returns the angular velocity.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
Vec3
local val = physics.get_angular_velocity(body) Sets the angular velocity.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The angular velocity value. |
void
physics.set_angular_velocity(body, value) Switches a physics body between kinematic and dynamic motion type at runtime.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a RigidBody component. |
| kinematic | bool | True to make kinematic, false to restore dynamic. |
void
-- Freeze object in place during cutscene
physics.set_kinematic(door, true)
timer.delay(3.0, function()
physics.set_kinematic(door, false)
end) Sets the friction.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The friction value. |
void
physics.set_friction(body, value) Returns the friction.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_friction(body) Sets the restitution.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The restitution value. |
void
physics.set_restitution(body, value) Returns the restitution.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_restitution(body) Returns the position.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
Vec3
local val = physics.get_position(body) Returns the rotation.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
Vec3
local val = physics.get_rotation(body) Sets a per-body gravity multiplier. Use 0 for zero-gravity objects or negative values for upward drift.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic RigidBody. |
| scale | number | Gravity scale multiplier. Default: 1.0. |
void
-- Balloon floats upward
physics.set_gravity(balloon, -0.5) Returns the gravity.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_gravity(body) Creates a weld constraint locking two bodies together.
| Name | Type | Description |
|---|---|---|
| body_a | entity | First body. |
| body_b | entity | Second body. |
void
local weld = physics.create_weld(body_a, body_b) Creates a hinge constraint between two bodies.
| Name | Type | Description |
|---|---|---|
| body_a | entity | First body. |
| body_b | entity | Second body. |
| config | table | Hinge axis and limits. |
void
local hinge = physics.create_hinge(body_a, body_b, {
axis = vec3.up(),
min_angle = -90,
max_angle = 90
}) Creates a slider constraint allowing linear movement.
| Name | Type | Description |
|---|---|---|
| body_a | entity | First body. |
| body_b | entity | Second body. |
| config | table | Slider axis and limits. |
void
local obj = physics.create_slider(params) Creates a rope constraint with maximum distance.
| Name | Type | Description |
|---|---|---|
| body_a | entity | First body. |
| body_b | entity | Second body. |
| max_length | number | Maximum rope length. |
void
local rope = physics.create_rope(body_a, body_b, 5.0) Creates a spring constraint between two bodies.
| Name | Type | Description |
|---|---|---|
| body_a | entity | First body. |
| body_b | entity | Second body. |
| config | table | Spring stiffness and damping. |
void
local spring = physics.create_spring(body_a, body_b, {
stiffness = 100,
damping = 10
}) Destroys a physics constraint by handle.
| Name | Type | Description |
|---|---|---|
| constraint | number | Constraint handle. |
void
physics.destroy_constraint(constraint_handle) Sets the constraint break force.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The constraint break force value. |
void
physics.set_constraint_break_force(body, value) Returns the constraint break force.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_constraint_break_force(body) Creates a trigger volume that detects overlapping bodies.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to make a trigger. |
| config | table | Trigger shape configuration. |
void
physics.create_trigger(ent, { shape = "sphere", radius = 5 }) Returns all entities whose physics bodies overlap with a sphere at a given world position. Useful for explosion radius checks.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | Centre of the overlap sphere. |
| radius | number | Sphere radius in metres. |
| filter | table? | Optional layer filter: { layer = "characters" }. |
table — Array of entity handles inside the sphere.
-- Explosion damage
local victims = physics.find_in_sphere(explosion_pos, 5.0)
for _, ent in ipairs(victims) do
if entity.has_tag(ent, "character") then
character.damage(ent, 80, "explosion")
end
end Optimizes the physics broadphase for better query performance.
void
physics.optimize_broadphase() Applies buoyancy forces to a body based on water level.
void
physics.apply_buoyancy(body, water_level, 1.0) Queries all bodies within an axis-aligned bounding box.
| Name | Type | Description |
|---|---|---|
| min | Vec3 | Minimum corner of the AABB. |
| max | Vec3 | Maximum corner of the AABB. |
void
local bodies = physics.query_aabb(vec3.new(-10, 0, -10), vec3.new(10, 5, 10)) Creates a water volume for buoyancy simulation.
| Name | Type | Description |
|---|---|---|
| config | table | Water volume configuration. |
void
physics.create_water({ level = 0, flow = vec3.zero() }) Sets the water level.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The water level value. |
void
physics.set_water_level(body, value) Returns the water level.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_water_level(body) Sets the water flow.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The water flow value. |
void
physics.set_water_flow(body, value) Removes a water volume.
void
physics.remove_water(water_handle) Creates a ragdoll from a skeleton hierarchy.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with skeleton. |
| config | table? | Optional ragdoll configuration. |
void
local rag = physics.create_ragdoll(character_ent) Activates ragdoll physics on an entity.
void
physics.activate_ragdoll(ent) Deactivates ragdoll and returns to animation.
void
physics.deactivate_ragdoll(ent) Applies an impulse to a specific ragdoll bone.
| Name | Type | Description |
|---|---|---|
| entity | entity | Ragdoll entity. |
| bone | string | Bone name to apply impulse to. |
| impulse | Vec3 | Impulse vector. |
void
physics.impulse_ragdoll(ent, "spine", vec3.new(0, 0, -500)) Destroys a ragdoll and its constraints.
void
physics.destroy_ragdoll(ent) Creates a cloth simulation on an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to add cloth to. |
| config | table | Cloth simulation parameters. |
void
physics.create_cloth(ent, { stiffness = 0.8 }) Destroys cloth simulation from an entity.
void
physics.destroy_cloth(ent) Sets the cloth wind.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The cloth wind value. |
void
physics.set_cloth_wind(body, value) Pins cloth vertex.
void
physics.pin_cloth_vertex() Unpins cloth vertex.
void
physics.unpin_cloth_vertex() Returns the cloth vertex count.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
number
local val = physics.get_cloth_vertex_count(body) Sets the layer name.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The layer name value. |
void
physics.set_layer_name(body, value) Returns the layer name.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
string
local val = physics.get_layer_name(body) Returns the layer count.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
number
local val = physics.get_layer_count(body) Finds a collision layer index by name.
| Name | Type | Description |
|---|---|---|
| name | string | Layer name to find. |
void
local idx = physics.find_layer("characters") Creates a collision layer mask from layer indices.
| Name | Type | Description |
|---|---|---|
| ... | number | Layer indices to include in mask. |
void
local mask = physics.layer_mask(0, 1, 3) Sets the collision pair.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The collision pair value. |
void
physics.set_collision_pair(body, value) Returns the collision pair.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_collision_pair(body) Sets the layer mask row.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The layer mask row value. |
void
physics.set_layer_mask_row(body, value) Returns the layer mask row.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_layer_mask_row(body) Sets the body layer.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
| value | any | The body layer value. |
void
physics.set_body_layer(body, value) Returns the body layer.
| Name | Type | Description |
|---|---|---|
| body | entity | Physics body entity. |
any
local val = physics.get_body_layer(body) Queries all bodies within a sphere radius.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | Sphere center position. |
| radius | number | Sphere radius. |
void
local bodies = physics.sphere_query(center, 10.0) Applies an impulse force to a physics body. The entity must have a RigidBody component.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a RigidBody component. |
| force | Vec3 | Force vector in world space (Newtons). |
| point | Vec3? | World-space application point. Defaults to centre of mass. |
void
-- Launch a crate upward
local crate = entity.create("props/crate", Vec3.new(0, 1, 0))
physics.add_force(crate, Vec3.new(0, 500, 0)) Applies a continuous torque to a physics body for this simulation step.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
| torque | Vec3 | Torque vector (N·m). |
void
physics.add_torque(top, Vec3.new(0, 10, 0)) Applies an impulse force at a specific world-space point on a physics body, generating both linear and angular momentum.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
| force | Vec3 | Force vector (N). |
| point | Vec3 | World-space application point. |
void
physics.add_force_at(car, Vec3.new(0, 2000, 0), hit.position) Scales the world gravity applied to a specific physics body. 0 = weightless, 1 = normal, negative = inverted.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
| factor | number | Gravity scale multiplier. |
void
physics.set_gravity_factor(balloon, 0.0) Sets the mass of a dynamic physics body at runtime.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
| mass | number | New mass in kilograms. |
void
physics.set_mass(crate, 200) Returns the mass of a dynamic physics body in kilograms.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic physics body. |
number — Mass in kilograms.
local mass = physics.get_mass(crate)
print("Crate mass:", mass, "kg") Sets linear and angular damping of a physics body, controlling how quickly it loses velocity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
| linear | number | Linear damping coefficient (0–1). |
| angular | number | Angular damping coefficient (0–1). |
void
physics.set_damping(ball, 0.1, 0.05) Returns the linear and angular damping values of a physics body.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
number, number — linear_damping, angular_damping.
local lin, ang = physics.get_damping(ball) Enables or disables motion on a physics body. Disabled bodies are effectively kinematic.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a physics body. |
| enabled | boolean | True to allow motion, false to freeze. |
void
physics.enable_motion(platform, false) Returns whether motion is currently enabled on a physics body.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a physics body. |
boolean — True if motion is enabled.
if not physics.is_motion_enabled(platform) then
physics.enable_motion(platform, true)
end Forces a physics body to sleep immediately, stopping simulation until it is woken.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
void
physics.sleep(debris) Wakes a sleeping physics body, resuming simulation.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
void
physics.wake(debris) Returns whether a physics body is currently in sleep state.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a dynamic body. |
boolean — True if sleeping.
if physics.is_sleeping(boulder) then print("Boulder is at rest") end Casts a ray and returns ALL hits sorted by distance, not just the first.
| Name | Type | Description |
|---|---|---|
| origin | Vec3 | Ray start position. |
| direction | Vec3 | Normalised direction. |
| max_dist | number? | Maximum distance. Default: 1000. |
table — Array of RayHit tables sorted nearest-first.
local hits = physics.raycast_all(origin, dir, 50)
for _, hit in ipairs(hits) do
print("Hit:", hit.entity, hit.distance)
end Sweeps a sphere along a ray and returns all overlapping hits. Useful for melee weapon hit detection.
| Name | Type | Description |
|---|---|---|
| origin | Vec3 | Start position of the sweep. |
| direction | Vec3 | Normalised sweep direction. |
| radius | number | Sphere radius in metres. |
| max_dist | number? | Maximum sweep distance. Default: 100. |
table — Array of RayHit tables (entity, position, normal, distance), sorted by distance.
-- Melee attack sweep
local hits = physics.shape_cast(origin, forward, 0.5, 1.5)
for _, hit in ipairs(hits) do
if entity.has_tag(hit.entity, "enemy") then
character.damage(hit.entity, 40, "melee")
end
end Returns the list of entities currently in contact with a given physics body.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity with a physics body. |
table — Array of entity handles in contact.
local contacts = physics.get_contacts(player)
for _, e in ipairs(contacts) do print("Touching:", e) end Tests whether a given sphere overlaps any physics bodies, returning true on first contact.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | Sphere centre in world space. |
| radius | number | Sphere radius. |
boolean — True if any body overlaps the sphere.
if physics.overlap_test(pos, 2) then print("Something is here") end Creates a distance constraint between two physics bodies, keeping them within a min/max range.
| Name | Type | Description |
|---|---|---|
| entity_a | entity | First entity. |
| entity_b | entity | Second entity. |
| min_dist | number | Minimum allowed distance. |
| max_dist | number | Maximum allowed distance. |
constraint — Constraint handle.
local rope = physics.create_distance(anchor, bob, 0, 5) Activates or adjusts the motor on a hinge or slider constraint.
| Name | Type | Description |
|---|---|---|
| constraint | constraint | Constraint handle. |
| velocity | number | Target angular or linear velocity. |
| max_force | number | Maximum motor force. |
void
physics.set_motor(door_hinge, 2.0, 500) Returns a string describing the type of a constraint (e.g. "fixed", "hinge", "slider", "distance").
| Name | Type | Description |
|---|---|---|
| constraint | constraint | Constraint handle. |
string — Constraint type name.
print(physics.get_constraint_type(c)) Creates a ball-and-socket constraint allowing free rotation around a shared pivot point.
| Name | Type | Description |
|---|---|---|
| entity_a | entity | First entity. |
| entity_b | entity | Second entity. |
| pivot | Vec3 | World-space pivot point. |
constraint — Constraint handle.
local joint = physics.create_ball_socket(torso, arm, shoulder_pos) Creates a constraint that aligns the positions of two bodies (acts as a spring-like position lock).
| Name | Type | Description |
|---|---|---|
| entity_a | entity | First entity. |
| entity_b | entity | Second entity. |
constraint — Constraint handle.
physics.create_align_position(follower, target) Creates a constraint that keeps two bodies rotationally aligned with each other.
| Name | Type | Description |
|---|---|---|
| entity_a | entity | First entity. |
| entity_b | entity | Second entity. |
constraint — Constraint handle.
physics.create_align_orientation(turret, base) Creates a constraint that disables collision detection between two specific physics bodies.
| Name | Type | Description |
|---|---|---|
| entity_a | entity | First entity. |
| entity_b | entity | Second entity. |
constraint — Constraint handle.
physics.create_no_collision(player, carried_object) Plays a sound asset at a given world position for 3D spatial audio, or as a 2D sound when no position is given.
| Name | Type | Description |
|---|---|---|
| path | string | Asset path to an OGG file, e.g. "sounds/gunshot.ogg". |
| position | Vec3? | World position for 3D playback. Omit for 2D (UI) sounds. |
| options | table? | Options: volume (0–1), pitch (0.5–2.0), looping (bool). |
sound — A sound handle that can be passed to audio.stop().
-- 3D gunshot at a position
local sound = audio.play("sounds/gunshot.ogg", hit_pos, {
volume = 0.8,
pitch = 1.0 + math.random() * 0.1,
}) Plays a 3D positional sound at a world position.
| Name | Type | Description |
|---|---|---|
| path | string | Sound asset path. |
| position | Vec3 | World position. |
| config | table? | Optional config (volume, loop, etc.). |
void
audio.play_3d("sounds/explosion.ogg", hit_position) Stops a playing sound and releases its handle. The sound fades out over an optional duration.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle returned by audio.play(). |
| fade_time | number? | Fade-out duration in seconds. Default: 0 (immediate). |
void
local ambient = audio.play("sounds/wind_loop.ogg", nil, {
looping = true,
volume = 0.3,
})
-- Stop with a 1-second fade
timer.delay(30, function()
audio.stop(ambient, 1.0)
end) Changes the volume of a currently playing sound without stopping it.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle to modify. |
| volume | number | New volume in the range [0, 1]. |
void
-- Reduce volume of background music during combat
audio.set_volume(bg_music, 0.2) Sets the master volume.
| Name | Type | Description |
|---|---|---|
| value | any | The master volume value. |
void
audio.set_master_volume(value) Returns the master volume.
any
local val = audio.get_master_volume() Pauses a currently playing sound. Call audio.resume to continue from the same position.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle returned by audio.play. |
void
audio.pause(music) Resumes a paused sound from where it was paused.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
void
audio.resume(music) Returns whether a sound handle is currently playing.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle to query. |
bool — True if the sound is still playing.
if not audio.is_playing(footstep_sound) then
footstep_sound = audio.play("sounds/step.ogg", pos)
end Returns the total duration of a sound in seconds.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
number — Duration in seconds.
local len = audio.get_length(music)
print("Track length:", len, "s") Returns the current playback position of a sound in seconds.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
number — Current position in seconds.
local t = audio.get_time(music) Seeks a sound to a specific playback position in seconds.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
| time | number | Target position in seconds. |
void
audio.set_time(music, 30.0) Changes the playback pitch of a currently playing sound. 1.0 is normal speed, 0.5 is half speed, 2.0 is double speed.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle to modify. |
| pitch | number | Pitch multiplier in the range [0.1, 4.0]. |
void
-- Slow-motion effect
audio.set_pitch(engine_sound, 0.6) Enables or disables looping on a sound.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
| loop | boolean | True to loop, false to play once. |
void
audio.set_loop(ambient, true) Sets the distance rolloff factor for a 3D positional sound. Higher values make the sound fall off faster with distance.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
| rolloff | number | Rolloff factor (default: 1.0). |
void
audio.set_rolloff(explosion, 2.0) Smoothly fades a sound's volume from its current level to a target volume over a duration.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
| target_volume | number | Target volume (0–1). |
| duration | number | Fade duration in seconds. |
void
audio.fade(music, 0.0, 3.0) -- fade out over 3 seconds Creates a named audio group for collective volume control.
| Name | Type | Description |
|---|---|---|
| name | string | Group name. |
void
audio.create_group("sfx")
audio.create_group("music") Sets the master volume multiplier for an audio group.
| Name | Type | Description |
|---|---|---|
| name | string | Group name. |
| volume | number | Volume multiplier (0–1). |
void
audio.set_group_volume("music", 0.5) Assigns a playing sound to an audio group so it is affected by group volume changes.
| Name | Type | Description |
|---|---|---|
| sound | sound | Sound handle. |
| group | string | Group name. |
void
local snd = audio.play("sounds/theme.ogg")
audio.assign_group(snd, "music") Returns the current volume multiplier of an audio group.
| Name | Type | Description |
|---|---|---|
| name | string | Group name. |
number — Volume multiplier.
print("Music volume:", audio.get_group_volume("music")) Switches the camera rig mode. Available modes: "first_person", "third_person", "fixed", "free".
| Name | Type | Description |
|---|---|---|
| mode | string | Camera mode: "first_person", "third_person", "fixed", or "free". |
void
-- Switch to third-person on spawn
hook.add("PlayerSpawn", "cam_mode", function(player)
camera.set_mode("third_person")
camera.follow(player)
end) Returns the mode.
string
local val = camera.get_mode() Sets the vertical field-of-view of the camera in degrees.
| Name | Type | Description |
|---|---|---|
| fov | number | Vertical FOV in degrees (typically 60–120). |
void
-- ADS zoom
camera.set_fov(weapon.is_ads(rifle) and 40 or 75) Returns the current vertical field-of-view of the camera in degrees.
number — Current FOV in degrees.
print("Current FOV:", camera.get_fov()) Sets the sensitivity.
| Name | Type | Description |
|---|---|---|
| value | any | The sensitivity value. |
void
camera.set_sensitivity(value) Sets the pitch limit.
| Name | Type | Description |
|---|---|---|
| value | any | The pitch limit value. |
void
camera.set_pitch_limit(value) Sets the distance.
| Name | Type | Description |
|---|---|---|
| value | any | The distance value. |
void
camera.set_distance(value) Sets the height.
| Name | Type | Description |
|---|---|---|
| value | any | The height value. |
void
camera.set_height(value) Sets the offset.
| Name | Type | Description |
|---|---|---|
| value | any | The offset value. |
void
camera.set_offset(value) Sets the shoulder.
| Name | Type | Description |
|---|---|---|
| value | any | The shoulder value. |
void
camera.set_shoulder(value) Applies a screen-shake effect to the camera over a given duration.
| Name | Type | Description |
|---|---|---|
| intensity | number | Shake intensity (0–1). |
| duration | number | Duration in seconds. |
| falloff | number? | Distance from explosion at which shake reaches 0. Default: 20. |
void
-- Shake camera on nearby explosion
local dist = Vec3.distance(camera.get_position(), explosion_pos)
if dist < 30 then
camera.shake(1 - dist / 30, 0.5)
end Smoothly zooms the camera FOV over a duration.
| Name | Type | Description |
|---|---|---|
| value | any | The zoom value. |
void
camera.set_zoom(1, 30, 0.3) Sets the camera target entity to follow.
| Name | Type | Description |
|---|---|---|
| value | any | The target value. |
void
camera.set_target(1, player_ent) Resets the camera target, returning to free mode.
void
camera.reset_target(1) Sets the near far.
| Name | Type | Description |
|---|---|---|
| value | any | The near far value. |
void
camera.set_near_far(value) Returns the near far.
any
local val = camera.get_near_far() Sets which camera entity is the active render camera.
| Name | Type | Description |
|---|---|---|
| value | any | The active value. |
void
camera.set_active(camera_ent) Sets the walk speed.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The walk speed value. |
void
character.set_walk_speed(peer_id, value) Returns the walk speed.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_walk_speed(peer_id) Sets the run speed.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The run speed value. |
void
character.set_run_speed(peer_id, value) Returns the run speed.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_run_speed(peer_id) Sets the crouch speed.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The crouch speed value. |
void
character.set_crouch_speed(peer_id, value) Returns the crouch speed.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_crouch_speed(peer_id) Sets the jump power.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The jump power value. |
void
character.set_jump_power(peer_id, value) Returns the jump power.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_jump_power(peer_id) Sets the max jumps.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The max jumps value. |
void
character.set_max_jumps(peer_id, value) Returns the max jumps.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_max_jumps(peer_id) Sets the gravity scale.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The gravity scale value. |
void
character.set_gravity_scale(peer_id, value) Returns the gravity scale.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_gravity_scale(peer_id) Sets the air control.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The air control value. |
void
character.set_air_control(peer_id, value) Returns the air control.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_air_control(peer_id) Sets the friction.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The friction value. |
void
character.set_friction(peer_id, value) Returns the friction.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_friction(peer_id) Sets the step height.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The step height value. |
void
character.set_step_height(peer_id, value) Returns the step height.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_step_height(peer_id) Sets the max slope.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The max slope value. |
void
character.set_max_slope(peer_id, value) Returns the max slope.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_max_slope(peer_id) Sets the character capsule dimensions (radius, height).
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The capsule value. |
void
character.set_capsule(peer_id, 0.4, 1.8) Sets the crouch height.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The crouch height value. |
void
character.set_crouch_height(peer_id, value) Returns the crouch height.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_crouch_height(peer_id) Returns the move state.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
string
local val = character.get_move_state(peer_id) Returns true if on ground.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
boolean
if character.is_on_ground() then
print("true")
end Returns true if crouching.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
boolean
if character.is_crouching() then
print("true")
end Returns true if sprinting.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
boolean
if character.is_sprinting() then
print("true")
end Returns true if in air.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
boolean
if character.is_in_air() then
print("true")
end Sets the character movement type (walk, fly, noclip).
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The move type value. |
void
character.set_move_type(peer_id, "fly") Freezes the character, preventing all movement.
void
character.freeze(peer_id, true) Enables or disables noclip mode for the character.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The noclip value. |
void
character.set_noclip(peer_id, true) Sets the godmode.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The godmode value. |
void
character.set_godmode(peer_id, value) Returns the godmode.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
string
local val = character.get_godmode(peer_id) Returns the velocity.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
Vec3
local val = character.get_velocity(peer_id) Sets the velocity.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The velocity value. |
void
character.set_velocity(peer_id, value) Applies an instantaneous impulse to the character.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| impulse | Vec3 | Impulse vector to apply. |
void
character.add_impulse(peer_id, vec3.new(0, 500, 0)) Sets the maximum health cap for a character.
| Name | Type | Description |
|---|---|---|
| entity | entity | Character entity. |
| max_hp | number | New maximum health value. |
void
-- Tank class gets more HP
character.set_max_health(player, 200)
character.set_health(player, 200) Returns the max health.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_max_health(peer_id) Sets the health of a character entity. Clamped between 0 and max_health. Setting to 0 triggers the CharacterDied hook.
| Name | Type | Description |
|---|---|---|
| entity | entity | Character entity. |
| health | number | New health value (clamped to [0, max_health]). |
void
-- Full heal on respawn
hook.add("PlayerSpawn", "my_mod.heal", function(player)
character.set_health(player, 100)
character.set_armor(player, 50)
end) Returns the current health of a character entity as a number.
| Name | Type | Description |
|---|---|---|
| entity | entity | Character entity. |
number — Current health value.
local hp = character.get_health(player)
if hp < 25 then
net.send(peer, "low_health_warning", { hp = hp })
end Restores health to a character. Capped at max_health.
| Name | Type | Description |
|---|---|---|
| entity | entity | Character entity. |
| amount | number | Amount of health to restore. |
void
-- Medkit pickup
hook.add("ItemPickup", "medkit", function(player, item)
if item.type == "medkit" then
character.heal(player, 50)
end
end) Returns whether a character is currently alive (health > 0).
| Name | Type | Description |
|---|---|---|
| entity | entity | Character entity. |
bool — True if the character is alive.
if character.is_alive(player) then
character.damage(player, 10, "fire")
end Applies damage to a character. Fires the CharacterDamaged hook (which can be cancelled). Damage type is used for effects and resistances.
| Name | Type | Description |
|---|---|---|
| entity | entity | Character entity to damage. |
| amount | number | Damage amount. |
| damage_type | string? | Damage type string: "bullet", "explosion", "fire", "melee", "fall". Default: "generic". |
| attacker | entity? | Entity responsible for the damage (for kill credit). |
void
-- Explosion radius damage
local victims = physics.find_in_sphere(pos, 5)
for _, ent in ipairs(victims) do
if entity.has_tag(ent, "character") then
character.damage(ent, 80, "explosion", attacker)
end
end Kills the character immediately.
void
character.kill(peer_id) Respawns the character at a spawn point.
void
character.respawn(peer_id) Sets the respawn time.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The respawn time value. |
void
character.set_respawn_time(peer_id, value) Returns the respawn time.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
any
local val = character.get_respawn_time(peer_id) Sets the animation profile for the character.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The anim profile value. |
void
character.set_anim_profile(peer_id, "soldier") Sets the animation blend/crossfade time.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| value | any | The blend time value. |
void
character.set_blend_time(peer_id, 0.2) Plays a named animation on the character.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| name | string | Animation name. |
| loop | boolean? | Whether to loop. |
void
character.play_anim(peer_id, "wave", true) Returns whether a keyboard key is currently held down. Client-side only. Use key name strings (SDL scancode names).
| Name | Type | Description |
|---|---|---|
| key | string | Key name string, e.g. "W", "Space", "LeftShift", "F". |
bool — True if the key is held.
hook.add("Think", "sprint.check", function()
if input.is_key_down("LeftShift") and character.is_grounded(local_player) then
character.set_speed(local_player, 8.0)
else
character.set_speed(local_player, 5.0)
end
end) Returns true if key pressed this frame.
| Name | Type | Description |
|---|---|---|
| key | string | The key identifier. |
boolean
if input.was_key_pressed() then
print("true")
end Returns true if key released this frame.
| Name | Type | Description |
|---|---|---|
| key | string | The key identifier. |
boolean
if input.was_key_released() then
print("true")
end Returns how many pixels the mouse moved since the last frame. Useful for look input in first-person cameras.
number, number — Delta X and delta Y in pixels.
hook.add("Think", "look", function()
local dx, dy = input.get_mouse_delta()
camera.rotate(dy * 0.1, dx * 0.1)
end) Returns the current cursor position in screen pixels (x, y). Client-side only.
number, number — Mouse X and Y position in pixels.
local mx, my = input.get_mouse_position()
ui.set_position(tooltip, UDim2.new(0, mx + 12, 0, my + 8)) Returns whether a mouse button is currently held. Button names: "Left", "Right", "Middle".
| Name | Type | Description |
|---|---|---|
| button | string | Mouse button name: "Left", "Right", or "Middle". |
bool — True if the button is held.
if input.is_mouse_down("Left") and weapon.get_equipped(player) then
net.send_to_server("fire_request", {})
end Returns true if mouse pressed this frame.
| Name | Type | Description |
|---|---|---|
| mouse | string | The mouse identifier. |
boolean
if input.was_mouse_pressed() then
print("true")
end Binds a key to a named action.
| Name | Type | Description |
|---|---|---|
| action | string | Action name. |
| key | string | Key name to bind. |
void
input.bind("jump", "Space") Removes a key binding from a named action.
| Name | Type | Description |
|---|---|---|
| action | string | Action name to unbind. |
void
input.unbind("jump") Returns true if action down.
| Name | Type | Description |
|---|---|---|
| action | string | The action identifier. |
boolean
if input.is_action_down() then
print("true")
end Returns true if action pressed this frame.
| Name | Type | Description |
|---|---|---|
| action | string | The action identifier. |
boolean
if input.was_action_pressed() then
print("true")
end Returns true if action released this frame.
| Name | Type | Description |
|---|---|---|
| action | string | The action identifier. |
boolean
if input.was_action_released() then
print("true")
end Returns a table of all current key bindings.
any
local bindings = input.get_bindings() Sets the direction of the directional (sun) light.
| Name | Type | Description |
|---|---|---|
| dir | Vec3 | Normalized direction vector pointing toward the sun. |
void
lighting.set_sun_direction(Vec3.new(-0.5, -1, -0.3)) Sets the color and intensity of the sun light.
| Name | Type | Description |
|---|---|---|
| r | number | Red channel [0, 1]. |
| g | number | Green channel [0, 1]. |
| b | number | Blue channel [0, 1]. |
| intensity | number? | Intensity multiplier (default 1.0). |
void
lighting.set_sun_color(1.0, 0.95, 0.8, 2.0) Sets the ambient light color applied uniformly to all surfaces.
| Name | Type | Description |
|---|---|---|
| r | number | Red [0, 1]. |
| g | number | Green [0, 1]. |
| b | number | Blue [0, 1]. |
void
lighting.set_ambient(0.1, 0.1, 0.15) Configures exponential fog parameters.
| Name | Type | Description |
|---|---|---|
| density | number | Fog density. |
| r | number | Fog color red. |
| g | number | Fog color green. |
| b | number | Fog color blue. |
void
lighting.set_fog(0.02, 0.8, 0.85, 0.9) Enables or disables scene fog rendering.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable fog. |
void
lighting.set_fog_enabled(true) Sets the sky color or sky box asset used for background rendering.
| Name | Type | Description |
|---|---|---|
| asset | string | Sky asset path or color preset name. |
void
lighting.set_sky("skyboxes/sunset") Overrides the global metallic factor for PBR materials (0.0-1.0).
| Name | Type | Description |
|---|---|---|
| value | number | Metallic factor [0, 1]. |
void
lighting.set_metallic(0.0) Overrides the global roughness factor for PBR materials (0.0-1.0).
| Name | Type | Description |
|---|---|---|
| value | number | Roughness factor [0, 1]. |
void
lighting.set_roughness(0.5) Sets the global emissive color multiplier for emissive materials.
| Name | Type | Description |
|---|---|---|
| r | number | Red [0, 1+]. |
| g | number | Green [0, 1+]. |
| b | number | Blue [0, 1+]. |
void
lighting.set_emissive(2.0, 2.0, 2.0) Sets the point light shadows.
| Name | Type | Description |
|---|---|---|
| value | any | The point light shadows value. |
void
lighting.set_point_light_shadows(value) Sets the point shadow quality.
| Name | Type | Description |
|---|---|---|
| value | any | The point shadow quality value. |
void
lighting.set_point_shadow_quality(value) Sets the point shadow bias.
| Name | Type | Description |
|---|---|---|
| value | any | The point shadow bias value. |
void
lighting.set_point_shadow_bias(value) Adds a point light to the scene and returns its handle.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World position. |
| color | Vec3 | RGB color [0,1] each. |
| radius | number | Attenuation radius. |
| intensity | number? | Intensity multiplier. |
handle — Point light handle.
local light = lighting.add_point(Vec3.new(0,3,0), Vec3.new(1,0.8,0.4), 10) Updates parameters of an existing point light.
| Name | Type | Description |
|---|---|---|
| handle | handle | Point light handle. |
| position | Vec3 | New position. |
| color | Vec3 | New color. |
| radius | number | New radius. |
void
lighting.set_point(light, Vec3.new(0,5,0), Vec3.new(1,1,1), 15) Returns the properties of a point light.
any
local info = lighting.get_point(handle) Removes a point light from the scene.
| Name | Type | Description |
|---|---|---|
| handle | handle | Point light handle. |
void
lighting.remove_point(light) Adds a spot light to the scene and returns its handle.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World position. |
| direction | Vec3 | Normalized direction. |
| color | Vec3 | RGB color. |
| inner_angle | number | Inner cone angle in degrees. |
| outer_angle | number | Outer cone angle in degrees. |
handle — Spot light handle.
local spot = lighting.add_spot(pos, dir, Vec3.new(1,1,1), 15, 30) Updates an existing spot light properties.
| Name | Type | Description |
|---|---|---|
| value | any | The spot value. |
void
lighting.set_spot(handle, { color = {1,1,1}, range = 20 }) Returns the properties of a spot light.
any
local info = lighting.get_spot(handle) Removes a spot light from the scene.
| Name | Type | Description |
|---|---|---|
| handle | handle | Spot light handle. |
void
lighting.remove_spot(spot) Enables or disables shadow casting for the directional light.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable shadows. |
void
lighting.set_shadow_enabled(true) Sets the shadow cascade quality tier (0=Low, 1=Medium, 2=High, 3=Ultra).
| Name | Type | Description |
|---|---|---|
| quality | number | Quality tier 0-3. |
void
lighting.set_shadow_quality(2) Sets the shadow distance.
| Name | Type | Description |
|---|---|---|
| value | any | The shadow distance value. |
void
lighting.set_shadow_distance(value) Sets the shadow bias.
| Name | Type | Description |
|---|---|---|
| value | any | The shadow bias value. |
void
lighting.set_shadow_bias(value) Sets the shadow cascades.
| Name | Type | Description |
|---|---|---|
| value | any | The shadow cascades value. |
void
lighting.set_shadow_cascades(value) Sets the shadow split lambda.
| Name | Type | Description |
|---|---|---|
| value | any | The shadow split lambda value. |
void
lighting.set_shadow_split_lambda(value) Returns the shadow settings.
any
local val = lighting.get_shadow_settings() Enables or disables image-based lighting (IBL) from the environment map.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable IBL. |
void
lighting.set_ibl_enabled(true) Sets the ibl intensity.
| Name | Type | Description |
|---|---|---|
| value | any | The ibl intensity value. |
void
lighting.set_ibl_intensity(value) Loads a pre-convolved environment cubemap for IBL.
| Name | Type | Description |
|---|---|---|
| path | string | Path to the KTX2 environment cubemap. |
void
lighting.load_environment_map("env/outdoor_day.ktx2") Returns the ibl settings.
any
local val = lighting.get_ibl_settings() Convolves a cubemap for IBL (irradiance/prefilter).
| Name | Type | Description |
|---|---|---|
| path | string | Cubemap texture path. |
void
lighting.convolve_cubemap("textures/sky.ktx2") Bakes a reflection probe at a given world position, capturing the scene.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | Probe capture position. |
handle — Reflection probe handle.
local probe = lighting.bake_probe(Vec3.new(0, 2, 0)) Activates or deactivates a reflection probe.
| Name | Type | Description |
|---|---|---|
| handle | handle | Probe handle. |
| active | bool | True to activate. |
void
lighting.set_probe_active(probe, true) Creates an occlusion culling area.
| Name | Type | Description |
|---|---|---|
| min | Vec3 | Minimum corner of occlusion volume. |
| max | Vec3 | Maximum corner of occlusion volume. |
void
local area = lighting.create_occlusion(min_pos, max_pos) Sets the occlusion extents.
| Name | Type | Description |
|---|---|---|
| value | any | The occlusion extents value. |
void
lighting.set_occlusion_extents(value) Returns the occlusion extents.
any
local val = lighting.get_occlusion_extents() Removes an occlusion culling area.
void
lighting.remove_occlusion(area_handle) Sets a portal connection between occlusion areas.
| Name | Type | Description |
|---|---|---|
| value | any | The occlusion portal value. |
void
lighting.set_occlusion_portal(area_a, area_b, portal_bounds) Loads a glTF skinned mesh onto an entity, replacing any existing mesh.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| path | string | Path to the glTF asset. |
void
animation.load_skinned_mesh(player, "characters/soldier.gltf") Plays an animation clip on a skeletal mesh entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| clip | string | Clip name. |
void
animation.play(player, "run") Stops the currently playing animation on an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
void
animation.stop(player) Sets the playback speed multiplier for an animation.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| speed | number | Speed multiplier (1.0 = normal). |
void
animation.set_speed(player, 1.5) Enables or disables looping for the current animation.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| loop | bool | True to loop. |
void
animation.set_loop(player, true) Returns the current playback time of the active animation in seconds.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
number — Playback time in seconds.
local t = animation.get_time(player)
print("Anim time:", t) Returns the total duration of a named animation clip in seconds.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| clip | string | Clip name. |
number — Duration in seconds.
local dur = animation.get_duration(player, "jump")
print("Jump duration:", dur) Returns a table of all available animation clip names on an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
table — Array of clip name strings.
for _, name in ipairs(animation.list(player)) do
print(name)
end Smoothly transitions from the current clip to a new clip over a given duration.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| clip | string | Target clip name. |
| duration | number | Blend duration in seconds. |
void
animation.crossfade(player, "idle", 0.3) Sets the number of animation blend layers for an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| count | number | Number of layers. |
void
animation.set_layer_count(player, 2) Plays an animation clip on a specific blend layer.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| layer | number | Layer index (0-based). |
| clip | string | Clip name. |
void
animation.play_on_layer(player, 1, "wave") Stops the animation playing on the specified blend layer.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| layer | number | Layer index. |
void
animation.stop_layer(player, 1) Sets the blend weight of a specific layer (0.0-1.0).
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| layer | number | Layer index. |
| weight | number | Blend weight [0, 1]. |
void
animation.set_layer_weight(player, 1, 0.8) Masks a blend layer to only affect a bone subtree rooted at the given bone.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| layer | number | Layer index. |
| bone | string | Root bone name for the mask. |
void
animation.set_layer_mask_subtree(player, 1, "spine") Creates an animation state machine on an entity and returns its handle.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
handle — State machine handle.
local sm = animation.create_state_machine(player) Triggers a named transition in the animation state machine.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| trigger | string | Transition trigger name. |
void
animation.trigger_transition(player, "to_run") Returns the current state name of the animation state machine.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
string — Current state name.
print("Anim state:", animation.get_state(player)) Returns a table of all bone names in the skeleton of the entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
table — Array of bone name strings.
for _, bone in ipairs(animation.list_bones(player)) do
print(bone)
end Returns the world-space position of a named bone.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| bone | string | Bone name. |
Vec3 — World position of the bone.
local pos = animation.get_bone_position(player, "hand_r") Attaches a child entity to a named bone of a skeletal mesh entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity (parent). |
| bone | string | Bone name. |
| child | entity | Entity to attach. |
void
animation.attach_to_bone(player, "hand_r", weapon_entity) Detaches a child entity from the bone it is attached to.
| Name | Type | Description |
|---|---|---|
| child | entity | Entity to detach. |
void
animation.detach_from_bone(weapon_entity) Pauses or resumes the animation playback on an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| playing | bool | True to play, false to pause. |
void
animation.set_playing(player, false) Sets the default crossfade duration for animation transitions.
| Name | Type | Description |
|---|---|---|
| value | any | The crossfade value. |
void
animation.set_crossfade(ent, 0.25) Registers a callback that fires when a clip reaches a specific time.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| clip | string | Clip name. |
| time | number | Time in seconds to fire the event. |
| callback | function | Function to call. |
void
animation.add_clip_event(player, "attack", 0.3, function()
deal_damage()
end) Removes a specific clip event by ID.
| Name | Type | Description |
|---|---|---|
| entity | entity | Animated entity. |
| event_id | number | Event ID to remove. |
void
animation.remove_clip_event(ent, event_id) Removes all registered clip events for a given clip on an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Skeletal mesh entity. |
| clip | string | Clip name. |
void
animation.clear_clip_events(player, "attack") Returns all registered events on an animation clip.
any
local events = animation.get_clip_events(ent) Begins writing a new network message.
| Name | Type | Description |
|---|---|---|
| name | string | Network message name. |
void
net.Start("MyMessage") Writes a string to the current network message.
| Name | Type | Description |
|---|---|---|
| value | string | The string value to write. |
void
net.WriteString("hello") Writes an integer to the current network message.
| Name | Type | Description |
|---|---|---|
| value | int | The int value to write. |
void
net.WriteInt(42) Writes a float to the current network message.
| Name | Type | Description |
|---|---|---|
| value | float | The float value to write. |
void
net.WriteFloat(3.14) Writes a Vec3 to the current network message.
| Name | Type | Description |
|---|---|---|
| value | vec3 | The vec3 value to write. |
void
net.WriteVec3(vec3.new(1, 2, 3)) Writes a boolean to the current network message.
| Name | Type | Description |
|---|---|---|
| value | bool | The bool value to write. |
void
net.WriteBool(true) Reads a string from the current network message.
string
local str = net.ReadString() Reads an integer from the current network message.
int
local n = net.ReadInt() Reads a float from the current network message.
float
local f = net.ReadFloat() Reads a Vec3 from the current network message.
vec3
local v = net.ReadVec3() Reads a boolean from the current network message.
bool
local b = net.ReadBool() Sends the current network message to a specific peer.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Target peer ID. |
void
net.Send(peer_id) Broadcasts the current network message to all peers.
void
net.Broadcast() Sends the current network message to the server.
void
net.SendToServer() Registers a callback for incoming network messages.
| Name | Type | Description |
|---|---|---|
| name | string | Message name to listen for. |
| callback | function | Callback receiving (len, sender). |
void
net.Receive("MyMessage", function(len, sender)
local msg = net.ReadString()
print(msg)
end) Returns the peer ID of the message sender.
number
local sender = net.Sender() Writes a Lua table to the current network message.
| Name | Type | Description |
|---|---|---|
| value | table | The table value to write. |
void
net.WriteTable({ score = 100 }) Reads a Lua table from the current network message.
table
local data = net.ReadTable() Returns the local peer network ID.
number
local my_id = net.GetLocalNetId() Writes an integer to the current outgoing net message buffer.
| Name | Type | Description |
|---|---|---|
| value | number | Integer value to write. |
void
net.write_int(player_health)
net.send(peer, "health_sync") Writes a floating-point number to the current outgoing net message buffer.
| Name | Type | Description |
|---|---|---|
| value | number | Float value to write. |
void
net.write_float(vehicle.get_speed(car)) Writes a Vec3 (3 floats) to the current outgoing net message buffer.
| Name | Type | Description |
|---|---|---|
| value | Vec3 | Vec3 value to write. |
void
net.write_vec3(entity.get_position(player)) Writes an entity reference to the current outgoing net message buffer.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity handle to write. |
void
net.write_entity(attacker)
net.write_entity(victim) Writes a Color3 value to the current outgoing net message buffer.
| Name | Type | Description |
|---|---|---|
| color | Color3 | Color value to write. |
void
net.write_color(Color3.new(1, 0, 0)) Reads an integer from the current incoming net message buffer.
number — Integer value.
net.receive("health_sync", function(data)
local hp = net.read_int()
update_health_bar(hp)
end) Reads a float from the current incoming net message buffer.
number — Float value.
local speed = net.read_float() Reads a Vec3 from the current incoming net message buffer.
Vec3 — Read vector value.
local pos = net.read_vec3() Reads an entity reference from the current incoming net message buffer.
entity — Entity handle.
local attacker = net.read_entity() Reads a Color3 from the current incoming net message buffer.
Color3 — Color value.
local team_color = net.read_color() Returns the number of bytes written to the current outgoing message buffer so far.
number — Byte count.
net.write_vec3(pos)
print("Bytes so far:", net.bytes_written()) Sends a named message unreliably (UDP, no retransmission). Use for high-frequency data like position updates where dropped packets are acceptable.
| Name | Type | Description |
|---|---|---|
| peer | peer | Recipient peer. |
| message | string | Message identifier. |
| data | table? | Payload table. |
void
net.send_unreliable(peer, "pos_update", { pos = entity.get_position(player) }) Sends a large reliable message split into multiple packets (latent channel). Suitable for map data or large payloads.
| Name | Type | Description |
|---|---|---|
| peer | peer | Recipient peer. |
| message | string | Message identifier. |
| data | table | Payload table (can be large). |
void
net.send_latent(peer, "map_data", { chunks = map_table }) Draws a text string at the given position.
void
ui.text(100, 50, "Hello World", 0xFFFFFFFF) Draws a filled rectangle.
void
ui.rect(10, 10, 200, 100, 0xFF333333) Draws a clickable button and returns true if clicked.
boolean
if ui.button(10, 10, 120, 40, "Click Me") then
print("Clicked!")
end Measures the pixel dimensions of a text string.
number
local w, h = ui.measure_text("Hello") Creates a color from RGB components (0-255).
number
local color = ui.rgb(255, 128, 0) Creates a color from RGBA components (0-255).
number
local color = ui.rgba(255, 128, 0, 200) Returns the current screen width in pixels.
number
local w = ui.screen_width() Returns the current screen height in pixels.
number
local h = ui.screen_height() Returns the current mouse X position.
number
local mx = ui.mouse_x() Returns the current mouse Y position.
number
local my = ui.mouse_y() Draws a panel background rectangle.
void
ui.panel(0, 0, 300, 200, 0xFF222222) Draws an image/texture at the given position.
void
ui.image(10, 10, 64, 64, "textures/icon.png") Draws an editable text input field.
void
local text = ui.input_text("name_input", 10, 50, 200, 30, current_text) Begins a scrollable area region.
void
ui.begin_scroll_area(10, 10, 300, 400) Ends the current scrollable area region.
void
ui.end_scroll_area() Returns the visible range of items in a scroll area.
void
local first, last = ui.visible_range() Sets the scroll offset.
void
ui.set_scroll_offset("my_scroll", 100) Draws a progress bar widget.
void
ui.progress_bar(10, 10, 200, 20, 0.75, 0xFF00FF00) Registers a callback for the click event.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
ui.on_click("btn_id", function()
print("Clicked")
end) Draws a line between two points.
void
ui.line(0, 0, 100, 100, 0xFFFFFFFF) Sets a clipping rectangle for subsequent draws.
void
ui.clip(10, 10, 200, 200) Creates a flex layout container.
void
ui.container({ dir = "row", gap = 8 }) Advances to the next flex layout slot.
void
ui.next() Returns true if hovered.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_hovered("btn") then print("Hovering") end Returns true if clicked.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_clicked("btn") then print("Clicked") end Returns true if right clicked.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_right_clicked("btn") then print("Right-clicked") end Returns the mouse scroll wheel delta this frame.
number
local delta = ui.scroll_delta() Sets keyboard focus to a widget by ID.
void
ui.focus("input_name") Returns true if focused.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_focused("input_name") then end Removes keyboard focus from the current widget.
void
ui.blur() Returns true if key pressed.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_key_pressed("Return") then end Returns true if key held.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_key_held("W") then end Returns true if key released.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_key_released("Space") then end Sets the cursor.
void
ui.set_cursor("hand") Returns true if the UI wants to capture mouse input.
void
if ui.wants_mouse() then return end Returns true if the UI wants to capture keyboard input.
void
if ui.wants_keyboard() then return end Draws a checkbox widget and returns the toggled state.
boolean
local checked = ui.checkbox("opt", 10, 50, "Enable feature", is_enabled) Draws a toggle switch widget.
boolean
local on = ui.toggle("dark_mode", 10, 50, is_dark) Draws a slider widget and returns the current value.
number
local val = ui.slider("volume", 10, 50, 200, 0.0, 1.0, current_vol) Draws an editable text field widget.
void
local text = ui.textfield("username", 10, 50, 200, 30, current) Draws a dropdown selection widget.
void
local idx = ui.dropdown("diff", 10, 50, 150, {"Easy","Normal","Hard"}, sel) Creates a scrollable area with automatic scrollbars.
void
ui.scroll_area("list", 10, 10, 300, 400) Draws a tab bar widget and returns the selected tab index.
void
local tab = ui.tabs("main_tabs", 10, 10, 400, {"General","Audio","Video"}, cur) Shows a temporary toast notification message.
void
ui.toast("Settings saved!", "success") Draws a modal dialog overlay.
void
ui.modal("confirm", function()
ui.text(20, 20, "Are you sure?", 0xFFFFFFFF)
end) Opens a modal dialog by ID.
void
ui.open_modal("confirm") Closes the currently open modal dialog.
void
ui.close_modal("confirm") Returns true if modal open.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_modal_open("confirm") then end Draws a keybind capture widget.
void
local key = ui.keybind("jump_key", 10, 50, 150, current_key) Sets the theme.
void
ui.set_theme({ bg = 0xFF1A1A2E, accent = 0xFF00D2FF }) Returns the theme.
any
local theme = ui.get_theme() Returns the frame delta time for UI animations.
number
local dt = ui.delta_time() Returns the total elapsed UI time.
number
local t = ui.time() Linearly interpolates between two values.
number
local v = ui.lerp(0, 100, 0.5) Returns a smooth Hermite interpolation between 0 and 1.
number
local v = ui.smoothstep(0, 1, t) Begins a new UI frame. Call at the start of each frame.
void
ui.begin_frame() Ends the current UI frame and flushes draw commands.
void
ui.end_frame() Shows a tooltip near the cursor when hovering a widget.
void
ui.tooltip("Click to confirm") Animates one or more properties of a UI element over a duration using an easing function. Fires an optional callback when complete.
| Name | Type | Description |
|---|---|---|
| element | uielement | Target UI element. |
| duration | number | Animation duration in seconds. |
| goals | table | Target property values: size, position, transparency, color, etc. |
| easing | string? | Easing function name. Default: "linear". Options: ease_in, ease_out, ease_in_out, bounce, elastic, etc. |
| callback | function? | Called when the tween completes. |
void
-- Slide HUD in from the left
ui.set_position(hud, UDim2.new(-0.3, 0, 0.9, 0))
ui.tween(hud, 0.4, {
position = UDim2.new(0.01, 0, 0.9, 0),
}, "ease_out") Cancels an active UI tween by ID.
void
ui.cancel_tween("fade") Restarts a UI tween animation from the beginning.
void
ui.restart_tween("fade") Creates a declarative UI frame container with styling options.
void
ui.frame({
x = 10, y = 10, w = 200, h = 100,
bg = 0xFF333333, radius = 8
}) Creates a declarative text label with styling options.
void
ui.label({
x = 20, y = 20, text = "Hello",
color = 0xFFFFFFFF, size = 16
}) Renders rich text with markup tags for styling.
void
ui.rich_text(10, 10, "<b>Bold</b> and <i>italic</i>", 0xFFFFFFFF) Makes a UI element draggable for drag-and-drop.
void
ui.draggable("item_1", 10, 10, 80, 80) Creates a drop zone that accepts dragged elements.
void
local dropped = ui.drop_zone("slot_1", 100, 10, 80, 80) Returns true if dragging.
| Name | Type | Description |
|---|---|---|
| id | string | Widget identifier. |
boolean
if ui.is_dragging() then end Returns the drag id.
any
local id = ui.get_drag_id() Opens a context menu at the current mouse position.
void
ui.open_context_menu("ctx", {{"Copy","copy"},{"Paste","paste"}}) Closes the currently open context menu.
void
ui.close_context_menu() Renders the context menu if open. Call each frame.
void
ui.context_menu() Sets the design resolution.
void
ui.set_design_resolution(1920, 1080) Loads a TTF font file and registers it under a name for use with set_font. The atlas is built on first use.
| Name | Type | Description |
|---|---|---|
| name | string | Identifier name to register the font under. |
| path | string | Asset path to a TTF font file. |
void
ui.load_font("HUD", "fonts/inter_bold.ttf")
ui.load_font("Body", "fonts/inter_regular.ttf") Sets the font of a TextLabel or TextButton element to a previously loaded named font.
| Name | Type | Description |
|---|---|---|
| element | uielement | Target TextLabel or TextButton. |
| font_name | string | Registered font name (from ui.load_font). |
void
ui.set_font(damage_number, "HUD") Loads a layout.
void
local layout = ui.load_layout("ui/hud.json") Renders a previously loaded UI layout.
void
ui.draw_layout(layout) Registers a new weapon definition with properties.
| Name | Type | Description |
|---|---|---|
| name | string | Unique weapon name. |
| config | table | Weapon properties (damage, fire_rate, etc.). |
void
weapon.register("ak47", {
damage = 25,
fire_rate = 600,
clip_size = 30,
type = "hitscan"
}) Returns the definition.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_definition() Gives a weapon to a player by definition name.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| weapon_name | string | Registered weapon name. |
void
weapon.give(peer_id, "ak47") Removes a specific weapon from a player.
void
weapon.remove() Removes all weapons from a player.
void
weapon.remove_all(peer_id) Has.
void
weapon.has() Sets the active.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
| value | any | The active value. |
void
weapon.set_active(value) Drops a specific weapon from the player inventory.
void
weapon.drop(peer_id, "ak47") Drops the currently active weapon.
void
weapon.drop_active(peer_id) Spawns a weapon pickup entity in the world.
| Name | Type | Description |
|---|---|---|
| weapon_name | string | Weapon definition name. |
| position | Vec3 | World position for the pickup. |
void
weapon.spawn_pickup("ak47", vec3.new(10, 1, 5)) Returns the active.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_active() Returns the all.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
table
local val = weapon.get_all() Returns the clip.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_clip() Returns the reserve.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_reserve() Sets the clip.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
| value | any | The clip value. |
void
weapon.set_clip(value) Sets the reserve.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
| value | any | The reserve value. |
void
weapon.set_reserve(value) Adds ammo.
void
weapon.add_ammo(params) Fires the weapon from the perspective of an entity. Performs hitscan or spawns a projectile depending on the weapon type. Server-side only.
| Name | Type | Description |
|---|---|---|
| weapon_ent | entity | The weapon entity to fire. |
| origin | Vec3 | Muzzle world position. |
| direction | Vec3 | Normalised fire direction. |
FireResult — Table with: hit (bool), hit_entity (entity?), hit_position (Vec3?), damage_dealt (number).
-- Server-side fire handler
hook.add("WeaponFire", "my_mod.fire", function(player, weapon_ent)
local origin = character.get_muzzle_position(player)
local dir = character.get_aim_direction(player)
local result = weapon.fire(weapon_ent, origin, dir)
if result.hit then
print("Hit!", result.damage_dealt, "damage")
end
end) Triggers a reload on a weapon, refilling the magazine from reserve ammo. Fires the WeaponReload hook.
| Name | Type | Description |
|---|---|---|
| weapon_ent | entity | Weapon entity to reload. |
void
-- Auto-reload when empty
hook.add("WeaponAmmoEmpty", "my_mod.autoreload", function(player, weapon_ent)
weapon.reload(weapon_ent)
end) Cancels an in-progress reload.
void
weapon.cancel_reload(peer_id) Fires a projectile from the weapon.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player peer ID. |
| config | table? | Optional projectile override. |
void
weapon.fire_projectile(peer_id) Sets the spread modifier.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
| value | any | The spread modifier value. |
void
weapon.set_spread_modifier(value) Resets the spread modifier to default.
void
weapon.reset_spread_modifier(peer_id) Enables or disables Aim Down Sights (ADS) for a weapon. ADS reduces spread and changes the camera FOV.
| Name | Type | Description |
|---|---|---|
| weapon_ent | entity | Weapon entity. |
| ads | bool | True to enter ADS, false to leave. |
void
net.receive("ads_state", function(data)
weapon.set_ads(held_weapon, data.ads)
end) Returns true if ads.
boolean
if weapon.is_ads() then
print("true")
end Returns the ads progress.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_ads_progress() Returns the recoil.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_recoil() Returns the fire cooldown.
| Name | Type | Description |
|---|---|---|
| id | number | Weapon identifier. |
any
local val = weapon.get_fire_cooldown() Returns true if reloading.
boolean
if weapon.is_reloading() then
print("true")
end Creates a wheeled vehicle entity from a vehicle definition asset. Returns the vehicle entity handle.
| Name | Type | Description |
|---|---|---|
| def | string | table | Asset path (e.g. "vehicles/jeep") or inline vehicle definition table. |
| position | Vec3? | Spawn world position. Default: origin. |
| rotation | Quat? | Initial rotation. Default: identity. |
entity — The vehicle entity handle.
local jeep = vehicle.create("vehicles/jeep", Vec3.new(20, 0, 0))
net.replicate(jeep, { rate = 30 }) Destroys a vehicle entity, ejecting its driver and firing the VehicleDestroyed hook.
| Name | Type | Description |
|---|---|---|
| vehicle_ent | entity | Vehicle entity to destroy. |
void
timer.delay(30.0, function()
if entity.is_valid(abandoned_car) then
vehicle.destroy(abandoned_car)
end
end) Sets vehicle input (throttle, brake, steering).
| Name | Type | Description |
|---|---|---|
| value | any | The input value. |
void
vehicle.set_input(car, 1.0, 0.0, 0.0) Returns the rpm.
any
local val = vehicle.get_rpm() Returns the gear.
any
local val = vehicle.get_gear() Returns the current speed of the vehicle in m/s.
| Name | Type | Description |
|---|---|---|
| vehicle_ent | entity | Vehicle entity. |
number — Speed in m/s.
local spd = vehicle.get_speed(car) * 3.6 -- convert to km/h
ui.set_text(speedometer, string.format("%.0f km/h", spd)) Returns true if grounded.
boolean
if vehicle.is_grounded() then
print("true")
end Returns the wheel count.
number
local val = vehicle.get_wheel_count() Returns the wheel transform.
any
local val = vehicle.get_wheel_transform() Returns true if a wheel has ground contact.
void
if vehicle.wheel_has_contact(car, 0) then end Sets the engine torque curve.
| Name | Type | Description |
|---|---|---|
| value | any | The engine torque value. |
void
vehicle.set_engine_torque(car, 300) Enables or disables automatic transmission.
| Name | Type | Description |
|---|---|---|
| value | any | The transmission auto value. |
void
vehicle.set_transmission_auto(car, true) Sets the gear.
| Name | Type | Description |
|---|---|---|
| value | any | The gear value. |
void
vehicle.set_gear(value) Returns the wheel rpm.
any
local val = vehicle.get_wheel_rpm() Configures vehicle suspension parameters.
| Name | Type | Description |
|---|---|---|
| value | any | The suspension value. |
void
vehicle.set_suspension(car, { stiffness = 1.5, damping = 0.3 }) Returns a table of all currently connected player entities.
table — Array of player entity handles.
-- End round: show scores for all players
local players = player.get_all()
for _, p in ipairs(players) do
print(player.get_name(p), player.get_kills(p))
end Returns the number of currently connected players.
number — Connected player count.
if player.get_count() < 2 then
game.set_state("waiting")
end Returns the display name of a player entity as a string.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
string — The player's display name.
hook.add("PlayerConnect", "welcome", function(player)
local name = player.get_name(player)
net.broadcast("chat", { text = name .. " joined the game." })
end) Returns the network latency of a player in milliseconds.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
number — Ping in milliseconds.
local ping = player.get_ping(player)
ui.set_text(ping_label, ping .. "ms") Returns the entity.
| Name | Type | Description |
|---|---|---|
| id | number | Player identifier. |
entity
local val = player.get_entity() Returns the state.
| Name | Type | Description |
|---|---|---|
| id | number | Player identifier. |
string
local val = player.get_state() Returns the team ID of a player, or 0 if they are not on any team.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
number — Team ID, or 0 if unassigned.
local tid = player.get_team(player)
if tid == red_team_id then
print("Player is on red team")
end Returns the score.
| Name | Type | Description |
|---|---|---|
| id | number | Player identifier. |
number
local val = player.get_score() Returns the kill count of a player in the current round.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
number — Kill count.
local kills = player.get_kills(player)
ui.set_text(score_label, "Kills: " .. kills) Returns the death count of a player in the current round.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
number — Death count.
local kd = player.get_kills(p) / math.max(1, player.get_deaths(p))
print(string.format("K/D: %.2f", kd)) Returns the local player peer ID (client-only).
number
local my_id = player.local_id() Sets the state.
| Name | Type | Description |
|---|---|---|
| id | number | Player identifier. |
| value | any | The state value. |
void
player.set_state(value) Assigns a player to a team by team ID. Fires the PlayerChangedTeam hook.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| team_id | number | Target team ID. |
void
player.set_team(new_player, red_team_id) Sets the score.
| Name | Type | Description |
|---|---|---|
| id | number | Player identifier. |
| value | any | The score value. |
void
player.set_score(value) Adds score.
void
player.add_score(params) Increments the kill counter for a player by one.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
void
hook.add("CharacterDied", "scoreboard", function(victim, attacker)
if attacker and entity.has_tag(attacker, "player") then
player.add_kill(attacker)
player.add_death(victim)
end
end) Increments the death counter for a player by one.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
void
player.add_death(victim) Spawns the player character entity.
entity
player.spawn(peer_id, spawn_pos) Kills the player character.
void
player.kill(peer_id) Freezes the player, preventing movement.
void
player.freeze(peer_id, true) Kicks a player from the server with an optional reason string.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity to kick. |
| reason | string? | Kick reason shown to the player. |
void
player.kick(afk_player, "Kicked: AFK") Returns the ip.
| Name | Type | Description |
|---|---|---|
| id | number | Player identifier. |
any
local val = player.get_ip() Returns true if enabled.
boolean
if mod.is_enabled() then
print("true")
end Returns the mod.json metadata of the calling mod as a table.
table — Mod info: name, version, author, description.
local info = mod.get_info()
print(info.name, "v" .. info.version, "by", info.author) Returns the metadata.
any
local val = mod.get_metadata() Returns the all.
table
local val = mod.get_all() Returns the current mod info table.
any
local val = mod.get_current() Returns whether a mod with the given ID is currently loaded and active.
| Name | Type | Description |
|---|---|---|
| mod_id | string | Mod identifier to check. |
bool — True if the mod is loaded.
if mod.is_loaded("premium_weapons") then
weapon.create("weapons/railgun")
end Registers a callback for when the mod starts.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
mod.on_start(function()
print("Mod started!")
end) Registers a callback for when the mod stops.
| Name | Type | Description |
|---|---|---|
| callback | function | Callback function. |
void
mod.on_stop(function()
print("Mod stopping...")
end) Exposes a function under a name so other mods can call it via mod.call.
| Name | Type | Description |
|---|---|---|
| name | string | Export name other mods use to call this function. |
| fn | function | Function to export. |
void
-- Expose an API for other mods
mod.export("get_leaderboard", function()
return leaderboard_data
end) Calls an exported function from another mod by mod ID. Enables cross-mod communication without tight coupling.
| Name | Type | Description |
|---|---|---|
| mod_id | string | Target mod identifier (from mod.json). |
| function_name | string | Name of the exported function to call. |
| ... | any | Arguments forwarded to the target function. |
any — Return value(s) from the called function, or nil on error.
-- Call an inventory mod's API
local item_count = mod.call("inventory_mod", "get_item_count", player, "ammo_556") Returns all exported functions from a mod.
any
local exports = mod.get_exports("other_mod") Starts a mod by name.
void
mod.start("my_addon") Stops a running mod.
void
mod.stop("my_addon") Restarts a mod.
void
mod.restart("my_addon") Returns the state.
string
local val = mod.get_state() Returns the last error message for a mod.
any
local val = mod.get_error() Saves a key-value pair to persistent storage.
void
storage.save("highscore", 9999) Loads a value from persistent storage by key.
void
local score = storage.load("highscore") Deletes a key-value pair from a storage table.
| Name | Type | Description |
|---|---|---|
| table_name | string | Database table. |
| key | string | Row key to delete. |
void
storage.delete("temp_data", session_id) Returns whether a key exists in a storage table.
| Name | Type | Description |
|---|---|---|
| table_name | string | Database table name. |
| key | string | Row key to check. |
bool — True if the key exists.
if storage.has("bans", player_uid) then
player.kick(player, "You are banned.")
end Returns all keys in mod storage.
void
local keys = storage.keys() Clears all mod storage data.
void
storage.clear() Saves player-specific data to persistent storage.
void
storage.save_player(peer_id, "level", 5) Loads player-specific data from persistent storage.
void
local lvl = storage.load_player(peer_id, "level") Deletes player-specific data by key.
void
storage.delete_player(peer_id, "temp_data") Returns true if a player-specific key exists.
boolean
if storage.has_player(peer_id, "level") then end Returns all keys for a player in storage.
void
local keys = storage.player_keys(peer_id) Clears all storage data for a specific player.
void
storage.clear_player(peer_id) Runs a raw SQL SELECT query against this mod's database and returns the results as a table of row tables.
| Name | Type | Description |
|---|---|---|
| sql | string | SQL SELECT query string. |
| params | table? | Positional parameters for prepared statement binding. |
table — Array of row tables. Each row is a table of column name → value.
-- Top 10 players by kills
local rows = storage.query([[
SELECT key, value FROM player_stats
ORDER BY CAST(value AS INTEGER) DESC
LIMIT 10
]])
for i, row in ipairs(rows) do
print(i, row.key, row.value)
end Returns a leaderboard-style sorted list of all entries in a sorted datastore. Entries are ordered by numeric value, highest first by default. Use this for kill leaderboards, playtime rankings, or any top-N query. Backed by the SQLite datastore — fast even with thousands of entries.
| Name | Type | Description |
|---|---|---|
| store | string | Sorted datastore name (same one used with datastore.set_sorted / datastore.increment). |
| limit | number? | Maximum entries to return. Default: 10. |
| ascending | boolean? | True for ascending sort (lowest first). Default: false (highest first). |
table — Array of { key: string, value: number } pairs.
-- Display top-10 kill leaderboard in chat on round end
game.on_state("RoundEnd", function()
local top10 = datastore.get_ordered("kills", 10)
game.broadcast_chat("=== Kill Leaderboard ===")
for i, entry in ipairs(top10) do
game.broadcast_chat(string.format("#%d %s — %d kills", i, entry.key, entry.value))
end
end) Sets or overwrites a numeric value for a key in a sorted datastore. Use this when you have the exact final value (e.g. score from a match). For incrementing an existing value, prefer datastore.increment() to avoid race conditions.
| Name | Type | Description |
|---|---|---|
| store | string | Sorted datastore name. |
| key | string | Entry key — typically a player ID or username. |
| value | number | Numeric value to store. |
void
-- Save final score at round end
hook.add("OnRoundEnd", "save_scores", function()
for _, p in ipairs(player.get_all()) do
local id = tostring(player.get_id(p))
local score = player.get_score(p)
datastore.set_sorted("scores", id, score)
end
end) Gets the stored numeric value for a specific key in a sorted datastore. Returns nil if the key has never been set.
| Name | Type | Description |
|---|---|---|
| store | string | Sorted datastore name. |
| key | string | Entry key to look up. |
number? — Stored numeric value, or nil if not set.
-- Show a player their all-time kill record on join
hook.add("OnPlayerJoin", "show_record", function(player)
local id = tostring(player.get_id(player))
local record = datastore.get_sorted("kills", id) or 0
hud.show_notification(player, "Your record: " .. record .. " kills", 5)
end) Atomically increments (or decrements with a negative amount) a numeric value in a datastore. If the key does not exist, it is initialised to 0 before the increment. Returns the new value. Safe to call from concurrent hooks.
| Name | Type | Description |
|---|---|---|
| store | string | Datastore name. |
| key | string | Key to increment. |
| amount | number? | Amount to add. Default: 1. Use negative to decrement. |
number — The new value after the increment.
-- Track kills persistently across sessions
hook.add("OnPlayerKill", "track_kills", function(killer, victim)
if player.is_player(killer) then
local id = tostring(player.get_id(killer))
local total = datastore.increment("kills", id)
hud.show_notification(killer, "Total kills: " .. total, 2)
end
end) Returns an array of all keys currently stored in a datastore. Useful for iterating all player records, migration scripts, or admin tools. On large datastores, consider limiting usage to low-frequency operations.
| Name | Type | Description |
|---|---|---|
| store | string | Datastore name to enumerate. |
table — Array of key strings.
-- Admin command: print all players who have saved data
local keys = datastore.list_keys("player_data")
print(#keys .. " players with saved data:")
for _, k in ipairs(keys) do
local val = datastore.get_sorted("player_data", k)
print(" " .. k .. " = " .. tostring(val))
end Shows a temporary toast notification on the player's HUD. Multiple notifications stack vertically and auto-dismiss. The optional color parameter lets you distinguish types: white for info, yellow for warnings, red for danger. Client-side delivery is automatic over the network.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity to show the notification to. |
| text | string | Notification text. |
| duration | number? | Display duration in seconds. Default: 4. |
| color | Color3? | Text color. Default: white. |
void
-- Info: item pickup
hud.show_notification(player, "Picked up AK-47", 3)
-- Warning: taking damage outside safe zone
hud.show_notification(player, "Warning: leaving combat zone!", 5,
Color3.new(1, 0.8, 0))
-- Danger: low health
hud.show_notification(player, "Critical health!", 4,
Color3.new(1, 0.2, 0.2)) Displays narrative subtitle text at the bottom-centre of the player's screen, similar to cinematic subtitles. The text fades out after the duration. Use this for story events, NPC dialogue, or world event announcements rather than gameplay alerts.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| text | string | Subtitle text to display. |
| duration | number? | Display duration in seconds. Default: 4. |
void
-- Story event: earthquake
audio.play_global("sounds/earthquake.ogg")
for _, p in ipairs(player.get_all()) do
hud.show_subtitle(p, "The ground shook violently...", 4)
end
-- NPC dialogue line
hud.show_subtitle(player, "Guard: "Stop right there!"", 3) Shows a persistent objective text in the top-right corner of the player's HUD. Replaces the previous objective. Call hud.hide_objective() to clear it. Use short, action-oriented phrases.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| text | string | Objective text. Keep it short (under 60 chars). |
void
-- Update objective at each game phase
game.on_state("Active", function()
for _, p in ipairs(player.get_all()) do
hud.show_objective(p, "Capture Zone A")
end
end)
game.on_state("RoundEnd", function()
for _, p in ipairs(player.get_all()) do
hud.hide_objective(p)
end
end) Hides the objective text shown by hud.show_objective(). Has no effect if no objective is currently displayed.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
void
hud.hide_objective(player) Shows or updates a progress bar at the centre-bottom of the player's screen. Call repeatedly with increasing values to animate the fill. The bar persists until hud.hide_progress() is called. Only one progress bar is shown at a time per player.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| label | string | Label displayed above the bar (e.g. "Hacking...", "Reviving..."). |
| value | number | Fill amount (0 = empty, 1 = full). |
void
-- Hacking terminal: 5-second hold, animated progress bar
local hack_task = nil
interact.on_hold_begin(terminal_interact, function(player)
hud.show_progress(player, "Hacking...", 0.0)
hack_task = tween.value(0, 1, 5.0, function(v)
hud.show_progress(player, "Hacking...", v)
end)
end)
interact.on_triggered(terminal_interact, function(player)
hud.hide_progress(player)
hud.show_notification(player, "Hack successful!", 3)
end)
interact.on_hold_end(terminal_interact, function(player)
if hack_task then tween.cancel(hack_task) end
hud.hide_progress(player)
end) Hides the active progress bar from the player's HUD. Has no effect if no progress bar is showing.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
void
hud.hide_progress(player) Sets the crosshair style for a player. Built-in styles: "default", "dot", "cross", "circle". Pass nil to hide the crosshair entirely (useful for sniper scope overlays or custom UI crosshairs).
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| style | string? | Crosshair style name, or nil to hide. |
void
-- Swap crosshair on ADS
hook.add("OnADS", "crosshair_ads", function(player, is_ads)
if is_ads then
hud.set_crosshair(player, nil) -- hide default, show scope UI
else
hud.set_crosshair(player, "dot")
end
end) Flashes a directional hit indicator on the edges of the player's screen pointing toward the damage source. Higher damage values produce a more intense visual. Call this server-side immediately after applying damage.
| Name | Type | Description |
|---|---|---|
| player | entity | The player who was damaged. |
| attacker_pos | Vec3 | World position of the attacker or damage source. |
| damage | number | Damage amount — affects indicator intensity (0–100+). |
void
hook.add("OnPlayerDamaged", "damage_indicator", function(victim, attacker, dmg)
if player.is_player(victim) and entity.is_valid(attacker) then
local pos = entity.get_position(attacker)
hud.show_damage_indicator(victim, pos, dmg)
end
end) Flashes a hitmarker on the shooter's HUD to confirm a successful hit. Pass headshot=true for a distinct headshot marker (typically a different color or sound). Call this server-side on the shooter when a hit registers.
| Name | Type | Description |
|---|---|---|
| player | entity | The player who landed the hit. |
| headshot | boolean? | True to show a headshot hitmarker. Default: false. |
void
hook.add("OnWeaponHit", "hitmarker", function(shooter, victim, hit_info)
if player.is_player(shooter) then
local is_head = hit_info.hitgroup == "head"
hud.show_hitmarker(shooter, is_head)
if is_head then
hud.show_notification(shooter, "Headshot!", 1.5, Color3.new(1, 0.8, 0))
end
end
end) Creates a 3D waypoint marker visible on the player's HUD as a world-space pin with an optional text label. The waypoint also appears on the minimap. Returns a handle — store it to call hud.remove_waypoint() later.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity to show the waypoint to. |
| position | Vec3 | World position of the waypoint. |
| label | string? | Optional text label shown next to the marker. |
| color | Color3? | Marker color. Default: white. |
waypoint — Waypoint handle. Pass to hud.remove_waypoint() to clean up.
-- Show mission objective waypoint, remove when player arrives
local wp = hud.create_waypoint(player, objective_pos, "Extract Here",
Color3.new(1, 1, 0))
local arrive_zone = zone.create({ position = objective_pos, radius = 5 })
zone.on_enter(arrive_zone, function(ent)
if ent == player then
hud.remove_waypoint(wp)
zone.destroy(arrive_zone)
end
end) Removes a waypoint created with hud.create_waypoint(). The marker disappears immediately from the player's HUD and minimap.
| Name | Type | Description |
|---|---|---|
| waypoint_handle | waypoint | Waypoint handle returned by hud.create_waypoint(). |
void
hud.remove_waypoint(objective_wp) Converts a 3D world position to 2D screen coordinates.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World-space position. |
void
local sx, sy = render.world_to_screen(world_pos) Returns the camera forward direction vector.
Vec3
local fwd = render.get_camera_forward() Draws a debug line in world space for this frame. Useful for visualising paths, rays, and connections.
| Name | Type | Description |
|---|---|---|
| from | Vec3 | Start position. |
| to | Vec3 | End position. |
| color | Color3? | Line color. Default: white. |
| duration | number? | How many seconds to show. Default: one frame. |
void
render.draw_line(origin, target, Color3.new(1,0,0), 1.0) Draws a wireframe box in world space for debugging collision bounds or zones.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | Box centre. |
| size | Vec3 | Box half-extents. |
| color | Color3? | Line color. |
| duration | number? | Display duration in seconds. |
void
render.draw_box(pos, Vec3.new(1,1,1), Color3.new(0,1,0)) Draws a wireframe sphere in world space.
| Name | Type | Description |
|---|---|---|
| center | Vec3 | Sphere centre. |
| radius | number | Sphere radius. |
| color | Color3? | Line color. |
| duration | number? | Display duration in seconds. |
void
render.draw_sphere(npc_pos, 5, Color3.new(1,1,0)) Renders a billboard text label at a world-space position, always facing the camera.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World position for the label. |
| text | string | Text to display. |
| color | Color3? | Text color. |
| duration | number? | Display duration. |
void
render.draw_text_3d(entity.get_position(e), "Enemy", Color3.new(1,0,0)) Creates a persistent beam effect between two attachment points.
| Name | Type | Description |
|---|---|---|
| from | entity | Vec3 | Start attachment (entity or world position). |
| to | entity | Vec3 | End attachment. |
| props | table? | Properties: color, width, texture, segments. |
effect — Beam effect handle.
local beam = render.create_beam(tower_a, tower_b, { color = Color3.new(0,0.5,1), width = 0.1 }) Attaches a motion trail effect to an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to attach the trail to. |
| props | table? | Properties: color, width, lifetime, texture. |
effect — Trail effect handle.
local trail = render.create_trail(bullet, { color = Color3.new(1,0.8,0), lifetime = 0.3 }) Removes a beam or trail effect created with render.create_beam / render.create_trail.
| Name | Type | Description |
|---|---|---|
| effect | effect | Effect handle to remove. |
void
render.remove_effect(beam) Applies or removes a color outline/highlight on an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to highlight. |
| color | Color3? | Highlight color. Pass nil to remove. |
| fill_alpha | number? | Interior fill transparency (0–1). |
void
render.set_highlight(target, Color3.new(1,0,0), 0.2) Converts a 2D screen position (pixels) to a world-space ray for picking and aiming.
| Name | Type | Description |
|---|---|---|
| screen_pos | Vec2 | Screen position in pixels. |
Vec3, Vec3 — origin, direction.
local origin, dir = render.screen_to_ray(Vec2.new(960, 540))
local hit = physics.raycast(origin, dir, 200) Returns the current render target resolution in pixels.
number, number — width, height.
local w, h = render.get_screen_size()
print("Resolution:", w, "x", h) Captures the current frame and saves it to a file. Callback is called when the file is written.
| Name | Type | Description |
|---|---|---|
| path | string | Output file path (PNG). |
| callback | function? | Called with (success, path) when done. |
void
render.screenshot("screenshots/round_end.png", function(ok, p)
if ok then print("Saved:", p) end
end) Overrides the tint color of an entity's material. Pass nil to remove the override.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| color | Color3? | Tint color, or nil to restore default. |
void
render.set_color_override(player, team_color) Adds a named hook callback for an event.
| Name | Type | Description |
|---|---|---|
| event | string | Hook event name. |
| name | string | Unique callback identifier. |
| callback | function | Callback function. |
void
hook.Add("PlayerJoined", "welcome", function(peer_id)
print("Welcome!")
end) Removes a named hook callback.
| Name | Type | Description |
|---|---|---|
| event | string | Hook event name. |
| name | string | Callback identifier to remove. |
void
hook.Remove("PlayerJoined", "welcome") Fires a hook event, calling all registered callbacks.
| Name | Type | Description |
|---|---|---|
| event | string | Hook event name to fire. |
| ... | any | Arguments passed to callbacks. |
any
hook.Run("CustomEvent", player_id, data) Returns the hook table for an event name.
| Name | Type | Description |
|---|---|---|
| event | string | Hook event name. |
table
local hooks = hook.GetTable("PlayerJoined") Ends the current round, transitions to the "ended" state, and fires the RoundEnd hook.
| Name | Type | Description |
|---|---|---|
| winner | number | entity | nil | Winning team ID, winning player, or nil for a draw. |
void
hook.add("Think", "round_timer", function()
if game.get_state() == "playing" and game.get_elapsed_time() > 300 then
game.end_round(nil) -- time limit draw
end
end) Returns the current round number.
any
local round = game.get_round() Returns the remaining time in the current round.
any
local time_left = game.get_round_time_left() Returns the current game state string. States are defined by the server mod. Common states: "waiting", "starting", "playing", "ended".
string — Current game state name.
if game.get_state() == "playing" then
-- Allow player actions
end Returns how long the current game state has been active.
string
local elapsed = game.get_state_time() Restarts the current round.
void
game.restart_round() Sets the round time limit in seconds.
| Name | Type | Description |
|---|---|---|
| value | any | The round time value. |
void
game.set_round_time(300) Transitions the game to a new state and fires the GameStateChanged hook. Server-side only.
| Name | Type | Description |
|---|---|---|
| state | string | New state name string. |
void
-- Start round when enough players connect
hook.add("PlayerConnect", "check_start", function()
if player.get_count() >= 2 and game.get_state() == "waiting" then
game.set_state("starting")
timer.delay(5.0, function()
game.set_state("playing")
end)
end
end) Returns whether the NPC can currently see a specific target entity. Checks if the target is within the vision cone range and angle, then performs a physics raycast for line-of-sight.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| target | entity | Entity to test visibility for. |
boolean — True if the target is within the vision cone and not occluded.
-- Only attack if NPC actually sees the player
hook.add("Think", "guard.ai", function()
for _, guard in ipairs(entity.find_by_tag("guard")) do
for _, p in ipairs(player.get_all()) do
if npc.can_see(guard, p) then
npc.set_behavior(guard, "hostile")
end
end
end
end) Creates an NPC entity from a character definition asset or inline table and places it at the given position. The NPC starts in "idle" behavior by default. Server-side only.
| Name | Type | Description |
|---|---|---|
| def | string | table | Asset path (e.g. "npcs/guard") or inline definition table with keys: model, health, speed, run_speed. |
| position | Vec3? | Spawn position. Default: world origin. |
entity — NPC entity handle, or nil on failure.
-- Create a patrolling guard NPC
local guard = npc.create("npcs/guard", Vec3.new(10, 0, 5))
npc.set_hostile(guard, true)
npc.set_vision(guard, 25, 140)
npc.set_patrol(guard, {
Vec3.new(10, 0, 5),
Vec3.new(20, 0, 5),
Vec3.new(20, 0, 15),
})
npc.set_behavior(guard, "patrol") Destroys an NPC entity and cleans up all associated AI state, callbacks, and navigation data. Server-side only.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity to destroy. |
void
-- Remove NPC when the round ends
hook.add("RoundEnd", "npc.cleanup", function()
for _, n in ipairs(npc.get_all()) do
npc.destroy(n)
end
end) Commands the NPC to follow a target entity, re-pathing whenever the target moves more than a threshold distance away. The NPC stops when within the preferred distance.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| target | entity | Entity to follow. |
| distance | number? | Preferred follow distance in metres. Default: 3. |
void
-- Companion NPC follows the local player
local companion = npc.create("npcs/ally", spawn_pos)
npc.set_behavior(companion, "follow")
npc.follow(companion, local_player, 2.5)
npc.set_running(companion, false) Returns a table of all currently alive NPC entities in the world. Use entity.find_by_tag for a filtered subset.
table — Array of NPC entity handles.
-- Activate all NPCs when round starts
local all_npcs = npc.get_all()
print(#all_npcs, "NPCs in world")
for _, n in ipairs(all_npcs) do
npc.set_behavior(n, "wander")
end Returns the current behavior mode name of an NPC as a string. Returns "idle" if no behavior has been explicitly set.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
string — Current behavior mode name.
local b = npc.get_behavior(guard)
if b ~= "hostile" then
npc.set_behavior(guard, "patrol")
end Returns all sound events the NPC detected this tick within its hearing radius. Each entry has position (Vec3) and loudness (0–1, where 1 is maximum).
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
table — Array of { position: Vec3, loudness: number } entries.
-- Stealth: zombie investigates loudest noise
local sounds = npc.get_nearby_sounds(zombie)
local loudest, max_loud = nil, 0
for _, s in ipairs(sounds) do
if s.loudness > max_loud then
loudest, max_loud = s.position, s.loudness
end
end
if loudest then npc.move_to(zombie, loudest) end Returns all entities currently visible to the NPC within its configured vision cone and range. Performs a line-of-sight raycast for each candidate.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
table — Array of visible enemy entity handles, empty if none.
-- Target the closest visible enemy
local enemies = npc.get_visible_enemies(guard)
if #enemies > 0 then
local closest = entity.find_nearest(entity.get_position(guard), "player")
if closest then npc.look_at(guard, closest) end
end Returns whether an entity is an NPC (has an AI controller component). Use this to safely distinguish NPCs from players and props in collision or damage callbacks.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to test. |
boolean — True if it is an NPC.
hook.add("CollisionEnter", "npc_check", function(a, b)
if npc.is_npc(b) then
character.damage(b, 10, "collision")
end
end) Makes the NPC immediately face a world position or entity. Rotates only the NPC's yaw (Y axis) to avoid unnatural tilting.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| target | Vec3 | entity | Position or entity to face. |
void
-- Guard looks at every player who enters its zone
zone.on_enter(guard_zone, function(e)
if entity.has_tag(e, "player") then
npc.look_at(guard, e)
npc.stop(guard)
end
end) Commands the NPC to navigate to a world position using the baked NavMesh. Fires the on_reached_target callback on arrival. Requires navmesh.bake() to have been called.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| target | Vec3 | Destination world position. |
void
-- Alert guard: investigate a suspicious noise
npc.on_hear_sound(guard, function(me, pos, loudness)
if loudness > 0.4 then
npc.set_behavior(me, "idle")
npc.move_to(me, pos)
end
end) Registers a callback fired whenever the NPC takes damage. Useful for triggering AI reactions such as running away, retaliating, or playing hit animations.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| callback | function | Called with (npc_ent, attacker: entity, damage: number, damage_type: string). |
void
npc.on_damaged(boss, function(me, attacker, dmg, dmg_type)
local hp = character.get_health(me)
-- Enrage below 50% HP
if hp < 50 and npc.get_behavior(me) ~= "enraged" then
npc.set_behavior(me, "hostile")
npc.set_running(me, true)
npc.set_speed(me, 8.0)
end
-- Always face the attacker
if entity.is_valid(attacker) then
npc.look_at(me, attacker)
end
end) Registers a callback fired each time the NPC detects a sound within its hearing radius. The loudness value (0–1) is inversely proportional to distance from the source.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| callback | function | Called with (npc_ent, position: Vec3, loudness: number). |
void
npc.on_hear_sound(zombie, function(me, pos, loudness)
-- Only react to sounds above a threshold
if loudness > 0.3 then
npc.set_behavior(me, "hostile")
npc.move_to(me, pos)
end
end) Registers a callback fired when the NPC successfully arrives at its move_to destination within the arrival tolerance radius.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| callback | function | Called with (npc_ent, target_position: Vec3). |
void
-- Guard investigates noise then resumes patrol
npc.on_hear_sound(guard, function(me, pos, _)
npc.move_to(me, pos)
end)
npc.on_reached_target(guard, function(me, pos)
-- Look around then go back to patrol
timer.delay(3.0, function()
npc.set_behavior(me, "patrol")
end)
end) Registers a callback fired the moment the NPC first spots an enemy (enters vision cone with LOS). Only fires on the initial detection, not continuously.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| callback | function | Called with (npc_ent, enemy_entity). |
void
npc.on_see_enemy(guard, function(me, enemy)
-- Alert nearby guards
local nearby = entity.find_in_sphere(entity.get_position(me), 30, "guard")
for _, g in ipairs(nearby) do
npc.set_behavior(g, "hostile")
npc.look_at(g, enemy)
end
net.broadcast("enemy_spotted", { pos = entity.get_position(enemy) })
end) Registers a callback fired whenever the NPC's AI state transitions. Useful for playing animations, sounds, or UI updates tied to behavior changes.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| callback | function | Called with (npc_ent, new_state: string, old_state: string). |
void
npc.on_state_changed(guard, function(me, new_state, old_state)
if new_state == "hostile" then
audio.play("sounds/guard_alert.ogg", entity.get_position(me))
animation.crossfade(me, "run", 0.2)
elseif new_state == "patrol" then
animation.crossfade(me, "walk", 0.3)
end
end) Sets the AI behavior mode. Built-in modes: "idle" (stand still), "wander" (roam randomly), "follow" (track a target), "patrol" (walk a waypoint path), "hostile" (attack enemies in range). Custom behavior names can be registered via hook.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| behavior | string | Behavior mode name. |
void
-- State machine: idle → alert → hostile
npc.on_see_enemy(guard, function(me, enemy)
if npc.get_behavior(me) == "patrol" then
npc.set_behavior(me, "hostile")
npc.look_at(me, enemy)
audio.play("sounds/alert.ogg", entity.get_position(me))
end
end) Sets the omnidirectional hearing radius of an NPC. Any audio.play call within range triggers the on_hear_sound callback with the source position and normalized loudness (0–1).
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| radius | number | Hearing radius in metres. |
void
-- Sensitive guard hears gunshots from 30m away
npc.set_hearing(guard, 30)
npc.on_hear_sound(guard, function(me, pos, loud)
if loud > 0.6 then
npc.set_behavior(me, "hostile")
npc.move_to(me, pos)
end
end) Enables or disables hostile aggression. Hostile NPCs automatically attack entities tagged "player" or "enemy" when they enter the NPC's vision cone or hearing range.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| hostile | boolean | True to enable aggression, false to make passive. |
void
-- Spawn wave of hostile zombies
for i = 1, 5 do
local z = npc.create("npcs/zombie", spawn_pos + Vec3.new(i*2, 0, 0))
npc.set_hostile(z, true)
npc.set_vision(z, 20, 180)
npc.set_hearing(z, 15)
npc.set_behavior(z, "wander")
end Assigns an ordered patrol path to an NPC. The NPC visits each waypoint in sequence, looping by default. Set behavior to "patrol" to start patrolling.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| points | table | Ordered array of Vec3 waypoints. |
| loop | boolean? | Loop the path when the last point is reached. Default: true. |
void
local guard = npc.create("npcs/guard", Vec3.new(0, 0, 0))
npc.set_patrol(guard, {
Vec3.new(0, 0, 0),
Vec3.new(20, 0, 0),
Vec3.new(20, 0, 20),
Vec3.new(0, 0, 20),
}, true)
npc.set_behavior(guard, "patrol") Enables or disables running mode on an NPC. When running, the NPC uses its run_speed value instead of its walk speed. Typically triggered when an enemy is spotted.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| running | boolean | True to run, false to walk. |
void
-- Zombie runs when it spots a player
npc.on_see_enemy(zombie, function(me, enemy)
npc.set_running(me, true)
npc.follow(me, enemy)
end) Sets the walk speed of an NPC in m/s. This is the base speed used when not running. Typical values: zombie 1.5, guard 3.0, dog 5.0.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| speed | number | Walk speed in m/s. |
void
-- Slow down injured NPC
npc.on_damaged(zombie, function(me, _, dmg, _)
local hp = character.get_health(me)
npc.set_speed(me, math.max(0.5, hp / 100 * 2.0))
end) Configures the NPC's vision cone used for enemy detection. A 360-degree angle means the NPC has full peripheral vision. Vision is line-of-sight checked against physics geometry.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| range | number | Vision range in metres. |
| angle | number | Total field-of-view angle in degrees (e.g. 120 = 60° each side). |
void
-- Sniper: narrow but long-range vision
npc.set_vision(sniper, 100, 40)
-- Zombie: wide, short-range tunnel vision
npc.set_vision(zombie, 12, 200) Configures wander behavior: the NPC picks random destinations within a circle around its spawn position, pausing briefly between moves. Set behavior to "wander" to activate.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
| radius | number | Wander radius in metres from the NPC's home position. |
void
-- Villager wanders near the town center
local villager = npc.create("npcs/villager", town_center)
npc.set_wander(villager, 20)
npc.set_behavior(villager, "wander") Immediately halts the NPC's current movement and cancels any pending move_to command. The NPC stays in its current behavior mode.
| Name | Type | Description |
|---|---|---|
| npc_ent | entity | NPC entity. |
void
-- Freeze all guards during cutscene
local guards = entity.find_by_tag("guard")
for _, g in ipairs(guards) do
npc.stop(g)
character.set_freeze(g, true)
end Adds a player to a voice channel.
| Name | Type | Description |
|---|---|---|
| channel | string | Channel name. |
| peer_id | number | Peer ID. |
void
voice.add_to_channel("team_red", peer_id) Creates a named voice channel (e.g. team chat, radio).
| Name | Type | Description |
|---|---|---|
| name | string | Channel name. |
void
voice.create_channel("team_red") Destroys a named voice channel.
| Name | Type | Description |
|---|---|---|
| name | string | Channel name. |
void
voice.destroy_channel("team_red") Returns a list of peer IDs currently transmitting voice audio.
table — Array of peer ID numbers.
for _, pid in ipairs(voice.get_active_speakers()) do
print("Speaking:", pid)
end Returns a list of peer IDs in a voice channel.
| Name | Type | Description |
|---|---|---|
| channel | string | Channel name. |
table — Array of peer ID numbers.
local members = voice.get_channel_members("team_red") Returns the current microphone input gain.
number — Input volume.
print("Mic gain:", voice.get_input_volume()) Returns the current speaker output volume.
number — Output volume.
print("Speaker vol:", voice.get_output_volume()) Returns a list of channel names a player belongs to.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
table — Array of channel name strings.
local channels = voice.get_player_channels(peer_id) Returns the per-player volume override.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
number — Volume level.
print("Player vol:", voice.get_player_volume(peer_id)) Returns the current proximity voice range.
number — Proximity range.
print("Voice range:", voice.get_proximity_range()) Returns the RMS audio level (0-1) for a currently speaking peer.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
number — RMS volume level [0, 1].
local lvl = voice.get_speaker_volume(peer_id)
if lvl > 0.5 then print("Loud!") end Returns true if the given player is locally muted.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
boolean
if voice.is_muted(player) then print("Muted") end Returns true if a specific player is currently transmitting voice (server-side).
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
boolean
if voice.is_player_transmitting(pid) then
print("Player is talking")
end Returns true if the local client is currently transmitting voice.
boolean
if voice.is_transmitting() then print("Mic is live") end Mutes a specific player in voice chat.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player to mute. |
void
voice.mute_player(peer_id) Registers a callback fired when a player starts speaking.
| Name | Type | Description |
|---|---|---|
| callback | function | Function receiving (peer_id: number). |
void
voice.on_start_speaking(function(pid)
print("Player", pid, "started talking")
end) Registers a callback fired when a player stops speaking.
| Name | Type | Description |
|---|---|---|
| callback | function | Function receiving (peer_id: number). |
void
voice.on_stop_speaking(function(pid)
print("Player", pid, "stopped talking")
end) Removes a player from a voice channel.
| Name | Type | Description |
|---|---|---|
| channel | string | Channel name. |
| peer_id | number | Peer ID. |
void
voice.remove_from_channel("team_red", peer_id) Sets the audio mode for a channel ("proximity" or "global").
| Name | Type | Description |
|---|---|---|
| channel | string | Channel name. |
| mode | string | Mode: "proximity" or "global". |
void
voice.set_channel_mode("radio", "global") Sets the proximity range for a channel (only applies in proximity mode).
| Name | Type | Description |
|---|---|---|
| channel | string | Channel name. |
| range | number | Range in world units. |
void
voice.set_channel_range("team_red", 50) Sets the microphone input gain (0.0 = silent, 1.0 = normal, 2.0 = boosted).
| Name | Type | Description |
|---|---|---|
| vol | number | Input volume multiplier. |
void
voice.set_input_volume(1.5) -- boost mic Sets the maximum distance at which the local player can hear other players.
| Name | Type | Description |
|---|---|---|
| range | number | Listener range in world units. |
void
voice.set_listener_range(50) Sets the speaker output volume for all incoming voice (0.0 = silent, 1.0 = normal).
| Name | Type | Description |
|---|---|---|
| vol | number | Output volume multiplier. |
void
voice.set_output_volume(0.7) Sets a pitch shift for a specific player's voice (0.5 = low, 1.0 = normal, 2.0 = high).
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
| pitch | number | Pitch multiplier [0.5, 2.0]. |
void
voice.set_player_pitch(peer_id, 1.5) -- chipmunk mode Sets a per-player proximity range override.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
| range | number | Proximity range in world units. |
void
voice.set_player_range(peer_id, 100) -- hear this player from further Sets a per-player volume override for incoming voice.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID. |
| vol | number | Volume [0, 2]. |
void
voice.set_player_volume(peer_id, 0.3) -- quiet this player Sets the 3D proximity range within which players can hear each other.
| Name | Type | Description |
|---|---|---|
| range | number | Proximity range in world units. |
void
voice.set_proximity_range(30) Begins capturing and transmitting microphone audio.
void
voice.start_transmit() Stops capturing and transmitting microphone audio.
void
voice.stop_transmit() Unmutes a specific player in voice chat.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Player to unmute. |
void
voice.unmute_player(peer_id) Creates a new Vec3 with the given x, y, z components.
| Name | Type | Description |
|---|---|---|
| x | number | X component. |
| y | number | Y component. |
| z | number | Z component. |
Vec3
local v = vec3.new(1, 2, 3) Returns a unit-length version of the given Vec3.
| Name | Type | Description |
|---|---|---|
| v | Vec3 | Input vector. |
Vec3 — Unit vector.
local dir = vec3.normalize(velocity) Returns the dot product of two Vec3 values.
| Name | Type | Description |
|---|---|---|
| a | Vec3 | First vector. |
| b | Vec3 | Second vector. |
number — Dot product.
local d = vec3.dot(a, b) Returns the cross product of two Vec3 values.
| Name | Type | Description |
|---|---|---|
| a | Vec3 | First vector. |
| b | Vec3 | Second vector. |
Vec3 — Cross product.
local perp = vec3.cross(a, b) Linearly interpolates between two Vec3 values.
| Name | Type | Description |
|---|---|---|
| a | Vec3 | Start vector. |
| b | Vec3 | End vector. |
| t | number | Interpolation factor [0, 1]. |
Vec3 — Interpolated vector.
local mid = vec3.lerp(a, b, 0.5) Returns the Euclidean distance between two Vec3 positions.
| Name | Type | Description |
|---|---|---|
| a | Vec3 | First position. |
| b | Vec3 | Second position. |
number — Distance.
local dist = vec3.distance(pos_a, pos_b)
if dist < 5 then print("Near!") end Returns the world forward vector (0, 0, -1).
Vec3 — (0, 0, -1)
local fwd = vec3.forward() Returns the world right vector (1, 0, 0).
Vec3 — (1, 0, 0)
local r = vec3.right() Returns the world up vector (0, 1, 0).
Vec3 — (0, 1, 0)
local up = vec3.up() Returns a Vec3 with all components set to zero.
Vec3 — (0, 0, 0)
local v = vec3.zero() Returns a Vec3 with all components set to one.
Vec3 — (1, 1, 1)
local v = vec3.one() Configures bloom post-processing parameters.
| Name | Type | Description |
|---|---|---|
| intensity | number | Bloom intensity. |
| threshold | number? | Brightness threshold. |
void
postfx.set_bloom(0.8, 1.0) Globally enables or disables all post-processing effects.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable post-processing. |
void
postfx.set_enabled(false) Sets the scene exposure (EV compensation).
| Name | Type | Description |
|---|---|---|
| exposure | number | Exposure value. |
void
postfx.set_exposure(1.2) Enables or disables FXAA anti-aliasing.
| Name | Type | Description |
|---|---|---|
| value | any | The fxaa value. |
void
postfx.set_fxaa(true) Sets the overall post-processing quality preset (0=Low, 1=Medium, 2=High, 3=Ultra).
| Name | Type | Description |
|---|---|---|
| quality | number | Quality tier 0-3. |
void
postfx.set_quality(2) Sets the tone mapping operator by name: "aces", "reinhard", "linear", "filmic".
| Name | Type | Description |
|---|---|---|
| operator | string | Tonemap operator name. |
void
postfx.set_tonemap("aces") Sets vignette strength and radius.
| Name | Type | Description |
|---|---|---|
| intensity | number | Vignette intensity [0, 1]. |
| radius | number? | Vignette radius (default 0.75). |
void
postfx.set_vignette(0.4, 0.75) Enables or disables the vignette effect.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable. |
void
postfx.set_vignette_enabled(true) Enables or disables depth-of-field.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable DOF. |
void
postfx.set_dof_enabled(true) Sets the depth-of-field focus distance in world units.
| Name | Type | Description |
|---|---|---|
| distance | number | Focus distance. |
void
postfx.set_dof_focus(10.0) Sets the depth-of-field aperture (controls blur amount).
| Name | Type | Description |
|---|---|---|
| aperture | number | Aperture f-number. |
void
postfx.set_dof_aperture(2.8) Enables or disables near-field blur for depth of field.
| Name | Type | Description |
|---|---|---|
| enabled | bool | True to enable near blur. |
void
postfx.set_dof_near_blur_enabled(false) Applies a preset DOF configuration: "portrait", "wide", "macro", "disabled".
| Name | Type | Description |
|---|---|---|
| preset | string | Preset name. |
void
postfx.set_dof_preset("portrait") Returns a table with the current post-processing settings.
table — { bloom_intensity, exposure, tonemap, vignette, fxaa_enabled, dof_enabled }.
local info = postfx.get_info()
print("Tonemap:", info.tonemap) Returns the current depth-of-field settings.
any
local dof = postfx.get_dof_info() Clears all messages from the in-game console output.
void
console.clear() Registers a console command with a callback.
| Name | Type | Description |
|---|---|---|
| name | string | Command name. |
| callback | function | Command handler. |
| description | string? | Help text. |
void
console.register("teleport", function(args)
print("Teleporting...")
end, "Teleport to a position") Returns true if the in-game console is currently visible. Client-side only.
boolean
if console.is_open() then
print("Console is open")
end Adds a generic spawn point at a position.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | Spawn position. |
| rotation | Vec3? | Spawn rotation. |
void
spawn.add(vec3.new(0, 1, 0)) Removes all spawn points.
void
spawn.clear() Returns a random spawn position.
any
local pos = spawn.get_random() Adds a team-specific spawn point.
| Name | Type | Description |
|---|---|---|
| team_id | number | Team identifier. |
| position | Vec3 | Spawn position. |
void
spawn.add_team(1, vec3.new(10, 1, 0)) Returns a random spawn position for a team.
any
local pos = spawn.get_random_team(1) Creates a new team with a given name and optional configuration. Returns the team ID.
| Name | Type | Description |
|---|---|---|
| name | string | Display name for the team. |
| options | table? | Options: color (Color3), max_players (number), friendly_fire (bool). |
number — The new team ID.
-- Create two teams at game start
local red = team.create("Red", { color = Color3.new(1, 0.2, 0.2), max_players = 8 })
local blue = team.create("Blue", { color = Color3.new(0.2, 0.4, 1), max_players = 8 }) Removes a team by ID.
void
team.remove(team_id) Returns a table of all active team IDs.
table — Array of team ID numbers.
for _, tid in ipairs(team.get_all()) do
print("Team:", tid, "score:", team.get_score(tid))
end Returns the count.
| Name | Type | Description |
|---|---|---|
| id | number | Team identifier. |
number
local val = team.get_count() Returns a table of all player entities currently on a given team.
| Name | Type | Description |
|---|---|---|
| team_id | number | Team ID to query. |
table — Array of player entity handles.
local reds = team.get_players(red_id)
print("Red team size:", #reds) Returns the total score of a team.
| Name | Type | Description |
|---|---|---|
| team_id | number | Team ID to query. |
number — Team score.
local rs = team.get_score(red_id)
local bs = team.get_score(blue_id)
ui.set_text(scoreboard, rs .. " — " .. bs) Sets the score.
| Name | Type | Description |
|---|---|---|
| id | number | Team identifier. |
| value | any | The score value. |
void
team.set_score(value) Auto-assigns a player to the team with fewest members.
void
team.auto_assign(peer_id) Creates a world-space marker (cylinder, sphere, arrow, or checkpoint ring) at a given position.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World position. |
| props | table? | Properties: type ("cylinder"|"sphere"|"arrow"), color, scale, alpha. |
marker — Marker handle.
local m = marker.create(Vec3.new(0,0,0), { type="cylinder", color=Color3.new(0,1,0) }) Removes a world marker.
| Name | Type | Description |
|---|---|---|
| marker_handle | marker | Marker to remove. |
void
marker.remove(m) Registers this server with the master server so it appears in public listings.
| Name | Type | Description |
|---|---|---|
| name | string | Server display name. |
| port | number | Server port. |
void
masterserver.register("My Server", 27015) Removes this server from the master server public listing.
void
masterserver.unregister() Sends a query to the master server to refresh the server list asynchronously.
void
masterserver.query() Returns the most recently fetched list of public servers.
table — Array of { ip, port, name, players, max_players, ping } tables.
for _, s in ipairs(masterserver.get_list()) do
print(s.name, s.players .. "/" .. s.max_players)
end Returns true if a master server query is currently in progress.
boolean
if masterserver.is_query_pending() then
print("Fetching servers...")
end Shows or hides the minimap for a player.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| enabled | boolean | True to show, false to hide. |
void
minimap.enable(player, true) Sets the zoom level of the minimap. Higher values show a larger area.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| zoom | number | Zoom level (default: 1.0). |
void
minimap.set_zoom(player, 2.0) Adds a custom icon to the minimap at a world position.
| Name | Type | Description |
|---|---|---|
| player | entity | Player to show the icon to. |
| position | Vec3 | World position. |
| icon | string | Icon asset path. |
| color | Color3? | Icon tint color. |
icon — Icon handle.
local icon = minimap.add_icon(player, base_pos, "icons/flag", Color3.new(0,0,1)) Removes an icon from the minimap.
| Name | Type | Description |
|---|---|---|
| icon_handle | icon | Icon handle to remove. |
void
minimap.remove_icon(icon) Serializes a Lua table (or value) to a JSON string.
| Name | Type | Description |
|---|---|---|
| value | any | Value to encode. |
string — JSON-encoded string.
local s = json.encode({ name = "Alice", score = 42 })
print(s) Parses a JSON string and returns the equivalent Lua table.
| Name | Type | Description |
|---|---|---|
| str | string | JSON string to parse. |
any — Decoded Lua value.
local data = json.decode('{"hp":100}')
print(data.hp) Stores a value in the server session (in-memory, lost on restart). Scoped to the mod.
| Name | Type | Description |
|---|---|---|
| key | string | Key name. |
| value | any | Value to store. |
void
session.set("round_number", 1) Retrieves a session value by key.
| Name | Type | Description |
|---|---|---|
| key | string | Key name. |
| default | any? | Default value if key is not set. |
any — Stored value or default.
local round = session.get("round_number", 0) Removes a session key.
| Name | Type | Description |
|---|---|---|
| key | string | Key to remove. |
void
session.remove("round_number") Saves a value to persistent client-side local storage (survives session restarts).
| Name | Type | Description |
|---|---|---|
| key | string | Key name. |
| value | string | number | boolean | Value to persist. |
void
client_storage.set("settings.fov", 90) Retrieves a value from persistent client-side local storage.
| Name | Type | Description |
|---|---|---|
| key | string | Key name. |
| default | any? | Default value if key does not exist. |
any — Stored value or default.
local fov = client_storage.get("settings.fov", 75) Adds a ban entry for a player IP with an optional duration and reason.
| Name | Type | Description |
|---|---|---|
| ip | string | IP address to ban. |
| reason | string | Ban reason. |
| duration | number? | Duration in seconds, or nil for permanent. |
void
ban.add("1.2.3.4", "cheating", 86400) Removes the ban for a given IP address.
| Name | Type | Description |
|---|---|---|
| ip | string | IP address to unban. |
void
ban.remove("1.2.3.4") Returns true if the given IP is currently banned.
| Name | Type | Description |
|---|---|---|
| ip | string | IP address to check. |
boolean
if ban.is_banned("1.2.3.4") then
print("IP is banned")
end Returns a table of all active ban entries.
table — Array of { ip, reason, expiry } tables.
for _, b in ipairs(ban.list()) do
print(b.ip, b.reason)
end Kicks a connected player and immediately adds a ban for their IP.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity to kick and ban. |
| reason | string | Kick/ban reason. |
| duration | number? | Duration in seconds, or nil for permanent. |
void
ban.kick_and_ban(player, "griefing", 3600) Creates a billboard GUI attached to an entity, always facing the camera.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to attach the billboard to. |
| props | table? | Properties: size (Vec2), offset (Vec3), always_on_top (bool). |
billboard — Billboard handle.
local bb = billboard.create(npc_entity, { size = Vec2.new(4, 1), offset = Vec3.new(0,2.5,0) })
billboard.set_text(bb, "Guard") Sets the text displayed on a billboard.
| Name | Type | Description |
|---|---|---|
| billboard_handle | billboard | Billboard handle. |
| text | string | Text to display. |
void
billboard.set_text(bb, "HP: " .. character.get_health(npc)) Shows or hides a billboard.
| Name | Type | Description |
|---|---|---|
| billboard_handle | billboard | Billboard handle. |
| visible | boolean | True to show, false to hide. |
void
billboard.set_visible(bb, false) Removes a billboard from its entity.
| Name | Type | Description |
|---|---|---|
| billboard_handle | billboard | Billboard to remove. |
void
billboard.remove(bb) Creates a minimap blip at a world position.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World position for the blip. |
| props | table? | Properties: icon (string), color (Color3), label (string). |
blip — Blip handle.
local b = blip.create(Vec3.new(10,0,20), { icon="enemy", color=Color3.new(1,0,0) }) Attaches a blip to an entity so it follows the entity's position.
| Name | Type | Description |
|---|---|---|
| blip_handle | blip | Blip handle. |
| entity | entity | Entity to follow. |
void
local player_blip = blip.create(Vec3.new(0,0,0), { icon="player" })
blip.attach(player_blip, player) Removes a blip from the minimap.
| Name | Type | Description |
|---|---|---|
| blip_handle | blip | Blip to remove. |
void
blip.remove(enemy_blip) Shows or hides a blip on the minimap without destroying it.
| Name | Type | Description |
|---|---|---|
| blip_handle | blip | Blip handle. |
| visible | boolean | True to show, false to hide. |
void
blip.set_visible(enemy_blip, false) Returns the last reported FPS of a connected client, as periodically sampled by the engine. Server-side only. Returns nil if the peer is not found or hasn't reported yet. Use this for server-side performance monitoring or adaptive quality scaling.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
number? — Last reported client FPS, or nil if not available.
-- Warn low-FPS players and suggest reducing settings
hook.add("OnPlayerJoin", "fps_check", function(player)
task.delay(10, function() -- wait for first FPS report
local peer = player.get_peer_id(player)
local fps = client.get_fps(peer)
if fps and fps < 25 then
hud.show_notification(player, "Low FPS detected. Try reducing graphics settings.", 8)
end
end)
end) Returns the OS platform of a connected client. Server-side only. Use this to send platform-appropriate content — mobile clients may need simplified UI, touch controls, and reduced quality settings.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
string? — "windows", "linux", "macos", "android", or "ios". Nil if not yet reported.
hook.add("OnPlayerJoin", "platform_setup", function(player)
local peer = player.get_peer_id(player)
local plat = client.get_platform(peer)
if plat == "android" or plat == "ios" then
net.send(player, "enable_touch_ui", {})
player.set_render_distance(player, 400)
else
player.set_render_distance(player, 1000)
end
end) Returns the screen resolution of a connected client in pixels. Server-side only. Useful for detecting ultra-wide or very low resolution clients to send appropriately sized UI layouts.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
number?, number? — Width and height in pixels, or nil if not available.
local peer = player.get_peer_id(player)
local w, h = client.get_screen_size(peer)
if w and h then
local aspect = w / h
net.send(player, "set_ui_layout", {
wide = aspect > 2.0, -- ultra-wide layout
width = w, height = h,
})
end Returns the device category of a connected client. Server-side only. "mobile" covers phones, "tablet" covers iPads and Android tablets, "pc" covers all desktop platforms.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
string? — "pc", "mobile", or "tablet". Nil if not available.
local peer = player.get_peer_id(player)
local dtype = client.get_device_type(peer)
if dtype == "mobile" then
-- Larger buttons, simplified HUD, auto-aim assist
net.send(player, "mobile_mode", { auto_aim = true, large_ui = true })
elseif dtype == "tablet" then
net.send(player, "mobile_mode", { auto_aim = false, large_ui = true })
end Returns the total system RAM of a connected client in megabytes. Server-side only. Use this to estimate device tier and avoid sending high-res assets or complex scenes to low-memory devices.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
number? — Total RAM in megabytes, or nil if not available.
local peer = player.get_peer_id(player)
local mem = client.get_memory(peer)
local quality = "high"
if mem and mem < 2048 then quality = "low"
elseif mem and mem < 4096 then quality = "medium" end
net.send(player, "set_quality", { level = quality }) Returns the GPU name/vendor string reported by the connected client. Server-side only. Primarily useful for telemetry, bug reports, or logging hardware distribution across your player base.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
string? — GPU identifier string (e.g. "NVIDIA GeForce RTX 3060"), or nil.
-- Log hardware telemetry on join
hook.add("OnPlayerJoin", "hw_telemetry", function(player)
local peer = player.get_peer_id(player)
print(string.format("[JOIN] %s | GPU: %s | OS: %s",
player.get_name(player),
client.get_gpu(peer) or "unknown",
client.get_os_version(peer) or "unknown"
))
end) Returns the system language/locale code of a connected client (e.g. "en", "tr", "de"). Server-side only. Use this to automatically localise messages sent to each player.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
string? — ISO 639-1 language code (e.g. "en", "tr"), or nil.
hook.add("OnPlayerJoin", "auto_locale", function(player)
local peer = player.get_peer_id(player)
local lang = client.get_locale(peer) or "en"
-- Send preferred locale to client so it can load its own UI strings
net.send(player, "set_locale", { lang = lang })
end) Returns the OS version string of a connected client. Server-side only. Useful for telemetry and diagnosing platform-specific bugs.
| Name | Type | Description |
|---|---|---|
| peer_id | number | Peer ID of the connected client. |
string? — OS version string (e.g. "Windows 11", "Android 14", "iOS 17.4"), or nil.
local peer = player.get_peer_id(player)
local os_ver = client.get_os_version(peer) or "unknown"
print("Client OS:", os_ver) Returns the current local frame rate as an EMA-smoothed value. Client-side only. Use this to implement client-side adaptive quality: reduce particle counts, shadow distance, or draw calls when FPS drops.
number — Current smoothed FPS on the local client.
-- Client-side: reduce effects at low FPS
hook.add("Think", "adaptive_quality", function()
local fps = client.get_local_fps()
if fps < 25 then
-- Tell server we're struggling
net.send_server("fps_report", { fps = fps })
end
end) Returns a table with all local device information in a single call. Client-side only. Use this at mod startup to configure the local experience, then optionally report to the server.
table — { platform, screen_w, screen_h, device_type, memory, gpu, locale, os_version }.
-- Client-side init: report device info and configure local UI
local info = client.get_local_info()
local is_mobile = info.device_type == "mobile" or info.device_type == "tablet"
if is_mobile then
ui.set_scale(1.4) -- larger UI elements on touch screens
end
-- Report to server for adaptive quality decisions
net.send_server("client_info", {
platform = info.platform,
device_type = info.device_type,
memory = info.memory,
locale = info.locale,
}) Registers a callback fired immediately whenever any entity receives a specific tag via entity.set_tag(). Use this to reactively set up behaviour on newly-tagged entities — attaching AI, applying effects, or registering subsystems — without polling every frame.
| Name | Type | Description |
|---|---|---|
| tag | string | Tag name to watch for. |
| callback | function | Called with (entity) when the tag is added to any entity. |
void
-- Auto-configure any entity tagged "enemy" — no matter where it was created
collection.on_tagged("enemy", function(e)
npc.set_hostile(e, true)
npc.set_vision(e, 20, 120)
npc.set_behavior(e, "wander")
local bb = billboard.create(e, { size = Vec2.new(3, 0.6), offset = Vec3.new(0, 2.2, 0) })
billboard.set_text(bb, "ENEMY")
end)
-- Track all "loot" entities in a global table for the minimap
local all_loot = {}
collection.on_tagged("loot", function(e)
all_loot[e] = blip.create(entity.get_position(e), { icon = "loot" })
end) Registers a callback fired whenever a specific tag is removed from any entity. Use this to clean up subsystems or state that was set up in the corresponding on_tagged callback.
| Name | Type | Description |
|---|---|---|
| tag | string | Tag name to watch for removal. |
| callback | function | Called with (entity) when the tag is removed. |
void
-- Clean up the loot blip when loot entity is removed/picked up
collection.on_untagged("loot", function(e)
if all_loot[e] then
blip.remove(all_loot[e])
all_loot[e] = nil
end
end)
-- Trigger death logic when "alive" tag is removed
collection.on_untagged("alive", function(e)
if entity.is_valid(e) then
on_entity_died(e)
end
end) Returns all tags currently attached to a given entity as an array of strings. Useful for inspection, serialization, or building generic systems that react to multiple possible tags.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to query. |
table — Array of tag strings currently on the entity.
-- Debug: print all tags on a selected entity
local tags = collection.get_all_tags(selected_entity)
if #tags == 0 then
print("Entity has no tags")
else
print("Tags: " .. table.concat(tags, ", "))
end Creates a Color3 value from 0–255 integer RGB components. This is more readable than Color3.new() when working with web/CSS colors or artist-supplied values.
| Name | Type | Description |
|---|---|---|
| r | number | Red channel (0–255). |
| g | number | Green channel (0–255). |
| b | number | Blue channel (0–255). |
Color3 — Normalised Color3 value (components in 0–1 range internally).
-- Use designer-specified hex colors directly
local team_red = color.from_rgb(220, 50, 50)
local team_blue = color.from_rgb(50, 100, 220)
local gold = color.from_rgb(255, 200, 0)
hud.show_notification(player, "You joined Red team!", 3, team_red) Creates a Color3 from HSV (hue/saturation/value) components. HSV is more intuitive than RGB for generating colour palettes, cycling hues, or tinting — e.g. animating through the rainbow by incrementing hue.
| Name | Type | Description |
|---|---|---|
| h | number | Hue angle in degrees (0–360). 0=red, 120=green, 240=blue. |
| s | number | Saturation (0=grey, 1=fully saturated). |
| v | number | Value/brightness (0=black, 1=full brightness). |
Color3 — Converted color value.
-- Animate a health bar from green → yellow → red based on HP %
local function health_color(hp_pct)
-- hue: 120 = green, 0 = red
return color.from_hsv(hp_pct * 120, 1, 1)
end
-- Rainbow name tags cycling over time
hook.add("Think", "rainbow_tags", function()
local hue = (world.get_time() * 60) % 360
local c = color.from_hsv(hue, 1, 1)
for _, p in ipairs(player.get_all()) do
player.set_name_color(p, c)
end
end) Linearly interpolates between two Color3 values. t=0 returns color a, t=1 returns color b, and intermediate values blend smoothly. Use with tween.value() for animated color transitions.
| Name | Type | Description |
|---|---|---|
| a | Color3 | Start color (t=0). |
| b | Color3 | End color (t=1). |
| t | number | Blend factor (0–1). |
Color3 — Interpolated color.
-- Fade sky color from dawn orange to noon blue over 60 seconds
local dawn = color.from_rgb(255, 160, 80)
local noon = color.from_rgb(100, 170, 255)
tween.value(0, 1, 60, function(t)
local sky = color.lerp(dawn, noon, t)
world.set_sky_color(sky)
end, "InOutSine") Converts a Color3 back to 0–255 integer RGB components. Useful when passing colors to APIs that expect integer channels (e.g. serialising to JSON, network messages).
| Name | Type | Description |
|---|---|---|
| c | Color3 | Color3 value to convert. |
number, number, number — r, g, b integers in 0–255.
local r, g, b = color.to_rgb(team_color)
net.send(player, "set_team_color", { r = r, g = g, b = b }) Converts a Color3 to HSV components. Useful for modifying only one channel — e.g. darkening a color by reducing V, or desaturating by reducing S — without disrupting hue.
| Name | Type | Description |
|---|---|---|
| c | Color3 | Color3 value to convert. |
number, number, number — h (0–360), s (0–1), v (0–1).
-- Darken any team color by 30% for shadow/outline tint
local function darken(c, amount)
local h, s, v = color.to_hsv(c)
return color.from_hsv(h, s, math.max(0, v - amount))
end
local shadow = darken(team_color, 0.3) Schedules an entity for automatic destruction after a given lifetime. Ideal for short-lived visual effects — shell casings, impact decals, particle emitters, blood splats — that would accumulate and degrade performance if not cleaned up. The entity is destroyed silently with no callbacks.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to auto-destroy. |
| lifetime | number | Seconds before the entity is destroyed. Must be > 0. |
void
-- Weapon fire effects: spawn and auto-clean all transient FX
local function fire_weapon(muzzle_pos, muzzle_rot)
local flash = entity.create("fx/muzzle_flash", muzzle_pos)
local shell = entity.create("fx/shell_casing", muzzle_pos)
local smoke = entity.create("fx/gun_smoke", muzzle_pos)
debris.add(flash, 0.05) -- muzzle flash: 50ms
debris.add(shell, 8.0) -- shell casing: 8 seconds
debris.add(smoke, 3.0) -- smoke trail: 3 seconds
end Cancels a previously scheduled auto-destruction. The entity will remain alive until explicitly destroyed. Useful when an entity transitions from temporary to permanent (e.g. a placed structure that started as a preview ghost).
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to remove from the debris queue. |
void
-- Preview ghost: destroy after 10s unless player confirms placement
local ghost = entity.create("props/wall_preview", place_pos)
debris.add(ghost, 10)
interact.on_triggered(confirm_interact, function(player)
debris.cancel(ghost) -- keep it
entity.set_model(ghost, "props/wall") -- swap to real model
entity.set_tag(ghost, "structure")
end) Projects a decal onto the world surface at a given position and normal. Returns a decal handle.
| Name | Type | Description |
|---|---|---|
| texture | string | Texture asset path. |
| position | Vec3 | World-space position. |
| normal | Vec3 | Surface normal direction. |
| size | Vec3? | Width/height/depth extents. |
handle — Decal handle.
local d = decal.create("fx/bullet_hole", hit_pos, hit_normal) Removes a specific decal from the world.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle to remove. |
void
decal.destroy(my_decal) Removes all decals currently in the world.
void
decal.destroy_all() Changes the texture of an existing decal.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
| texture | string | New texture asset path. |
void
decal.set_texture(my_decal, "fx/scorch") Returns the texture path currently assigned to a decal.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
string — Texture asset path.
print(decal.get_texture(my_decal)) Sets the opacity of a decal (0.0 = invisible, 1.0 = fully opaque).
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
| opacity | number | Opacity [0, 1]. |
void
decal.set_opacity(my_decal, 0.5) Returns the current opacity of a decal.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
number — Opacity value.
print(decal.get_opacity(my_decal)) Sets the world-space size extents of a decal.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
| size | Vec3 | Width/height/depth. |
void
decal.set_size(my_decal, Vec3.new(0.5, 0.5, 0.1)) Returns the current size extents of a decal.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
Vec3 — Size extents.
print(decal.get_size(my_decal)) Returns the world-space position of a decal.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
Vec3 — World position.
print(decal.get_position(my_decal)) Returns the surface normal direction the decal was projected along.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
Vec3 — Surface normal.
print(decal.get_normal(my_decal)) Returns the entity that owns (created) this decal, or nil.
| Name | Type | Description |
|---|---|---|
| handle | handle | Decal handle. |
entity|nil — Owner entity.
local owner = decal.get_owner(my_decal) Returns the total number of active decals in the world.
number — Active decal count.
print("Decals:", decal.count()) Sets the maximum number of simultaneously active decals. Oldest are removed first.
| Name | Type | Description |
|---|---|---|
| max | number | Maximum decal count. |
void
decal.set_max(256) Returns the current maximum decal limit.
number — Maximum decal count.
print("Max decals:", decal.get_max()) Registers a listener for a named event. Returns a handle that can be used to unregister.
| Name | Type | Description |
|---|---|---|
| name | string | Event name. |
| callback | function | Function to call when the event fires. |
handle — Listener handle.
event.on("player_died", function(player)
print(player, "died")
end) Unregisters a previously registered event listener by handle.
| Name | Type | Description |
|---|---|---|
| handle | handle | Listener handle returned by event.on. |
void
local h = event.on("player_died", cb)
event.off(h) Fires a named event, invoking all registered listeners with optional arguments.
| Name | Type | Description |
|---|---|---|
| name | string | Event name. |
| ... | any | Optional arguments passed to listeners. |
void
event.emit("player_died", player_entity) Reads the full content of a file as a string. All paths are relative to the mod's sandboxed data directory (e.g. "data/my_mod/"). Access outside this sandbox is blocked. Returns nil on failure — always check the return value.
| Name | Type | Description |
|---|---|---|
| path | string | File path relative to the mod's data directory. Cannot contain ".." path traversal. |
string? — File contents as a string, or nil if the file does not exist or cannot be read.
-- Load mod config, fall back to defaults if missing
local function load_config()
local raw = file.read("config.json")
if not raw then
return { max_players = 16, friendly_fire = false }
end
return game.json_decode(raw)
end
local cfg = load_config() Writes a string to a file, overwriting it if it already exists and creating it (plus any missing parent dirs) if not. Returns true on success. Writes are synchronous — for frequent saves consider using storage.* or session.* instead.
| Name | Type | Description |
|---|---|---|
| path | string | Destination file path relative to mod data dir. |
| content | string | String content to write. |
boolean — True on success, false on I/O error.
-- Persist mod config changes
local function save_config(cfg)
local json = game.json_encode(cfg)
if not file.write("config.json", json) then
print("ERROR: failed to save config")
end
end Returns true if a file or directory exists at the given path. Use this before file.read() when missing files require a first-run setup path.
| Name | Type | Description |
|---|---|---|
| path | string | Path to check, relative to mod data dir. |
boolean — True if the path exists (file or directory).
-- First-run setup: write default config if none exists
if not file.exists("config.json") then
file.write("config.json", game.json_encode({
map = "default", max_players = 16
}))
end Permanently deletes a file. Returns false if the file did not exist or could not be removed. Cannot delete directories — use only on files.
| Name | Type | Description |
|---|---|---|
| path | string | File path to delete. |
boolean — True on success.
-- Clean up old replay before saving a new one
file.delete("replays/latest.bin")
file.write("replays/latest.bin", replay_data) Returns the names (not full paths) of all entries in a directory. Includes both files and subdirectories. Use file.is_dir() to distinguish them.
| Name | Type | Description |
|---|---|---|
| path | string | Directory path relative to mod data dir. Use "" for the root data directory. |
table — Array of entry name strings.
-- List all saved map files
local entries = file.list("maps/")
for _, name in ipairs(entries) do
if not file.is_dir("maps/" .. name) then
print("Map file:", name)
end
end Creates a directory at the given path, including all intermediate parent directories. Equivalent to "mkdir -p". Returns true if the directory exists (whether newly created or already present).
| Name | Type | Description |
|---|---|---|
| path | string | Directory path to create. |
boolean — True on success.
-- Ensure replay folder exists before writing
local year = os.date("%Y")
file.mkdir("replays/" .. year)
file.write("replays/" .. year .. "/match_001.bin", replay_data) Returns the size of a file in bytes. Returns -1 if the file does not exist. Useful for validating file integrity or enforcing storage quotas.
| Name | Type | Description |
|---|---|---|
| path | string | File path to measure. |
number — File size in bytes, or -1 if not found.
-- Warn if replay file is suspiciously small
local bytes = file.size("replay.bin")
if bytes < 100 then
print("Warning: replay file may be corrupt (" .. bytes .. " bytes)")
end Returns whether a given path is a directory (as opposed to a file). Use in combination with file.list() to walk a directory tree.
| Name | Type | Description |
|---|---|---|
| path | string | Path to test. |
boolean — True if the path exists and is a directory.
-- Recursively count files in a folder
local function count_files(dir)
local n = 0
for _, name in ipairs(file.list(dir)) do
local full = dir .. "/" .. name
if file.is_dir(full) then
n = n + count_files(full)
else
n = n + 1
end
end
return n
end
print("Total files:", count_files("maps")) Sets global wind direction, strength, and speed for vegetation animation.
| Name | Type | Description |
|---|---|---|
| dir_x | number | Wind direction X component. |
| dir_z | number | Wind direction Z component. |
| strength | number | Wind strength (0-2). |
| speed | number | Wind animation speed. |
void
foliage.set_wind(1.0, 0.3, 0.8, 1.2) Returns current global wind parameters.
number, number, number, number — dir_x, dir_z, strength, speed.
local dx, dz, str, spd = foliage.get_wind() Sets vegetation density at a specific point in a terrain chunk.
| Name | Type | Description |
|---|---|---|
| chunk_x | number | Chunk X coordinate. |
| chunk_z | number | Chunk Z coordinate. |
| type_slot | number | Foliage type slot (0-3). |
| x | number | X position within density map (0-63). |
| z | number | Z position within density map (0-63). |
| value | number | Density value (0-255). |
void
foliage.set_density(0, 0, 0, 32, 32, 200) Returns vegetation density at a specific point.
| Name | Type | Description |
|---|---|---|
| chunk_x | number | Chunk X coordinate. |
| chunk_z | number | Chunk Z coordinate. |
| type_slot | number | Foliage type slot (0-3). |
| x | number | X position within density map. |
| z | number | Z position within density map. |
number — Density value (0-255).
local d = foliage.get_density(0, 0, 0, 32, 32) Clears all vegetation density data for a terrain chunk.
| Name | Type | Description |
|---|---|---|
| chunk_x | number | Chunk X coordinate. |
| chunk_z | number | Chunk Z coordinate. |
void
foliage.clear_chunk(0, 0) Sets global density multiplier for quality settings (0.0 = no foliage, 1.0 = full).
| Name | Type | Description |
|---|---|---|
| scale | number | Density scale [0, 1]. |
void
foliage.set_density_scale(0.5) -- half density for mobile Returns the current global density scale.
number — Density scale [0, 1].
print("Foliage density:", foliage.get_density_scale()) Performs an asynchronous HTTP GET request. The callback is called on completion with the status code and response body. SSRF-protected: private IP ranges are blocked.
| Name | Type | Description |
|---|---|---|
| url | string | Full URL string (must be HTTPS or HTTP on allowed hosts). |
| callback | function | Called as callback(status_code, body_string) on completion. |
| headers | table? | Optional request headers as a string→string table. |
void
http.get("https://api.example.com/leaderboard", function(status, body)
if status == 200 then
local data = game.json_decode(body)
update_leaderboard_ui(data)
else
mod.log("HTTP error: " .. status, "warn")
end
end) Performs an asynchronous HTTP POST request with a string body. Commonly used to submit JSON data to an external API.
| Name | Type | Description |
|---|---|---|
| url | string | Full URL string. |
| body | string | Request body string (e.g. JSON). |
| callback | function | Called as callback(status_code, response_body) on completion. |
| headers | table? | Optional headers table. |
void
local payload = '{"player":"' .. player_uid .. '","kills":' .. kills .. '}'
http.post("https://stats.myserver.com/submit", payload, function(status, body)
if status ~= 200 then
mod.log("Failed to submit stats: " .. status, "error")
end
end, { ["Content-Type"] = "application/json" }) General-purpose HTTP request supporting any method (GET, POST, PUT, DELETE, etc.). Returns the status code, headers, and body via callback.
| Name | Type | Description |
|---|---|---|
| options | table | Request options: url (string), method (string), body (string?), headers (table?). |
| callback | function | Called as callback(status_code, response_headers, body) on completion. |
void
http.request({
url = "https://api.example.com/items/42",
method = "DELETE",
headers = { ["Authorization"] = "Bearer " .. api_token },
}, function(status, headers, body)
print("DELETE status:", status)
end) Creates an interaction zone attached to an entity. Players who enter the range see a key prompt in their HUD. Triggering the interaction fires the on_triggered callback server-side. Default distance is 3m, default key is "E", and hold_time 0 means instant press.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to attach the interaction zone to. |
| props | table? | Configuration: { text (string), distance (number, metres), hold_time (number, seconds, 0=instant), key (string, e.g. "E") }. |
interact — Interaction handle. Use on_triggered to register a callback.
-- Simple door interaction
local door_interact = interact.create(door_entity, {
text = "Open Door", distance = 2.5, key = "E"
})
interact.on_triggered(door_interact, function(player)
entity.set_rotation(door_entity, Vec3.new(0, 90, 0))
interact.set_text(door_interact, "Close Door")
end) Permanently removes an interaction from its entity. The prompt disappears immediately for all nearby players. Use interact.set_enabled(handle, false) instead if you want to temporarily hide and restore it later.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle to permanently remove. |
void
-- Remove interaction once chest is looted
interact.on_triggered(chest_interact, function(player)
give_loot(player)
interact.remove(chest_interact)
end) Updates the prompt text shown to nearby players. Changes take effect immediately, even if a player is already viewing the prompt.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| text | string | New prompt text to display. |
void
-- Toggle door text based on state
local is_open = false
interact.on_triggered(door_interact, function()
is_open = not is_open
interact.set_text(door_interact, is_open and "Close Door" or "Open Door")
end) Sets the maximum distance at which the interaction prompt becomes visible and triggerable. Players farther away than this distance will not see the prompt.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| distance | number | Activation radius in metres. |
void
-- Large terminal requires closer approach
interact.set_distance(terminal_interact, 1.5)
-- Wide vehicle door can be opened from further away
interact.set_distance(vehicle_interact, 4.0) Sets the hold duration in seconds required before the interaction triggers. A value of 0 means instant press. When hold_time > 0, on_hold_begin fires when the player starts holding and on_triggered fires on completion. Use on_hold_end to detect cancellation.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| hold_time | number | Required hold duration in seconds. 0 = instant. |
void
-- Revive requires 3-second hold
local revive_interact = interact.create(downed_player, { text = "Revive (Hold E)" })
interact.set_hold(revive_interact, 3.0)
interact.on_hold_begin(revive_interact, function(p)
hud.show_progress(p, "Reviving...", 0)
end)
interact.on_triggered(revive_interact, function(p)
hud.hide_progress(p)
character.set_health(downed_player, 50)
end) Enables or disables an interaction. When disabled, the prompt is hidden and triggering is blocked. The interaction remains attached to the entity and can be re-enabled at any time.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| enabled | boolean | True to show and allow triggering, false to hide. |
void
-- Only allow looting when player has a lockpick item
hook.add("PlayerEquipItem", "lockpick_check", function(player, item)
local has_pick = item == "lockpick"
interact.set_enabled(locked_chest_interact, has_pick)
if has_pick then
interact.set_text(locked_chest_interact, "Pick Lock")
end
end) Changes the key name shown in the interaction prompt. This is display-only; the actual trigger key is determined by the player's interact binding.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| key | string | Key label shown in the prompt (e.g. "E", "F", "G"). |
void
-- Use F for vehicle interactions to differentiate from world objects
interact.set_key(car_door_interact, "F")
interact.set_key(car_horn_interact, "H") Registers a callback fired when a player successfully triggers the interaction (instant press, or at the end of a hold). This is the primary callback for implementing interact logic.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| callback | function | Called with (player_entity) when the interaction completes. |
void
interact.on_triggered(shop_interact, function(player)
-- Server: send the shop inventory to this specific player
local inv = get_shop_inventory()
net.send(player, "open_shop", { items = inv })
end) Registers a callback fired the moment a player starts holding the interact key on this interaction. Only relevant when hold_time > 0. Use this to show a progress indicator.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| callback | function | Called with (player_entity) when hold begins. |
void
interact.on_hold_begin(bomb_defuse, function(player)
hud.show_progress(player, "Defusing...", 0.0)
-- Animate progress bar over hold duration
tween.value(0, 1, 5.0, function(v)
hud.show_progress(player, "Defusing...", v)
end)
end) Registers a callback fired when a player releases the interact key before the hold completes (i.e. they cancelled the interaction mid-hold). Use this to clean up progress indicators.
| Name | Type | Description |
|---|---|---|
| interact_handle | interact | Interaction handle. |
| callback | function | Called with (player_entity) when hold is released early. |
void
interact.on_hold_end(bomb_defuse, function(player)
-- Player let go — hide the progress bar
hud.hide_progress(player)
end) Sets the active locale for the mod (e.g. "en", "tr", "de"). Affects all locale.translate calls.
| Name | Type | Description |
|---|---|---|
| code | string | ISO 639-1 language code. |
void
locale.set("tr") Returns the currently active locale code.
string — Active locale code.
print("Locale:", locale.get()) Registers a translation table for a given locale code.
| Name | Type | Description |
|---|---|---|
| code | string | Locale code. |
| strings | table | Key-value table of translation strings. |
void
locale.register("tr", { greeting = "Merhaba!", bye = "GĂĽle gĂĽle!" }) Translates a key using the active locale. Falls back to the default locale if not found.
| Name | Type | Description |
|---|---|---|
| key | string | Translation key. |
| vars | table? | Optional substitution variables. |
string — Translated string.
local text = locale.translate("greeting")
hud.show_notification(player, text) Returns the preferred locale code of a connected player based on their client settings.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
string — Locale code (e.g. "en", "tr").
local lang = locale.get_player_locale(player)
locale.set(lang) Bakes the navigation mesh from the current world geometry.
void
navmesh.bake()
print("NavMesh baked. Polys:", navmesh.poly_count()) Finds a path between two world positions. Returns an array of Vec3 waypoints, or nil if no path exists.
| Name | Type | Description |
|---|---|---|
| from | Vec3 | Start position. |
| to | Vec3 | End position. |
table|nil — Array of Vec3 waypoints.
local path = navmesh.find_path(start_pos, target_pos)
if path then
for _, wp in ipairs(path) do print(wp) end
end Returns the nearest valid navigation mesh point to the given world position.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World position to snap. |
Vec3|nil — Nearest nav mesh point.
local snapped = navmesh.closest_point(Vec3.new(10, 5, 20)) Returns true if a baked navigation mesh is currently loaded and valid.
boolean
if not navmesh.is_valid() then navmesh.bake() end Saves the current baked navigation mesh to a file.
| Name | Type | Description |
|---|---|---|
| path | string | File path to save to. |
void
navmesh.save("maps/my_map.navmesh") Loads a previously saved navigation mesh from a file.
| Name | Type | Description |
|---|---|---|
| path | string | File path to load from. |
void
navmesh.load("maps/my_map.navmesh") Returns the number of polygons in the baked navigation mesh.
number — Polygon count.
print("NavMesh polys:", navmesh.poly_count()) Configures navmesh bake parameters before baking.
| Name | Type | Description |
|---|---|---|
| config | table | Bake parameters (cell_size, agent_height, etc.). |
void
navmesh.bake_config({ cell_size = 0.3, agent_height = 2.0 }) Creates a particle emitter entity at the given position and returns its handle.
| Name | Type | Description |
|---|---|---|
| position | Vec3 | World spawn position. |
| config | table? | Optional config table (see particle.set_config). |
handle — Particle emitter handle.
local fx = particle.create(Vec3.new(0, 1, 0)) Destroys a particle emitter, stopping emission and removing existing particles.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
void
particle.destroy(fx) Starts or pauses particle emission on an emitter.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
| playing | bool | True to emit, false to pause. |
void
particle.set_playing(fx, true) Sets the texture used for all particles emitted by this emitter.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
| texture | string | Texture asset path. |
void
particle.set_texture(fx, "fx/spark") Returns the number of currently alive particles in an emitter.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
number — Live particle count.
print("Particles alive:", particle.get_count(fx)) Immediately emits a burst of N particles from the emitter.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
| count | number | Number of particles to burst-emit. |
void
particle.emit(fx, 20) Sets a time scale multiplier for particle simulation speed.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
| scale | number | Time scale (1.0 = normal speed). |
void
particle.set_time_scale(fx, 0.5) Applies a config table to an emitter: emission_rate, lifetime, speed, gravity, color, size.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
| config | table | Config table with emitter properties. |
void
particle.set_config(fx, { emission_rate = 50, lifetime = 2.0, speed = 3.0 }) Returns the current configuration table of an emitter.
| Name | Type | Description |
|---|---|---|
| handle | handle | Emitter handle. |
table — Current emitter config.
local cfg = particle.get_config(fx)
print(cfg.emission_rate) Declares a new permission identifier that can later be granted to players or groups. Call this at mod init time before using the permission anywhere. Use dot-namespaced strings to organise permissions hierarchically (e.g. "admin.kick", "admin.ban", "build.place").
| Name | Type | Description |
|---|---|---|
| perm | string | Permission identifier string (e.g. "admin.kick"). |
| description | string? | Human-readable description shown in admin UIs. |
void
-- Register all mod permissions at startup
permission.register("admin.kick", "Can kick players from the server")
permission.register("admin.ban", "Can ban players by IP")
permission.register("admin.mute", "Can mute players in chat")
permission.register("build.place", "Can place structures")
permission.register("build.destroy", "Can destroy any structure") Grants a specific permission directly to a player. This is a per-player override on top of any group permissions. Persists for the session — does not survive a server restart unless you re-grant on join.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity to grant the permission to. |
| perm | string | Permission identifier to grant. |
void
-- Grant server owner special permissions on join
hook.add("OnPlayerJoin", "owner_perms", function(player)
if player.get_name(player) == "ServerOwner" then
permission.add_to_group(player, "admin")
permission.grant(player, "admin.rcon") -- extra perm beyond group
end
end) Removes a directly-granted permission from a player. Does not affect permissions inherited from their group. Use permission.remove_from_group() to remove group-based permissions.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| perm | string | Permission identifier to revoke. |
void
-- Temporarily revoke build permission during combat
hook.add("OnCombatStart", "no_build_in_combat", function(player)
permission.revoke(player, "build.place")
end)
hook.add("OnCombatEnd", "restore_build", function(player)
permission.grant(player, "build.place")
end) Returns true if a player has the given permission either directly or via their assigned group. This is the primary gate-check function — use it at the top of any admin command handler.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity to check. |
| perm | string | Permission identifier to test. |
boolean — True if the player has the permission (directly or via group).
-- Net handler: only mods can kick players
net.on("kick_player", function(sender, data)
if not permission.has(sender, "admin.kick") then
net.send(sender, "error", { msg = "You don't have permission to kick." })
return
end
local target = player.find_by_id(data.target_id)
if target then player.kick(target, "Kicked by moderator") end
end) Creates a named permission group with an initial set of permissions. Groups allow assigning multiple permissions at once. A player can be in one group at a time; assign via permission.add_to_group().
| Name | Type | Description |
|---|---|---|
| group | string | Group name (e.g. "moderator", "vip", "admin"). |
| perms | table? | Optional array of permission strings to pre-assign to the group. |
void
-- Set up role hierarchy at mod startup
permission.create_group("vip", { "build.place" })
permission.create_group("moderator", { "admin.kick", "admin.mute", "build.place" })
permission.create_group("admin", { "admin.kick", "admin.mute", "admin.ban", "build.place", "build.destroy" }) Adds an additional permission to an existing group. All players currently in that group gain the permission immediately.
| Name | Type | Description |
|---|---|---|
| group | string | Existing group name. |
| perm | string | Permission to add to the group. |
void
-- Dynamically unlock a new permission for all moderators
permission.register("event.start", "Can start special events")
permission.set_group("moderator", "event.start") Returns the name of the permission group a player belongs to, or nil if they have no group assignment.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
string? — Group name, or nil if the player has no group.
local group = permission.get_group(player) or "player"
hud.show_notification(player, "Role: " .. group, 3) Returns the full list of effective permissions for a player, including both direct grants and inherited group permissions. Useful for debugging or displaying a player's capabilities in an admin panel.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
table — Array of permission identifier strings.
-- Admin command: list all permissions for a target player
net.on("list_perms", function(sender, data)
if not permission.has(sender, "admin.kick") then return end
local target = player.find_by_id(data.target_id)
local perms = permission.get_permissions(target)
net.send(sender, "perm_list", { perms = perms })
end) Assigns a player to a permission group, giving them all the group's permissions in addition to any directly-granted ones. Replaces the player's previous group assignment.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| group | string | Group name to assign. |
void
-- Promote player to moderator via chat command
game.register_command("promote", function(caller, args)
if not permission.has(caller, "admin.kick") then return end
local target = player.find_by_name(args[1])
if target then
permission.add_to_group(target, "moderator")
game.broadcast_chat(player.get_name(target) .. " is now a Moderator!")
end
end) Removes a player from a permission group. The player loses all permissions inherited from that group, but retains any directly-granted permissions.
| Name | Type | Description |
|---|---|---|
| player | entity | Player entity. |
| group | string | Group name to remove the player from. |
void
-- Demote moderator via chat command
game.register_command("demote", function(caller, args)
if not permission.has(caller, "admin.ban") then return end
local target = player.find_by_name(args[1])
if target then
permission.remove_from_group(target, "moderator")
game.broadcast_chat(player.get_name(target) .. " was demoted.")
end
end) Sets the network replication priority of an entity (higher = more frequent updates).
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| priority | number | Priority value (default 1.0). |
void
replication.set_priority(player, 2.0) Returns the current replication priority of an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
number — Priority value.
print(replication.get_priority(player)) Sets the enter and leave distances for entity scope culling.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
| enter_dist | number | Distance at which entity enters a client scope. |
| leave_dist | number | Distance at which entity leaves a client scope. |
void
replication.set_distances(npc, 100, 120) Returns the enter and leave scope distances for an entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Target entity. |
number, number — Enter distance, leave distance.
local enter, leave = replication.get_distances(npc) Forces an entity into the scope of a specific peer, bypassing distance checks.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to scope. |
| peer | number | Peer ID. |
void
replication.force_scope(important_entity, peer_id) Creates a numeric keyframe curve from an array of time-value pairs. Values between keyframes are linearly interpolated. Use sequence.evaluate() each frame to sample the curve. Ideal for particle emission rates, audio volume envelopes, or any value that changes non-uniformly over time.
| Name | Type | Description |
|---|---|---|
| keyframes | table | Ordered array of { time (number), value (number) } tables. Time values must be ascending. |
sequence — Sequence handle.
-- Explosion particle burst: fast at start, trails off
local emit_rate = sequence.create_number({
{ time = 0.0, value = 200 }, -- peak emission at start
{ time = 0.1, value = 80 },
{ time = 0.5, value = 20 },
{ time = 1.5, value = 0 }, -- fades out after 1.5s
})
hook.add("Think", "particle_tick", function()
local t = world.get_time() - explosion_start
if t < sequence.get_length(emit_rate) then
local rate = sequence.evaluate(emit_rate, t)
particle.set_emission_rate(explosion_fx, rate)
end
end) Creates a Color3 keyframe sequence for animating colors over time. Values between keyframes are linearly interpolated in RGB space. Use with particle systems for fire/explosion color gradients, or for ambient light color cycling.
| Name | Type | Description |
|---|---|---|
| keyframes | table | Ordered array of { time (number), value (Color3) } tables. |
sequence — Sequence handle.
-- Fire particle color: white core → orange → dark red → black smoke
local fire_color = sequence.create_color({
{ time = 0.0, value = color.from_rgb(255, 255, 200) }, -- white hot
{ time = 0.2, value = color.from_rgb(255, 140, 30) }, -- orange
{ time = 0.6, value = color.from_rgb(180, 40, 10) }, -- dark red
{ time = 1.0, value = color.from_rgb(40, 40, 40) }, -- smoke grey
})
hook.add("Think", "fire_color_tick", function()
local age = world.get_time() - fire_start
local t = math.min(age, sequence.get_length(fire_color))
particle.set_color(fire_fx, sequence.evaluate(fire_color, t))
end) Samples a sequence at the given time position and returns the interpolated value. For times before the first keyframe, returns the first value. For times after the last keyframe, returns the last value (no extrapolation).
| Name | Type | Description |
|---|---|---|
| seq | sequence | Sequence handle to evaluate. |
| time | number | Time position to sample. Clamped to [0, length]. |
any — Interpolated value (number or Color3 depending on sequence type).
-- Drive a health bar color from the emit_rate curve sampled each frame
hook.add("Think", "hpbar_color", function()
local hp_pct = character.get_health(player) / 100
local bar_color = sequence.evaluate(hp_color_seq, hp_pct)
ui.set_background_color(health_bar, bar_color)
end) Returns the total duration of a sequence — the time value of the last keyframe. Use this to know when to stop evaluating.
| Name | Type | Description |
|---|---|---|
| seq | sequence | Sequence handle. |
number — Time of the last keyframe in seconds.
-- Only evaluate sequence while within its duration
local t = world.get_time() - effect_start
if t <= sequence.get_length(emit_rate) then
particle.set_emission_rate(fx, sequence.evaluate(emit_rate, t))
else
particle.set_emission_rate(fx, 0)
end Sets a local mod-scoped state value by key.
| Name | Type | Description |
|---|---|---|
| key | string | State key. |
| value | any | Value to store. |
void
state.set("round_active", true) Gets a local mod-scoped state value by key.
| Name | Type | Description |
|---|---|---|
| key | string | State key. |
any — Stored value, or nil if not set.
local active = state.get("round_active") Sets a global state value shared across all mods.
| Name | Type | Description |
|---|---|---|
| key | string | Global key. |
| value | any | Value to store. |
void
state.set_global("match_time", 300) Gets a global state value shared across all mods.
| Name | Type | Description |
|---|---|---|
| key | string | Global key. |
any — Stored value, or nil.
local t = state.get_global("match_time") Registers a callback that fires whenever a state key changes.
| Name | Type | Description |
|---|---|---|
| key | string | State key to watch. |
| callback | function | Called with (key, new_value, old_value). |
handle — Listener handle.
state.on_change("round_active", function(k, new_val, old_val)
print("State changed:", new_val)
end) Returns an array of all keys currently set in the local mod state.
table — Array of key strings.
for _, k in ipairs(state.keys()) do print(k) end Returns a shallow copy of all local mod state as a table.
table — State snapshot table.
local snap = state.get_all() Returns true if a key exists in the local mod state.
| Name | Type | Description |
|---|---|---|
| key | string | State key. |
boolean
if state.has("round_active") then end Creates a surface GUI attached to an entity's face, rendering UI content in 3D world space.
| Name | Type | Description |
|---|---|---|
| entity | entity | Entity to attach the surface GUI to. |
| props | table? | Properties: size (Vec2 in world units), face ("front"|"back"|"top"), resolution (Vec2). |
surface_gui — Surface GUI handle.
local screen = surface_gui.create(terminal, { size = Vec2.new(1,0.6) }) Draws a UI element tree onto a surface GUI each frame.
| Name | Type | Description |
|---|---|---|
| surface_handle | surface_gui | Surface GUI handle. |
| root_element | uielement | Root UI element to render. |
void
surface_gui.draw(screen, terminal_ui_root) Removes a surface GUI from its entity.
| Name | Type | Description |
|---|---|---|
| surface_handle | surface_gui | Surface GUI to remove. |
void
surface_gui.remove(screen) Spawns a Luau coroutine that runs concurrently alongside the current frame. The function may yield at any point using task.wait(). Errors inside the coroutine are caught and logged — they do not crash the calling code. Extra arguments after fn are passed to the function.
| Name | Type | Description |
|---|---|---|
| fn | function | Coroutine body. May call task.wait() to yield. |
| ... | any | Arguments forwarded to fn. |
task — Task handle. Pass to task.cancel() or task.is_running().
-- Countdown sequence without blocking game logic
task.spawn(function()
for i = 10, 1, -1 do
game.broadcast_chat("Round starts in " .. i .. "...")
task.wait(1)
end
game.set_state("Active")
end) Schedules a function to run at the very start of the next simulation frame. Useful for deferring operations that must not run mid-iteration (e.g. destroying entities inside a query loop).
| Name | Type | Description |
|---|---|---|
| fn | function | Function to run next frame. |
void
-- Defer entity cleanup to avoid modifying the ECS while iterating
for _, e in ipairs(entity.find_by_tag("to_remove")) do
task.defer(function() entity.destroy(e) end)
end Yields the currently running coroutine for at least the given number of seconds, then resumes it. Must be called from within a task.spawn context — calling from the main thread will error. With no argument (or 0), waits exactly one frame.
| Name | Type | Description |
|---|---|---|
| seconds | number? | Minimum wait time in seconds. Default: one frame (0). |
number — Actual elapsed time in seconds (may be slightly more than requested).
-- Spawn loot over time: one item per second
task.spawn(function()
local positions = get_loot_spawn_points()
for _, pos in ipairs(positions) do
spawn_loot_at(pos)
task.wait(1)
end
print("All loot spawned")
end) Runs a function once after the given delay without blocking. Similar to timer.delay but returns a cancellable task handle. The function runs in its own coroutine so it can call task.wait() internally.
| Name | Type | Description |
|---|---|---|
| seconds | number | Delay in seconds before calling fn. |
| fn | function | Function to call after the delay. |
task — Task handle. Cancel with task.cancel() before it fires.
-- End round after 3-minute timer; cancel if all objectives done early
local round_timer = task.delay(180, function()
game.set_state("RoundEnd")
end)
hook.add("OnObjectivesComplete", "cancel_timer", function()
task.cancel(round_timer)
game.set_state("RoundEnd")
end) Cancels a running or pending task. The coroutine is terminated immediately and will not resume. Has no effect if the task has already completed.
| Name | Type | Description |
|---|---|---|
| task_handle | task | Task to cancel. |
void
local t = task.spawn(function()
while true do
update_ai_pathfinding()
task.wait(0.5)
end
end)
-- Stop AI loop when player leaves
hook.add("OnPlayerLeave", "stop_ai", function()
task.cancel(t)
end) Returns whether a task is still alive (either actively running or waiting to resume). Returns false if the task completed naturally or was cancelled.
| Name | Type | Description |
|---|---|---|
| task_handle | task | Task handle to query. |
boolean — True if still running or yielded, false if done or cancelled.
-- Don't start a second intro sequence if one is already playing
if not task.is_running(intro_task) then
intro_task = task.spawn(play_intro_sequence)
end Returns the total wall-clock time in seconds since the task was spawned, including any time spent yielded in task.wait().
| Name | Type | Description |
|---|---|---|
| task_handle | task | Task handle to query. |
number — Elapsed seconds since the task started.
local t = task.spawn(function()
task.wait(100) -- long background job
end)
-- Check progress somewhere else
hook.add("Think", "progress_check", function()
if task.is_running(t) then
print(string.format("Task running for %.1fs", task.get_elapsed(t)))
end
end) Yields the current coroutine until ALL tasks in the given array have completed. Useful for parallel loading — kick off multiple task.spawn calls and then await all of them before continuing.
| Name | Type | Description |
|---|---|---|
| tasks | table | Array of task handles to wait for. |
void
-- Parallel load: map geometry + enemy data + audio, then start round
task.spawn(function()
local t1 = task.spawn(load_map_geometry)
local t2 = task.spawn(load_enemy_data)
local t3 = task.spawn(load_ambient_audio)
task.synchronize({ t1, t2, t3 })
-- All three finished — safe to start
game.set_state("Active")
game.broadcast_chat("Match started!")
end) Transfers a player to another server by IP and port. The player receives a reconnect notice.
| Name | Type | Description |
|---|---|---|
| player | entity | Player to transfer. |
| address | string | Target server address (e.g. "1.2.3.4:27015"). |
| data | table? | Optional arrival data passed to the destination server. |
void
teleport.to_server(player, "10.0.0.2:27015", { reason = "match_transfer" }) Returns the arrival data sent by the origin server when the player was transferred.
| Name | Type | Description |
|---|---|---|
| player | entity | Arriving player. |
table? — Arrival data table, or nil if not a transfer.
local data = teleport.get_arrival_data(player)
if data and data.reason == "match_transfer" then
spawn.spawn_player(player)
end Loads a heightmap terrain from file. Accepts PNG/raw heightmap paths.
| Name | Type | Description |
|---|---|---|
| path | string | Heightmap file path. |
| config | table? | Optional config: { scale, height_scale, chunk_size }. |
void
terrain.load("maps/valley.png", { scale = 512, height_scale = 64 }) Procedurally generates terrain using FastNoise parameters.
| Name | Type | Description |
|---|---|---|
| config | table | Noise config: { seed, frequency, octaves, size }. |
void
terrain.generate({ seed = 42, frequency = 0.01, octaves = 4, size = 1024 }) Assigns a texture to one of the 4 terrain splatmap layers.
| Name | Type | Description |
|---|---|---|
| layer | number | Layer index 0-3. |
| texture | string | Texture asset path. |
void
terrain.set_texture(0, "terrain/grass")
terrain.set_texture(1, "terrain/rock") Returns the terrain height at the given world X,Z coordinates.
| Name | Type | Description |
|---|---|---|
| x | number | World X. |
| z | number | World Z. |
number — Terrain height in world units.
local h = terrain.get_height(100, 50)
print("Ground at (100,50):", h) Shows or hides the terrain mesh.
| Name | Type | Description |
|---|---|---|
| visible | bool | True to show. |
void
terrain.set_visible(true) Removes the terrain from the world, freeing all chunk and physics data.
void
terrain.destroy() Sets the collision layer for terrain physics.
| Name | Type | Description |
|---|---|---|
| layer | number | Collision layer index. |
void
terrain.set_layer(0) Loads an RGBA splatmap image that controls layer blending across the terrain.
| Name | Type | Description |
|---|---|---|
| path | string | PNG splatmap file path. |
void
terrain.load_splatmap("maps/valley_splatmap.png") Procedurally generates a splatmap based on slope and height thresholds.
| Name | Type | Description |
|---|---|---|
| config | table? | Optional config: { slope_threshold, height_threshold }. |
void
terrain.generate_splatmap({ slope_threshold = 30 }) Sets the distance thresholds for each terrain LOD level.
| Name | Type | Description |
|---|---|---|
| lod0 | number | Max distance for LOD0 (highest detail). |
| lod1 | number | Max distance for LOD1. |
| lod2 | number | Max distance for LOD2 (lowest detail). |
void
terrain.set_lod_distances(64, 256, 1024) Returns the total number of terrain chunks currently loaded.
number — Chunk count.
print("Terrain chunks:", terrain.get_chunk_count()) Returns the rendered pixel dimensions of a string given a font and size.
| Name | Type | Description |
|---|---|---|
| str | string | Text string. |
| font | string | Font name. |
| font_size | number | Font size in points. |
number, number — width, height in pixels.
local w, h = text.get_size("Hello World", "Regular", 16) Filters a string through a profanity/content filter, replacing disallowed words with asterisks.
| Name | Type | Description |
|---|---|---|
| str | string | Input string. |
string — Filtered string.
local safe = text.filter(player_message)
game.chat(player, safe) Wraps a text string to fit within a maximum pixel width, returning a table of wrapped lines.
| Name | Type | Description |
|---|---|---|
| str | string | Text to wrap. |
| max_width | number | Maximum pixel width per line. |
| font | string | Font name. |
| font_size | number | Font size. |
table — Array of wrapped line strings.
local lines = text.wrap(long_str, 300, "Regular", 14) Returns a list of all registered font names available for rendering.
table — Array of font name strings.
local fonts = text.get_fonts()
for _, f in ipairs(fonts) do print(f) end Calls a function once after a delay in seconds. Returns a timer handle for cancellation.
| Name | Type | Description |
|---|---|---|
| delay | number | Delay in seconds before calling the function. |
| callback | function | Function to call after the delay. |
timer_handle — A handle that can be passed to timer.cancel().
-- Respawn player 3 seconds after death
hook.add("CharacterDied", "respawn", function(player)
timer.delay(3.0, function()
if entity.is_valid(player) then
character.teleport(player, spawn.get_random_point())
character.set_health(player, 100)
end
end)
end) Calls a function repeatedly at a fixed interval in seconds. Returns a timer handle.
| Name | Type | Description |
|---|---|---|
| interval | number | Time between calls in seconds. |
| callback | function | Function to call on each tick. |
timer_handle — A handle to cancel the repeating timer.
-- Bleed tick: deal 2 damage every second
local bleed_timer = timer.interval(1.0, function()
if not character.is_alive(wounded_player) then
timer.cancel(bleed_timer)
return
end
character.damage(wounded_player, 2, "bleed")
end) Cancels a timer created by timer.delay() or timer.interval().
| Name | Type | Description |
|---|---|---|
| handle | timer_handle | Timer handle to cancel. |
void
local t = timer.interval(5.0, heal_player)
-- Stop healing when player leaves the zone
hook.add("ZoneExit", "stop_heal", function(player)
timer.cancel(t)
end) Creates a tween that animates one or more fields of a table from their current values toward the given goal values. Supported easing names: Linear, InQuad, OutQuad, InOutQuad, InCubic, OutCubic, InOutCubic, InBack, OutBack, InOutBack, InElastic, OutElastic, InBounce, OutBounce, and more. The direction field accepts "In", "Out", or "InOut". Does not start automatically — call tween.play() to begin.
| Name | Type | Description |
|---|---|---|
| object | table | Table whose fields will be animated. The current field values are the start point. |
| info | table | Tween configuration: { time (seconds), easing (string), direction? ("In"|"Out"|"InOut"), repeat_count? (0=infinite), reverses? (bool) }. |
| goals | table | Key-value pairs of target field values to animate toward. |
tween — Tween handle. Call tween.play(handle) to start.
-- Fade out a UI overlay with a smooth ease-out
local props = { alpha = 1.0, scale = 1.0 }
local t = tween.create(props, { time = 0.4, easing = "OutQuad" }, { alpha = 0, scale = 0.9 })
tween.on_complete(t, function() ui.set_visible(overlay, false) end)
tween.play(t) Creates a tween that animates a single numeric value from a start to an end, calling a callback each frame. Useful for driving custom logic — camera FOV, sound volume, material opacity — without a table intermediary. The tween starts immediately.
| Name | Type | Description |
|---|---|---|
| from | number | Start value. |
| to | number | End value. |
| duration | number | Duration in seconds. |
| callback | function | Called each frame with (current_value: number). Use this to apply the value. |
| easing | string? | Easing name. Default: "Linear". |
tween — Tween handle (already playing).
-- Smoothly reduce camera FOV from 90 to 55 on ADS
tween.value(90, 55, 0.15, function(v)
camera.set_fov(v)
end, "OutQuad")
-- Fade in BGM volume
tween.value(0, 1, 2.0, function(v)
audio.set_volume(bgm, v)
end, "InOutCubic") Starts a tween that hasn't begun yet, or resumes one that was paused. Has no effect on an already-running tween.
| Name | Type | Description |
|---|---|---|
| tween_handle | tween | Tween handle to start or resume. |
void
-- Create first, then play on an event
local slide_in = tween.create(panel, { time = 0.3, easing = "OutBack" }, { x = 0 })
interact.on_triggered(terminal, function()
tween.play(slide_in)
end) Pauses a running tween, freezing it at its current interpolated value. Call tween.play() to resume from where it stopped.
| Name | Type | Description |
|---|---|---|
| tween_handle | tween | Tween handle to pause. |
void
-- Pause all UI animations when game is paused
hook.add("OnPause", "tween_pause", function()
tween.pause(intro_tween)
tween.pause(hud_tween)
end) Immediately stops a tween, leaving the animated values at wherever they currently are. The on_complete callback is NOT fired. Use this when you need to interrupt animation before the new tween starts.
| Name | Type | Description |
|---|---|---|
| tween_handle | tween | Tween handle to cancel. |
void
-- Cancel existing move tween before starting a new one
if current_move_tween then
tween.cancel(current_move_tween)
end
current_move_tween = tween.create(pos, { time = 0.5, easing = "OutQuad" }, { x = target_x })
tween.play(current_move_tween) Registers a callback fired when the tween finishes naturally (not when cancelled). For sequences or parallel groups, fires after all child tweens complete.
| Name | Type | Description |
|---|---|---|
| tween_handle | tween | Tween handle to attach the callback to. |
| callback | function | Called with no arguments when the tween completes. |
void
-- Chain: slide out → destroy entity
local slide_out = tween.create(panel_pos, { time = 0.25, easing = "InBack" }, { y = -200 })
tween.on_complete(slide_out, function()
entity.destroy(panel_entity)
end)
tween.play(slide_out) Creates a composite tween that plays the given tweens one after another, in order. The sequence tween itself is a handle — play, pause, and cancel it like any other tween. on_complete fires after the last tween in the list finishes.
| Name | Type | Description |
|---|---|---|
| tweens | table | Ordered array of tween handles. Each starts when the previous one completes. |
tween — Sequence tween handle.
-- Door open animation: slide up, then swing open, then show prompt
local slide_up = tween.create(door_pos, { time=0.3, easing="OutQuad" }, { y = 2 })
local swing_open = tween.create(door_rot, { time=0.4, easing="OutBack" }, { y = 90 })
local show_ui = tween.create(prompt, { time=0.2, easing="OutQuad" }, { alpha = 1 })
local door_anim = tween.sequence({ slide_up, swing_open, show_ui })
tween.play(door_anim) Creates a composite tween that runs all given tweens simultaneously. Completes (and fires on_complete) when every child tween has finished.
| Name | Type | Description |
|---|---|---|
| tweens | table | Array of tween handles to run at the same time. |
tween — Parallel tween handle.
-- Spawn effect: scale up + fade in at the same time
local scale_up = tween.create(props, { time=0.3, easing="OutBack" }, { scale = 1.2 })
local fade_in = tween.create(props, { time=0.3, easing="OutQuad" }, { alpha = 1 })
local pop_in = tween.parallel({ scale_up, fade_in })
tween.on_complete(pop_in, function()
props.scale = 1.0 -- snap to final scale
end)
tween.play(pop_in) Creates a 3D viewport inside a UI frame element, rendering the scene from a given camera.
| Name | Type | Description |
|---|---|---|
| parent | uielement | UI frame to embed the viewport in. |
| props | table? | Properties: size (UDim2), position (UDim2). |
viewport — Viewport handle.
local vp = viewport.create(frame, { size = UDim2.new(1,0,1,0) })
viewport.set_camera(vp, preview_camera) Assigns a camera entity to a viewport, determining what the viewport renders.
| Name | Type | Description |
|---|---|---|
| viewport_handle | viewport | Viewport handle. |
| camera | entity | Camera entity to use. |
void
viewport.set_camera(vp, item_camera) Removes a viewport from its parent UI element.
| Name | Type | Description |
|---|---|---|
| viewport_handle | viewport | Viewport to remove. |
void
viewport.remove(vp) Sets the shallow and deep water colors and maximum depth.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| sr | number | Shallow color R. |
| sg | number | Shallow color G. |
| sb | number | Shallow color B. |
| dr | number | Deep color R. |
| dg | number | Deep color G. |
| db | number | Deep color B. |
| depth_max | number | Maximum depth for color blending. |
void
water.set_color(lake, 0.2,0.7,0.9, 0.0,0.1,0.3, 10) Returns the shallow color, deep color, and depth max of a water entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
table — {shallow={r,g,b}, deep={r,g,b}, depth_max=number}.
local c = water.get_color(lake)
print(c.shallow.r, c.deep.b) Configures a Gerstner wave on a water entity.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| index | number | Wave index (0-3). |
| dir_x | number | Wave direction X. |
| dir_z | number | Wave direction Z. |
| amplitude | number | Wave height. |
| frequency | number | Wave density. |
| speed | number | Animation speed. |
| steepness | number | Wave sharpness (0=sine, 1=Gerstner). |
void
water.set_wave(ocean, 0, 1,0, 0.5, 2, 1.5, 0.7) Sets the number of active waves (1-4).
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| count | number | Number of waves (1-4). |
void
water.set_wave_count(ocean, 3) Returns parameters of a specific wave.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| index | number | Wave index (0-3). |
number, number, number, number, number, number — dir_x, dir_z, amplitude, frequency, speed, steepness.
local dx,dz,amp,freq,spd,steep = water.get_wave(ocean, 0) Returns the number of active waves.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
number — Wave count.
print("Waves:", water.get_wave_count(ocean)) Configures shore foam appearance.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| r | number | Foam color R. |
| g | number | Foam color G. |
| b | number | Foam color B. |
| distance | number | Foam edge distance threshold. |
void
water.set_foam(ocean, 1, 1, 1, 1.5) Returns foam color and distance.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
number, number, number, number — r, g, b, distance.
local r,g,b,dist = water.get_foam(ocean) Sets Fresnel reflection strength.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| strength | number | Reflection strength [0, 1]. |
void
water.set_reflection(ocean, 0.5) Sets the water plane size and subdivision level.
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| size | number | XZ extent in world units. |
| subdivisions | number | Quads per axis. |
void
water.set_mesh_size(ocean, 200, 128) Samples wave height at a world XZ position (for buoyancy/effects).
| Name | Type | Description |
|---|---|---|
| entity | entity | Water entity. |
| x | number | World X position. |
| z | number | World Z position. |
number — Wave height at position.
local y = water.get_height(ocean, player_x, player_z) Sets the current weather type instantly with no transition. Built-in types: "clear", "rain", "storm", "snow", "fog". Mods can register custom weather types. For a gradual change, use weather.transition() instead.
| Name | Type | Description |
|---|---|---|
| type | string | Weather type name. Built-in: "clear", "rain", "storm", "snow", "fog". |
void
-- Snap to clear weather at round start
game.on_state("WaitingForPlayers", function()
weather.set("clear")
weather.set_intensity(0)
end) Sets the intensity of the active weather effect. At 0 the effect is barely visible; at 1 it is at full strength. For rain/storm, intensity affects particle density and audio volume. For fog, it controls fog density.
| Name | Type | Description |
|---|---|---|
| intensity | number | Effect intensity from 0 (minimal) to 1 (maximum). |
void
-- Build a storm gradually over 60 seconds
weather.set("storm")
weather.set_intensity(0.1)
tween.value(0.1, 1.0, 60, function(v)
weather.set_intensity(v)
end, "InQuad") Sets the global wind vector. Wind affects precipitation particle drift, foliage sway shaders, and long-range projectile deflection. Direction should be a unit vector; speed is in m/s.
| Name | Type | Description |
|---|---|---|
| direction | Vec3 | Normalised wind direction vector (unit length). |
| speed | number | Wind speed in m/s. Typical range: 2–20. |
void
-- North-east wind at gale force
weather.set_wind(Vec3.new(0.7, 0, 0.7), 15)
-- Calm before the storm
weather.set_wind(Vec3.new(1, 0, 0), 2)
timer.delay(30, function()
weather.transition("storm", 20)
weather.set_wind(Vec3.new(0, 0, 1), 18)
end) Smoothly blends from the current weather to a new weather type over the given duration. Affects particles, lighting, fog, and audio. The transition runs in the background — you can queue game logic in a timer.delay to match the end.
| Name | Type | Description |
|---|---|---|
| type | string | Target weather type to transition to. |
| duration | number | Duration of the blend in seconds. |
void
-- Dynamic weather cycle: clear → rain → storm → clear
local function start_weather_cycle()
weather.set("clear")
timer.delay(120, function()
weather.transition("rain", 30)
timer.delay(60, function()
weather.transition("storm", 20)
timer.delay(90, function()
weather.transition("clear", 45)
timer.delay(120, start_weather_cycle)
end)
end)
end)
end
start_weather_cycle() Returns the total elapsed server time in seconds since the session started.
number — Elapsed time in seconds.
print("Server uptime:", world.get_time(), "s") Returns the duration of the last simulation step (delta time) in seconds.
number — Delta time in seconds.
local dt = world.get_delta_time()
position = position + velocity * dt Returns the total number of live entities currently in the world.
number — Total entity count.
print("Entities in world:", world.get_entity_count()) Sets the sky's time of day. Value is in hours (0–24), affecting sun position, sky color, and ambient lighting.
| Name | Type | Description |
|---|---|---|
| hours | number | Time in hours (0–24). |
void
world.set_time_of_day(20.5) -- dusk Returns the current time of day in hours (0–24).
number — Current time of day.
local tod = world.get_time_of_day()
if tod > 18 then world.set_time_of_day(tod + 0.01) end Creates a trigger zone in world space for enter/exit detection. Pass "size" (Vec3) for a box zone or "radius" (number) for a sphere zone. Zones detect all entities by default — filter by type or tag inside the callback. Server-side only.
| Name | Type | Description |
|---|---|---|
| props | table | Zone config: { position (Vec3), size (Vec3) for box OR radius (number) for sphere, tag (string?) for a debug label }. |
zone — Zone handle. Attach callbacks with zone.on_enter / zone.on_exit.
-- Capture point: box zone, 10Ă—3Ă—10 metres
local cap_zone = zone.create({
position = Vec3.new(50, 0, 50),
size = Vec3.new(10, 3, 10),
tag = "capture_A",
})
-- Safe zone: sphere, 15m radius
local safe_zone = zone.create({
position = Vec3.new(0, 0, 0),
radius = 15,
}) Destroys a zone and unregisters all its enter/exit callbacks. Any entities currently inside the zone do NOT receive an on_exit event.
| Name | Type | Description |
|---|---|---|
| zone_handle | zone | Zone handle to destroy. |
void
-- Destroy capture zone when round ends
game.on_state("RoundEnd", function()
zone.destroy(cap_zone_a)
zone.destroy(cap_zone_b)
end) Registers a callback fired each time an entity crosses into the zone. The callback receives the entity that entered. For player-only zones, check with player.is_player() inside the callback.
| Name | Type | Description |
|---|---|---|
| zone_handle | zone | Zone handle. |
| callback | function | Called with (entity) when an entity enters the zone. |
void
-- Capture point: track players entering
zone.on_enter(cap_zone, function(ent)
if not player.is_player(ent) then return end
local team = player.get_team(ent)
hud.show_notification(ent, "Capturing point A...", 2)
entity.set_tag(ent, "capturing")
end) Registers a callback fired each time an entity leaves the zone boundaries. Also fires if the entity is destroyed while inside — check entity.is_valid() if needed.
| Name | Type | Description |
|---|---|---|
| zone_handle | zone | Zone handle. |
| callback | function | Called with (entity) when an entity leaves the zone. |
void
-- Safe zone: remove god-mode buff when leaving
zone.on_exit(safe_zone, function(ent)
if player.is_player(ent) then
character.set_invincible(ent, false)
hud.show_notification(ent, "You left the safe zone!", 3)
end
end) Returns a snapshot of all entities currently inside the zone. The table is a copy — modifying it does not affect the zone's tracking. Use this for periodic checks like capture progress or zone-wide effects.
| Name | Type | Description |
|---|---|---|
| zone_handle | zone | Zone handle to query. |
table — Array of entity handles currently inside the zone.
-- Tick: determine which team owns the capture zone
hook.add("Think", "capture_tick", function()
local inside = zone.get_entities(cap_zone)
local team_counts = { red = 0, blue = 0 }
for _, ent in ipairs(inside) do
if player.is_player(ent) then
local t = player.get_team(ent)
if team_counts[t] then team_counts[t] += 1 end
end
end
if team_counts.red > 0 and team_counts.blue == 0 then
award_capture_progress("red")
elseif team_counts.blue > 0 and team_counts.red == 0 then
award_capture_progress("blue")
end
end) Pick a function from the left panel to see its documentation.