Creating & Using Scripts
Last updated
Last updated
T# (pronounced T-Sharp) is Terra Studio’s scripting language, designed to feel familiar to Unity developers with a syntax similar to C#. It gives creators the freedom to write custom logic for their games .
If you already know Unity C#, you’ll feel right at home. However, T# has a few important differences to support live editing and interpreted execution.
In the latest Terra Studio workflow, scripts are attached to GameObjects through the TerraMachine
component.
To set this up:
Select your GameObject in the scene.
In the right-hand Inspector panel, click "Add Component".
Search for and add the TerraMachine
component.
In the dropdown, select the T# script you want this machine to run.
💡 You must create the script before assigning it in the TerraMachine (see below).
Open the Scripts tab in the left panel.
Click the ➕ button to create a new script.
Name the script and press Enter.
Your script will open in Visual Studio Code, along with all other project scripts.
You’ll find your file in the Scripts Directory.
Now, edit the generated class to implement your desired game behavior.
Here’s what a default T# script looks like:
All scripts must extend TerraBehaviour
or TerraNetBehaviour
(for multiplayer).
The class name must match the file name.
Start()
runs once at the beginning.
Update()
runs on every frame.
For networked games, extend TerraNetBehaviour
instead:
These methods are called automatically during multiplayer object lifecycles.
To define variables for your script:
Select a GameObject in your Unity scene.
In the Inspector, add a TerraMachine component.
Select the T# script you want this object to run.
Once selected, a new section called Object Variables will appear below the script field.
Click the + icon to add a new variable.
You can create one of four types:
String
Float
Int
GameObject
Each variable must have:
A unique name
An initial value that the script can read when the game starts
These variables can only be accessed from the script attached to the same TerraMachine. They are not shared globally or across multiple objects unless explicitly managed.
To use these variables in your script, you must:
Declare local variables inside your script to store their values.
Use Terra’s built-in getter methods like GetFloatVariable()
or GetStringVariable()
inside a function like Start()
to retrieve them.
✅ Example: Accessing a string variable
Let's say you've added a string variable named myName
to a GameObject’s TerraMachine and set it to "Terra"
.
If the variable "myName"
does not exist on this object, your code will throw an error at runtime. You will also get an error if
You can also fetch multiple variables of different types in one script:
Note that all variables values are assigned in the Start() method
In Terra Studio, you don’t write continuous loops like in traditional programming. Instead, the engine calls event functions in response to gameplay events — such as object initialization, collisions, updates per frame, user clicks, and more.
If you’ve worked with Unity before, this will feel very familiar. However, keep in mind that you are writing T# scripts that run inside the TerraMachine component added to GameObjects in your Unity scene.
T# supports a subset of Unity-style lifecycle methods, along with some limitations. This section outlines which events are supported and how to use them effectively.
Start()
The Start
method runs once at the beginning of a GameObject’s lifecycle — just after all variables and components have been initialized. This is where you should fetch object variables, set up references, or run any custom initialization logic.
Update()
The Update
method is called once per frame. Use this for dynamic logic such as input handling, movement, or timers.
FixedUpdate()
This is used for physics-based updates. It runs at a fixed interval and is ideal for applying forces or detecting rigidbody behavior.
Note: LateUpdate()
is not supported in T#. To execute logic after rendering or animations, use a coroutine with WaitForEndOfFrame()
.
T# supports Unity-style coroutines using IEnumerator
. These let you pause and resume logic across multiple frames — useful for animations, time-based triggers, or conditional delays.
Here’s a basic coroutine:
You start a coroutine using:
Let’s say you want to check if an enemy is nearby, but only once every 0.1 seconds:
Start this in Start()
or Update()
:
You can detect when a GameObject is clicked using OnMouseDown()
:
Make sure the GameObject has a collider component to receive click events.
Detect object collisions using OnCollisionEnter
. Combine this with an object variable to filter specific GameObjects.
When using TerraNetBehaviour
(instead of TerraBehaviour
), two special methods become available:
Use these to initialize or clean up network-specific data.
In earlier versions of Terra Studio, there was an OnBroadcasted()
method that responded to broadcast messages. This is no longer supported.
To implement custom broadcast behavior:
Use shared variables or flags
Poll for signals in Update()
or trigger logic manually via coroutines or function calls
Handle events using Unity-style component communication (GetComponent
, method calls, etc.)
For multiplayer games using TerraNetBehaviour
, there are special network lifecycle methods:
In earlier versions of Terra Studio, there was an OnBroadcasted()
method that responded to broadcast messages. This is no longer supported.
To implement custom broadcast behavior:
Use shared variables or flags
Poll for signals in Update()
or trigger logic manually via coroutines or function calls
Handle events using Unity-style component communication (GetComponent
, method calls, etc.)