Script Examples
This page contains complete script examples from the examples/assets/ directory, demonstrating various Lua/Luau API features.
Ping-Pong Animation
Simple animation that moves an entity up and down.
local PingPong = {}
function PingPong:on_start()
self.time = 0
self.amplitude = 10
self.speed = 0.5
end
function PingPong:on_update(dt)
self.time = self.time + dt
local offset = math.sin(self.time * self.speed) * self.amplitude
if Engine and Engine.setEntityPosition then
Engine.setEntityPosition(self.entity, 0, offset, 0)
else
self.last_offset = offset
end
end
return PingPong
Features demonstrated:
on_start()initializationon_update(dt)frame updatesEngine.setEntityPosition()entity manipulation- Frame-rate independent animation using delta time
Gamemode Script
Scene-wide state management with events and persistence.
local GamemodeTable = {}
function GamemodeTable:on_start()
self.counter = 0
self.initialized = true
-- Load from localStorage if available
local saved = localStorage.get("counter")
if saved then
self.counter = tonumber(saved) or 0
end
end
function GamemodeTable:on_update(dt)
self.counter = (self.counter or 0) + 1
-- Save to localStorage
localStorage.set("counter", tostring(self.counter))
-- Trigger event every 10 updates
if self.counter % 10 == 0 then
local api = Gamemode or self._GamemodeAPI
if api and api.triggerEvent then
api.triggerEvent("counter_updated", self.counter)
end
end
end
return GamemodeTable
Features demonstrated:
- Gamemode lifecycle
localStorage.get()andlocalStorage.set()persistenceGamemode.triggerEvent()event system- State management
Entity Event Listener
Entity script that listens to gamemode events.
local Entity = {}
function Entity:on_start()
self.eventCount = 0
self.lastEventData = nil
-- Listen for events from gamemode
local entitySelf = self
Gamemode.onEvent("counter_updated", function(data)
entitySelf.eventCount = entitySelf.eventCount + 1
entitySelf.lastEventData = data
end)
end
function Entity:on_update(dt)
-- Entity can access gamemode state
local counter = Gamemode.getState("counter")
if counter then
self.gamemodeCounter = tonumber(counter) or 0
end
end
return Entity
Features demonstrated:
Gamemode.onEvent()event listeningGamemode.getState()accessing gamemode state- Entity-gamemode communication
Audio Playback
Script that plays and stops audio on interaction.
local AudioTest = {}
function AudioTest:on_start()
self.audioPlaying = false
self.ambientPlaying = false
self.loopingPlaying = false
self.interactionCount = 0
end
function AudioTest:on_interact()
self.interactionCount = self.interactionCount + 1
if not self.audioPlaying then
-- Play spatial audio at entity position
if Engine and Engine.playAudio then
local pos = {0, 0, 0} -- Will use entity position
local success = Engine.playAudio(
"spatial-audio-" .. tostring(self.entity),
"test-audio",
pos,
false, -- not ambient (spatial)
false, -- not looping
0.8 -- volume
)
if success then
self.audioPlaying = true
print("Started spatial audio playback")
end
end
else
-- Stop spatial audio
if Engine and Engine.stopAudio then
Engine.stopAudio("spatial-audio-" .. tostring(self.entity))
self.audioPlaying = false
print("Stopped spatial audio")
end
end
-- Toggle ambient audio
if not self.ambientPlaying then
if Engine and Engine.playAudio then
local pos = {0, 0, 0}
local success = Engine.playAudio(
"ambient-audio-" .. tostring(self.entity),
"test-audio",
pos,
true, -- ambient (constant volume)
true, -- looping
0.5 -- volume
)
if success then
self.ambientPlaying = true
print("Started ambient looping audio")
end
end
else
if Engine and Engine.stopAudio then
Engine.stopAudio("ambient-audio-" .. tostring(self.entity))
self.ambientPlaying = false
print("Stopped ambient audio")
end
end
end
return AudioTest
Features demonstrated:
Engine.playAudio()spatial and ambient audioEngine.stopAudio()stopping playback- Audio instance management
- Interaction-based audio control
Textbox Interaction
Script that opens and closes textboxes with callbacks.
local TextBoxTest = {}
function TextBoxTest:on_start()
self.textboxOpen = false
self.interactionCount = 0
end
function TextBoxTest:on_interact()
self.interactionCount = self.interactionCount + 1
if not self.textboxOpen then
-- Open textbox with quest acceptance scenario
local buttons = {"Accept Quest", "Decline"}
local checkboxes = {
["Remember my choice"] = false,
["Show hints"] = true
}
if Engine and Engine.openTextBox then
local success = Engine.openTextBox(
"quest-textbox-" .. tostring(self.entity),
"Quest: Find the Lost Artifact",
"A mysterious artifact has been discovered. Will you help recover it?\n\nRewards:\n- 100 Gold\n- Rare Item\n- Experience Points",
buttons,
checkboxes
)
if success then
self.textboxOpen = true
print("Opened textbox for entity " .. tostring(self.entity))
end
end
else
-- Close textbox
if Engine and Engine.closeTextBox then
Engine.closeTextBox("quest-textbox-" .. tostring(self.entity))
self.textboxOpen = false
print("Closed textbox for entity " .. tostring(self.entity))
end
end
end
return TextBoxTest
Features demonstrated:
Engine.openTextBox()with buttons and checkboxesEngine.closeTextBox()closing textboxes- Interaction-based UI control
URL Modal
Script that opens external URLs with user confirmation.
local UrlModalTest = {}
function UrlModalTest:on_start()
self.modalOpen = false
self.interactionCount = 0
self.testUrls = {
"https://www.example.com",
"https://github.com",
"https://blazium-engine.github.io"
}
self.currentUrlIndex = 1
end
function UrlModalTest:on_interact()
self.interactionCount = self.interactionCount + 1
if not self.modalOpen then
-- Open external URL modal
local url = self.testUrls[self.currentUrlIndex]
if not url then
self.currentUrlIndex = 1
url = self.testUrls[1]
end
if Engine and Engine.openExternalUrl then
local success = Engine.openExternalUrl(url)
if success then
self.modalOpen = true
print("Opened URL modal for: " .. url)
-- Cycle to next URL for next interaction
self.currentUrlIndex = self.currentUrlIndex + 1
if self.currentUrlIndex > #self.testUrls then
self.currentUrlIndex = 1
end
end
end
else
-- Modal should close via user interaction (accept/decline)
self.modalOpen = false
end
end
return UrlModalTest
Features demonstrated:
Engine.openExternalUrl()opening external URLs- User confirmation modals
- URL cycling
Combined Features
Script demonstrating multiple features together.
-- This script demonstrates multiple features working together
-- See the actual file for the complete implementation
Features demonstrated:
- Integration of multiple APIs
- Complex interaction patterns
- State management across features
ImGui Textbox
Script using ImGui textboxes for lightweight UI.
-- Demonstrates ImGui textbox usage
-- See the actual file for the complete implementation
Features demonstrated:
Engine.openImGuiTextBox()lightweight UIEngine.closeImGuiTextBox()closing ImGui textboxes
Next Steps
- Best Practices - Learn scripting guidelines
- Engine API - Complete API reference
- Examples Directory - See example scenes