Scripting basics
An experience's scripts run on the server, one copy per match. Ember gives every script the same globals: players, events, ui, world, task, match and more. You never require them.
When main.luau runs
The entry script runs once the map is loaded but before anyone is admitted, so the top level of main.luau sets things up and handlers react to players later:
--!strict
local config = require("./core/config")
players.onJoin(function(player)
player:setGamemode("survival")
player:sendMessage(`<yellow>First to {config.coinsToWin} coins wins!`)
end)
Split code into modules and require them by relative path, as Coin Rush does with ./core/config and ./game/coins.
Events
events.on connects a handler to a built-in event (the list is under EventName) or one your scripts declare. Return false from a handler, or call event:cancel(), to cancel a cancellable event:
events.on("blockBreak", function(event)
if not coins.take(event.x, event.y, event.z) then
return false -- not a coin: leave the block alone
end
event.player:give("coin", 1)
end)
Time
Everything counts in seconds, at 20 ticks a second. task.delay runs something later; task.wait pauses a task started with task.spawn, task.defer or task.delay, but never an event handler directly.
task.delay(config.roundSeconds, function()
match.finish(scores.leader())
end)
Ending a match
Call match.finish with the winner (a Player or a name), or nil for nobody.
The rules
- Text is MiniMessage (
"<red>hi</red>"), at most 4096 characters. - A
Playerhandle raises once that player has left; anEntityhandle once the entity is gone. - An error in a handler or task goes to the creator console and the script keeps running. More than 100 errors in a minute stops the experience.
- Limits keep one experience from starving the server: 256 handlers, 256 live entities, 2048 pending tasks, 4096 block writes a tick. Going over raises, so you find out straight away.
Use print to write to the creator console while you work.