Complete API Reference
📖 Overview
This is the complete reference for all Vibe API functions. Each function includes parameters, return values, and practical examples.
🎮 Entity Management
vibe.spawn(kind, props)
Creates a new entity and returns its unique ID.
Parameters:
kind(string): Entity type -"sprite"or"label"props(table): Properties for the entity
Props Table:
| Key | Type | Default | Applies To | Description |
|---|---|---|---|---|
texture | string | - | sprites | Resource path (e.g., "res://assets/player.png") |
text | string | " " | labels | Text content to display |
x | number | 0.0 | both | X position in pixels |
y | number | 0.0 | both | Y position in pixels |
scale | number | 1.0 | sprites | Uniform scale multiplier |
cell_size | number | 0.0 | sprites | Auto-fit texture to this size |
tag | string | - | both | Group identifier for finding |
Returns: integer - Entity ID (0 if spawn failed due to limits)
Examples:
-- Basic sprite
local player = vibe.spawn("sprite", {
texture = "res://assets/player.png",
x = 100,
y = 200,
tag = "player"
})
-- Scaled sprite with auto-fitting
local enemy = vibe.spawn("sprite", {
texture = "res://assets/enemy.png",
x = 300,
y = 150,
scale = 1.5, -- 50% larger
cell_size = 32, -- Fit in 32x32 cell
tag = "enemy"
})
-- Text label
local score = vibe.spawn("label", {
text = "Score: 0",
x = 10,
y = 10,
tag = "ui"
})vibe.spawn_exit(props)
Creates an exit entity on a dedicated top-level layer, ensuring it's always visible above other entities.
Parameters:
props(table): Same properties asvibe.spawn()
Returns: integer - Entity ID
Example:
local exit = vibe.spawn_exit({
texture = "res://assets/exit_door.png",
x = 500,
y = 300,
cell_size = 48,
tag = "exit"
})vibe.destroy(id)
Removes an entity from the game world completely.
Parameters:
id(integer): Entity ID to destroy
Returns: None
Example:
local bullet = vibe.spawn("sprite", {...})
-- ... later ...
vibe.destroy(bullet) -- Bullet is gonevibe.set(id, property, value)
Sets a property on an entity.
Parameters:
id(integer): Entity IDproperty(string): Property namevalue(number|string): New value
Supported Properties:
"x","y"(number): Position coordinates (automatically clamped ≥ 0)"text"(string): Text content (labels only)"tag"(string): Group tag
Returns: None
Examples:
-- Move entity
vibe.set(player_id, "x", 150)
vibe.set(player_id, "y", 250)
-- Update text
vibe.set(score_label, "text", "Score: 1500")
-- Change tag (moves entity to different group)
vibe.set(enemy_id, "tag", "dead_enemy")vibe.get(id, property)
Gets a property value from an entity.
Parameters:
id(integer): Entity IDproperty(string): Property name
Returns: number|string|nil - Property value or nil if entity/property not found
Examples:
local x = vibe.get(player_id, "x")
local y = vibe.get(player_id, "y")
local current_text = vibe.get(label_id, "text")
-- Check if entity exists
if vibe.get(entity_id, "x") ~= nil then
-- Entity is valid
endvibe.find(tag)
Finds all entities with a specific tag.
Parameters:
tag(string): Tag to search for (case-sensitive)
Returns: table - Array of entity IDs (empty table if none found)
Examples:
-- Find all enemies
local enemies = vibe.find("enemy")
for i = 1, #enemies do
local enemy_id = enemies[i]
-- Do something with each enemy
end
-- Find player (usually just one)
local players = vibe.find("player")
if #players > 0 then
local player = players[1]
local px = vibe.get(player, "x")
end
-- Destroy all bullets
local bullets = vibe.find("bullet")
for i = 1, #bullets do
vibe.destroy(bullets[i])
end⌨️ Input System
vibe.axis(name)
Returns the current value of an input axis.
Parameters:
name(string): Axis name -"horizontal"or"vertical"
Returns: number - Value between -1.0 and 1.0
Axis Mapping:
"horizontal": A/Left (-1.0) ← → (+1.0) D/Right"vertical": W/Up (-1.0) ↑ ↓ (+1.0) S/Down
Examples:
-- 8-direction movement
function on_tick(dt)
local speed = 200
local h = vibe.axis("horizontal") -- -1, 0, or 1
local v = vibe.axis("vertical") -- -1, 0, or 1
local players = vibe.find("player")
if #players > 0 then
local player = players[1]
local x = vibe.get(player, "x")
local y = vibe.get(player, "y")
vibe.set(player, "x", x + h * speed * dt)
vibe.set(player, "y", y + v * speed * dt)
end
end
-- Analog-style movement with deadzone
local deadzone = 0.1
local h = vibe.axis("horizontal")
local v = vibe.axis("vertical")
if math.abs(h) > deadzone or math.abs(v) > deadzone then
-- Apply movement
endvibe.key(name)
Returns whether a specific key is currently pressed.
Parameters:
name(string): Key name
Supported Keys:
"up","down","left","right"- Arrow keys or WASD"space"- Space bar
Returns: boolean - true if pressed, false otherwise
Examples:
-- Jump on space press
if vibe.key("space") then
vibe.play_sfx("res://assets/jump.wav")
-- Apply jump logic
end
-- Discrete movement
if vibe.key("right") then
local x = vibe.get(player_id, "x")
vibe.set(player_id, "x", x + 32) -- Move one grid cell
end
-- Key combination
if vibe.key("space") and vibe.key("up") then
-- Super jump!
endInput Event Detection:
-- Detect key press (not hold)
local space_pressed_last = false
function on_tick(dt)
local space_now = vibe.key("space")
if space_now and not space_pressed_last then
-- Space was just pressed this frame
shoot_bullet()
end
space_pressed_last = space_now
end🔧 Utility Functions
vibe.time_ms()
Returns the current time in milliseconds since the engine started.
Returns: integer - Timestamp in milliseconds
Examples:
-- Cooldown system
local last_shot = 0
local cooldown = 250 -- 250ms
function shoot()
local now = vibe.time_ms()
if now - last_shot >= cooldown then
-- Shoot
last_shot = now
end
end
-- Frame rate monitoring
local frame_count = 0
local last_fps_check = vibe.time_ms()
function on_tick(dt)
frame_count = frame_count + 1
local now = vibe.time_ms()
if now - last_fps_check >= 1000 then -- Every second
print("FPS:", frame_count)
frame_count = 0
last_fps_check = now
end
end
-- Periodic events
local start_time = vibe.time_ms()
function on_tick(dt)
local elapsed = vibe.time_ms() - start_time
if elapsed > 5000 then -- After 5 seconds
spawn_enemy()
start_time = vibe.time_ms() -- Reset timer
end
endvibe.width() & vibe.height()
Returns the current screen dimensions in pixels.
Returns: integer - Screen width/height
Examples:
-- Center entity on screen
function center_entity(entity_id)
local w = vibe.width()
local h = vibe.height()
vibe.set(entity_id, "x", w / 2)
vibe.set(entity_id, "y", h / 2)
end
-- Keep entity on screen
function clamp_to_screen(entity_id, size)
size = size or 32
local x = vibe.get(entity_id, "x")
local y = vibe.get(entity_id, "y")
local w = vibe.width()
local h = vibe.height()
x = math.max(0, math.min(x, w - size))
y = math.max(0, math.min(y, h - size))
vibe.set(entity_id, "x", x)
vibe.set(entity_id, "y", y)
end
-- Spawn at screen edges
function spawn_from_edge()
local w = vibe.width()
local h = vibe.height()
local side = math.random(1, 4)
local x, y
if side == 1 then -- Top
x, y = math.random(0, w), -32
elseif side == 2 then -- Right
x, y = w + 32, math.random(0, h)
elseif side == 3 then -- Bottom
x, y = math.random(0, w), h + 32
else -- Left
x, y = -32, math.random(0, h)
end
return vibe.spawn("sprite", {
texture = "res://assets/enemy.png",
x = x, y = y, tag = "enemy"
})
end🔊 Audio System
vibe.play_sfx(resource_path)
Plays a sound effect from a resource file.
Parameters:
resource_path(string): Path to audio resource
Returns: None
Supported Formats: .wav, .ogg, .mp3
Examples:
-- Basic sound effects
vibe.play_sfx("res://assets/sounds/jump.wav")
vibe.play_sfx("res://assets/sounds/shoot.ogg")
vibe.play_sfx("res://assets/sounds/explosion.mp3")
-- Event-triggered sounds
function on_enemy_death()
vibe.play_sfx("res://assets/enemy_die.wav")
end
-- Randomized sounds
local hit_sounds = {
"res://assets/hit1.wav",
"res://assets/hit2.wav",
"res://assets/hit3.wav"
}
function play_hit_sound()
local index = math.random(1, #hit_sounds)
vibe.play_sfx(hit_sounds[index])
end
-- Cooldown to prevent spam
local sound_cooldown = 0
function on_tick(dt)
sound_cooldown = math.max(0, sound_cooldown - dt)
if vibe.key("space") and sound_cooldown <= 0 then
vibe.play_sfx("res://assets/shoot.wav")
sound_cooldown = 0.1 -- 100ms cooldown
end
endAudio Features:
- Automatic Cleanup: Audio nodes are automatically removed when sounds finish
- Multiple Sounds: Can play multiple sounds simultaneously
- Resource Caching: Godot automatically caches loaded audio files
- No Volume Control: Sounds play at default volume (set in Godot import settings)
📝 Lua Script Structure
on_init()
Called once when the script loads. Use for game initialization.
Parameters: None Returns: None
Example:
function on_init()
print("Game starting!")
-- Initialize game state
score = 0
lives = 3
-- Spawn initial entities
spawn_player()
spawn_enemies()
create_ui()
endon_tick(dt)
Called every frame during gameplay.
Parameters:
dt(number): Delta time in seconds since last frame (typically ~0.016 for 60 FPS)
Returns: None
Example:
function on_tick(dt)
-- Update game systems
update_player(dt)
update_enemies(dt)
update_bullets(dt)
-- Check interactions
check_collisions()
check_win_conditions()
-- Update UI
update_score_display()
end🚨 System Limits
Entity Limits
- Per Frame: Maximum 200 entities can be spawned per
on_tick()call - Total: Maximum 1500 entities can exist at once
- Behavior:
vibe.spawn()returns 0 when limits are exceeded
Performance Budget
- Warning Threshold: 4ms execution time per frame
- Monitoring: Automatic timing with console warnings
- Purpose: Prevents frame rate drops
Position Constraints
- Minimum: X and Y coordinates are automatically clamped to ≥ 0
- Maximum: No upper limit (entities can go off-screen)
Resource Paths
- Format: Must use Godot resource paths (
res://...) - Validation: No automatic checking - missing resources fail silently
- Case Sensitivity: Paths are case-sensitive
🐛 Error Handling
Lua Runtime Errors
-- This will cause an error and stop the script
function on_tick(dt)
local result = nil.something -- Error: attempt to index nil
endWhen errors occur:
- Error message appears in Godot console
- Script execution stops immediately
- Game world continues running (entities remain)
- Reload script to resume
Invalid Operations
-- These operations fail gracefully
local x = vibe.get(999999, "x") -- Returns nil
vibe.set(999999, "x", 100) -- Does nothing
local entities = vibe.find("nonexistent") -- Returns empty table {}Resource Loading
-- Missing resources fail silently
vibe.spawn("sprite", {
texture = "res://assets/nonexistent.png" -- No error, but sprite won't display
})
vibe.play_sfx("res://sounds/missing.wav") -- No error, no soundThis completes the API reference! For practical examples and implementation patterns, see the Game Development Guide and Examples and Tutorials.