Core concepts
A project is the folder containing your game. A scene describes a world inside that project. Entities are its objects; components give each object its data and capabilities. Scripts supply gameplay behavior.
Projects and scenes
A typical project uses these folders. Not every folder is created until its feature is used.
MyGame/
Scenes/ readable .ttrscene files
Assets/ models, textures and asset records
Scripts/ gameplay JavaScript
Cutscenes/ .cutscene.json timelines
Saves/ saved gameplay state in live play
A scene file is readable text, not a compiled executable. Saving a scene records its editable objects and components. Saving a game through game.save records supported play-session state; it is not the same operation.
Entities
An entity is a named object with an ID. It might be a lamp, a player, a trigger, or a rules object with no visible mesh. Many agent tools accept an entity name or an ID string such as #7; list_entities shows what exists. Names in examples are not objects created automatically for you.
Groups organize the scene list. Tags in an about component give scripts a way to find categories, such as world.all("pickup"). A tag is not a mesh, collider or script by itself.
Components
A component is a block of data attached to an entity. A transform supplies position, rotation and scale. A mesh_renderer supplies appearance. A light component supplies light. A script component attaches gameplay code. The current component catalogue, field names and defaults are available through the list_components tool; use it rather than guessing a field name.
Here is a small scene-text example, including a light and a cube. It illustrates the format; open/save it in a separate test scene rather than pasting over an existing world.
scene {
format 1
title "GuideScene"
next_id 3
}
entity Sun #1 {
directional_light { azimuth 215 elevation 38 intensity 3 color (1, 1, 1) }
}
entity Guide_Crate #2 {
group "Props"
about { role "A cube for learning" tags ["demo"] }
transform { position (0, 1, 0) rotation (0, 0, 0) scale (1, 1, 1) }
mesh_renderer { mesh "builtin:cube" color (0.8, 0.3, 0.1) }
script { file "guide-spin.js" params ["speed=30"] }
}
Three-dimensional scene positions use meters and Y-up coordinates. Vector fields in scene text use parentheses; JavaScript arrays use square brackets. Do not paste a JavaScript object in place of scene-component text.
Scripts
Create Scripts/guide-spin.js in the project and attach the script component shown above. The same file can be attached to multiple entities; each file/entity instance gets its own closure. self is the entity receiving the callback. dt is elapsed simulation time in seconds.
function onStart(self) {
log("Started", self.name);
}
function onTick(self, dt) {
var speed = self.params.speed === undefined ? 30 : self.params.speed;
var r = self.rotation;
self.rotation = [r[0], r[1] + speed * dt, r[2]];
}
A speed of 30 here means 30 degrees per simulation second. Start Play to instantiate the script. The write_script tool syntax-checks and writes code, but does not hot-replace the handlers of an already running Play session; stop and start Play after editing it.
Only define the callbacks you need: onStart, onTick, onEnter, onExit, and onMessage. They are listed in the script reference. These bindings provide the game APIs, not a browser DOM or Node.js filesystem API.
Transient state and saved state
Use closure variables for temporary state belonging to one script instance. Avoid attaching arbitrary fields to the transient self wrapper and expecting them to survive the next callback. Use self.params for the parsed component parameters and self.save for plain data that should be included in saved games.
function onMessage(self, name, data) {
if (name === "collected") {
self.save.collected = (self.save.collected || 0) + 1;
}
if (name === "loaded") {
log("Loaded slot", data.slot, "with", data.data);
}
}
Call game.save("progress") to request a save and check its boolean result. During a callback, an accepted game.load("progress") is applied at a safe boundary; a true return is not a promise that every value changed before the next line of that callback. Save data is checked for compatibility with the current scene.
Commands, history and rehearsals
Normal editor scene changes go through commands, which support History and Undo. An agent can begin a rehearsal to try scene changes separately, inspect and test that proposal, then merge or discard it.
A rehearsal is not a full filesystem snapshot. Shared-asset changes and scene replacement can be blocked while it is open; script files, generated models and recordings are not universally reversed by scene Undo. Read a tool's description before treating it as harmless inspection.
A useful working loop
Inspect the current scene, make one understandable change, then inspect and test its result. get_entity and list_components help with structure; play_test checks behavior on a copy; screenshot and inspect help with visible results. Read the test outcomes and the image instead of treating a successful request as approval of the game.