Write scripts
Scripts make your game do things. In Rally they’re written in TypeScript and live in the game’s tree, often right next to what they control: a door’s script can sit inside the door. Studio never runs your scripts while you edit. They run when you test and when people play.
This page is about working with scripts in Studio. To learn the game API itself, start with Scripts and modules.
Three kinds of scripts
Section titled “Three kinds of scripts”| Kind | Runs | Where to put it |
|---|---|---|
| Script | On the server. | In Workspace (for example, inside the part it controls) or in ServerScriptService. |
| LocalScript | On each player’s device. | In StarterPlayerScripts (inside StarterPlayer), or in a ScreenGui in StarterGui. |
| ModuleScript | When another script imports it. | Anywhere. ReplicatedStorage is the usual home for shared code. |
A Script or LocalScript somewhere else doesn’t run. The Explorer marks it won’t run here; hover over the label to see why.
Add a script
Section titled “Add a script”-
Select where the script should go, such as a part in Workspace.
-
Choose Insert > Scripts > Script, LocalScript or ModuleScript. You can also right-click an object in the Explorer and choose Insert Object.
-
Rename it with F2, then double-click it to open it.
If your selection isn’t a place where that kind of script runs, Studio puts it in the usual spot:
- a Script goes inside the selected object if that’s in Workspace or ServerScriptService, otherwise into ServerScriptService;
- a LocalScript goes inside the selected object if that’s in StarterPlayerScripts or StarterGui, otherwise into StarterPlayerScripts;
- a ModuleScript goes inside the selected object, otherwise into ReplicatedStorage.
New scripts start with a little code. A new Script prints a greeting when the game starts:
import { print } from '@rally/sdk';
print('Hello from the server!');The code editor
Section titled “The code editor”Double-click a script in the Explorer to open it in a tab above the viewport. Open as many as you like; select World to get back to your world, and close a tab with its × or a middle-click. Each tab remembers where you were.
The editor checks your TypeScript against Rally’s game API as you type. It suggests names as you type and underlines problems in red, including mistakes in imports between your own scripts.
The bar under the editor shows:
- the script’s path in the tree, like
Workspace/Door/Open; - where it runs: Runs on the server, Runs on each player’s device, Shared code — runs when a script imports it, or Doesn’t run here;
- who else has it open, for example Sam also editing;
- the number of problems, or a check mark when there are none;
- Check, which builds all your scripts without starting a test and lists any errors in Output.
Your code saves as you type, and collaborators see it change. If two people type in the same script at the same time, one person’s changes can overwrite the other’s, so take turns when the bar says someone else is editing. A script can be up to 200,000 characters long.
While you’re typing in the editor, Studio’s own shortcuts are paused and the editor’s take over. For example, Ctrl/⌘+Z undoes typing.
Import code
Section titled “Import code”Every script imports Rally’s game API from @rally/sdk. To share code between scripts, put it in
a ModuleScript and import it:
- by its path in the tree:
@game/ReplicatedStorage/Config; - or, for a ModuleScript next to your script, relative to the script’s parent:
./DoorLogic.
export const START_COINS = 10;import { Players, print } from '@rally/sdk';import { START_COINS } from '@game/ReplicatedStorage/Config';
Players.playerAdded.connect((player) => { print(`${player.displayName} joined with ${START_COINS} coins`);});Things to know:
- Besides
@rally/sdk, scripts can only import ModuleScripts, by@game/...path or by a relative path. Scripts and LocalScripts can’t be imported, and outside packages aren’t available. - Names are paths. Renaming or moving a ModuleScript changes how you import it, and if two objects at the same place share a name, rename one so imports know which one you mean.
- A script that lives inside an object can reach it with
script.parent:
import { Character, Part, script } from '@rally/sdk';
const lava = script.parent;if (!(lava instanceof Part)) throw new Error('Put this script inside a part');
lava.touched.connect((other) => { if (other instanceof Character) other.health = 0;});Find and fix errors
Section titled “Find and fix errors”Studio reports two kinds of problems:
- Problems the editor finds as you type, such as a misspelled property or a value of the wrong type. They’re underlined in red and counted in the bar under the editor. They don’t stop a test from starting, but they usually mean a bug, so fix them.
- Errors that stop your game from building, such as a syntax error or an import that points at nothing. Studio finds these when you test, select Check or publish. Nothing runs or publishes until you fix them.
When a test or Check can’t build your game, Studio shows a notice and lists every error in
Output as Path.ts:line:column: message, for example ServerScriptService/Main.ts:4:9: .... The
script also gets a red underline at that spot. If Publish finds errors, it stops and names the
first one; select Check to see them all.
Errors that happen while your game runs show up in Output in red, with their locations pointed at the lines of your TypeScript.
Select any underlined line in Output to open the script at that line.
Turn a script off
Section titled “Turn a script off”Select a Script or LocalScript and clear its enabled property in Properties to keep it from
running, without deleting it.
Scripts that open as JavaScript
Section titled “Scripts that open as JavaScript”Sometimes a script opens with a yellow note saying it’s compiled JavaScript from a published version. That happens when the version the game was opened from didn’t include its TypeScript, for example the first version of a game created from a template. These scripts still work as they are. To edit one comfortably, rewrite it in TypeScript.
Learn more
Section titled “Learn more”- Scripts and modules covers how scripts run and share code.
- Debugging has more ways to find problems.
- Test your game shows how to run your scripts and read their output.