Scripts in the editor
Gameplay is written in scripts, in Luau or AngelScript. Both see the same engine API; they differ in syntax. The examples in these pages show both: pick a language once and the tabs follow it.
Write a game’s scripts in one language. A game run uses one script language: the first script to load decides it, and scripts in the other language stay off (the Console says so).
Three kinds of script
Section titled “Three kinds of script”- Behavior: belongs to an entity, through its Script component. Most gameplay lives here: a coin that spins, a door that opens, a player that moves.
- Level: one per scene, for what concerns the whole scene: spawning, win conditions, timing.
Its class is always named
Level. - Game: one per game, running from start to quit, across scene changes: menus, lives,
scores, which level comes next. Its class is always named
Game.
Creating a script
Section titled “Creating a script”In the Assets panel, right-click and choose Create > Scripts, then the language and the kind: Luau Behavior, AngelScript Level and so on. The File menu has the same list.
The new script is named NewBehavior (or NewLevel, NewGame): rename it in the Assets panel.
A behavior’s class takes its name from the asset’s name when it is created. The script’s file is
in the project’s Sources/ folder (.luau or .as); importing a .luau or .as file adds one
too.
A new behavior moves its entity slowly along X, to show that it runs:
NewBehavior = {}NewBehavior.__index = NewBehavior
function NewBehavior.new(entity) local self = setmetatable({}, NewBehavior) self.entity = entity self.speed = 1.0 return selfend
function NewBehavior:onStart() Log.info("NewBehavior started on " .. self.entity:name())end
function NewBehavior:onUpdate(dt) local p = self.entity:position() self.entity:setPosition(p.x + self.speed * dt, p.y, p.z)end
function NewBehavior:onDestroy()endclass NewBehavior{ private Entity@ self;
NewBehavior(Entity@ entity) { @self = entity; }
void onStart() { Log::info("NewBehavior started on '" + self.name() + "'"); }
void onUpdate(double dt) { Float3@ p = self.position(); self.setPosition(p.x + float(dt), p.y, p.z); }
void onDestroy() {}}Editing
Section titled “Editing”Double-click a script to open it in the editor’s script page: a code editor with highlighting and completion from the engine’s API. API opens a list of everything scripts can call; filter it, and double-click an entry to insert it.
The page checks the script as you type and lists any errors under the code, as file:line: message, with markers on the lines. Save (Ctrl+S) saves and cooks it. A script saved with
errors keeps running as it last compiled until they are fixed.
You can also edit the file in Sources/ with another editor: the editor notices the change
within two seconds and cooks it. An open script page does not reload the file, so close it
first: saving from the page would write over your changes.
Attaching a behavior
Section titled “Attaching a behavior”- Select the entity and choose Add Component > Script.
- In the Script component, add a behavior with the + of its Behaviors list, and pick the script. Or drag the script from the Assets panel onto the list.
An entity can have several behaviors; they run in the order listed, and the arrows in each behavior’s header reorder them. Each one has:
- Enabled, to turn it off without removing it.
- Update Interval: seconds between
onUpdatecalls. 0, the default, is every frame; with a longer interval,dtis the time since the last call. - Its properties (below).
Setting the Level and Game scripts
Section titled “Setting the Level and Game scripts”- A scene’s Level script is set in the scene page’s inspector, on its Scene tab (beside Entity), as Level Script.
- The Game script is set in Project > Project Settings…, on the Startup tab, as Startup script.
When the game starts, the Game script’s launch() runs first, and then the default scene loads.
A project with no default scene leaves it to the Game script to load the first one.
Properties
Section titled “Properties”A behavior’s properties appear in the inspector, under the behavior, so each entity can set its own values while sharing the script.
Every field the constructor sets to a number, a boolean, a string or a Float3 is a property:
function Coin.new(entity) local self = setmetatable({}, Coin) self.entity = entity self.spinSpeed = 3.0 -- a property self.label = "Gold" -- a property self.bob = Float3.new(0, 0.2, 0) -- a property return selfendThe editor runs the constructor without an entity (entity is nil) to find the properties, so
keep it to setting fields. Every such field is listed, including ones you only use inside the
script.
A member field is a property when it has a default and a description in brackets before it:
class Coin{ private Entity@ self; [3.0, "Spin rate in radians a second"] float spinSpeed; [null, "Who collects it"] Entity@ target; ["asset:Prefab", "What appears when it is collected"] Guid@ sparkle; private float m_time = 0.0f; // no brackets: not a property
Coin(Entity@ entity) { @self = entity; }}A property can be a float, double, an integer, bool, string, Color@, Float3@, an
Entity@ (pick one from the scene, or drag it from the hierarchy) or an asset: a Guid@ with
"asset:<Type>" as its default, such as "asset:Prefab" or "asset:Material". The description
shows when you hover over the property. In a networked game, replicated after the description
keeps the property the same on every machine (see
Networking).
When a script fails
Section titled “When a script fails”An error while a behavior runs turns that behavior off and logs where it failed, in the Console under Script: the script, the line and the message. The entity and its other behaviors carry on. In the Game tab, each error also shows as a notice.
Changing scripts while playing
Section titled “Changing scripts while playing”Behaviors run while the game plays in the Game tab, or while a scene page simulates. Save a behavior while it runs and it restarts with the new code: its fields start over, and its property values stay as set. For a Level or Game script, stop and play again.
To step through a script line by line, see Debugging scripts.