Places and Rojo projects✎
Bringing a game in from its Rojo project or its place, browsing the place, and writing scripts back into it.
Verified
Most games already exist as a Rojo project, a place file, or both. This page is how Roswaal takes either in, shows you the place, and writes your scripts back into it. How a graph compiles is on Compiling and nodemaps for Roblox.
Starting from a Rojo project
A project Rojo already manages has its tree in default.project.json. Project → Import Rojo project…, or roswaal import default.project.json, reads it into a node map beside your graphs. The file is not changed, and every field in it is kept, including ones the map editor has no control for.
This map
Instance
Globs under this instance's path that Rojo should skip, e.g. shared/** — how you stop a nested mapping syncing twice.
Project file
Written to default.project.json when this map is compiled.
Passed to Rojo as globIgnorePaths, unanchored.
{ "name": "orchard", "tree": { "$className": "DataModel", "ReplicatedStorage": { "Shared": { "$path": "src/shared" }, "Packages": { "$path": "Packages" } }, "ServerScriptService": { "Server": { "$path": "src/server" } }, "StarterPlayer": { "StarterPlayerScripts": { "Client": { "$path": "src/client" } } } }}
- The treeEvery instance the map describes. Pick one and the Inspector follows.
- DescribesWhether this is a DataModel for Roblox or a filesystem for Lune. It decides what the rest of the panel is.
- NameThe instance's name in the DataModel.
- ClassBlank on a service, because Rojo infers it from the key and rejects it being said twice.
- PathThe folder or file on disk whose contents fill this instance.
- Ignore unknownRojo leaves alone anything in Studio that it did not put there.
- Ignore pathsGlobs under this instance's path that Rojo should skip.
- Add folder, Add service, DeleteBuild the tree. Services can only be added to the root.
- OutputWhere the project file is written, relative to the project root.
- Project-wide ignoresPassed to Rojo as globIgnorePaths, unanchored.
- The project fileWhat the map compiles to. Selecting a row lights the lines that row writes.
It asks which. Project File Only is the map, and your Luau stays hand-written, as the tree already lists it. Project File + Luau as Graphs is the map and then every hand-written .luau in the folders the file syncs, read into graphs with one set of Import as graph settings. Wally's packages are left out, and the .luau files are not changed.
Browse…, Open .zip… and Open folder… offer the same when there is a project file no map writes, with a list to pick from when there are several. A place file in the zip or folder is found too.
When the map compiles back to the same project, the map writes the file from then on. Compiling leaves it alone until the map changes, and then keeps its indentation and line endings. If the map would write it differently, the file stays yours until you compile with force.
Starting from nothing
roswaal new, Create on the start page and New project… in the editor make a project with place.rbxl unless you say not to: the place Studio starts a new experience with. A 2048-stud Baseplate with its top at height 0, a 12-stud SpawnLocation standing on it at the centre, and Studio's sky, light and chat. Roswaal writes it itself rather than copying Studio's Baseplate template, and Studio makes the Camera and the Terrain when the file is opened. roswaal export writes the project's scripts into it, with the folders they need.
Starting from a place
roswaal import place.rbxl makes a new project from a .rbxl or .rbxlx. Scripts Rojo can sync go under src/, and every service in the node map it writes has Ignore unknown, so Rojo never removes a part it was not given. The place is copied into the project.
A script inside a part, a model or a GUI stays in the place: Rojo cannot sync it without owning its parent. --scripts all brings those out too, under place/, where Rojo does not look. Identical copies become one file unless you pass --no-merge.
In the web app, Project → Open place… does the same, and asks the same questions with the counts in front of you. The place is kept with the project, and Export includes it.
Browsing the place
When the project has a place, the Project panel switches between Files and DataModel. DataModel lists the place's instances as Studio's Explorer does: its usual services first, children by name, and empty services at the end. Filter by name, or by a class name typed in full.
Double-click or double-tap an instance to open the Properties panel on the right: its properties, tags and attributes under Studio's headings. While it is open it follows what you pick, and a reference goes to what it names. For a script a project file writes, Open opens that file, and its graph when one generates it.
Changing properties
Turn on Settings → Workspace → Modify DataModel Instances and Properties changes values as well as showing them. Click a value to type over it, tick a box, pick from a list, or pick a colour from its swatch. Enter writes it; Esc puts it back.
Each change is written into the place file straight away. The first one asks, and a copy of the file as it was goes in .roswaal/backups first, and again whenever the file has changed since Roswaal last wrote it.
| Can be changed | Not yet |
|---|---|
| True or false, numbers, text, enums, colours and BrickColors; vectors, sizes, UDims, UDim2s, ranges and rects, a field a component; CFrames, as a Position and an Orientation in degrees; and references, picked from the place's instances of the class they take. On properties a script can set. Attributes and tags too, added and removed with the + and × beside them, and names, on anything but a service | Scripts' source, which is the project's to write |
Warning
Dragging onto a graph
| Drag from Properties | What it makes |
|---|---|
| A property | An Instance node at the instance's path, cast to its class, wired into Get Member, typed as the property is |
A property, with Ctrl held as you drop | The same, into Set Property. A read-only property stays a Get Member |
| An attribute | Get Attribute, or Set Attribute with Ctrl |
| The instance's name | The Instance node alone |
An instance dragged from the DataModel list makes the Instance node alone too.
local Workspace = game:GetService("Workspace") print(Workspace.House.Door.Anchored)
Ctrl held: Set Property.local Workspace = game:GetService("Workspace") Workspace.House.Door.Anchored = false
local Workspace = game:GetService("Workspace") print(Workspace.House.Door:GetAttribute("IsOpen"))
Dragging into code
Drop an instance, a property or an attribute into Code Block's editor and it writes the Luau that reaches it, where you let go. The DataModel and Properties stay above the editor while it is open, to drag from.
| Dropped on | What it writes |
|---|---|
| A blank line of Code Block | local Tank = game:GetService("ReplicatedStorage").Tank |
| Anywhere else, or a box that holds one value | The path alone |
Writing scripts into the place
Export, beside Settings in the top bar, takes the project out as a zip, or its place file alone. Ctrl + Shift + E opens it too, and Project → Export… is still there. For a project with a place it says what Modify RBXL would write and add before you choose; Don't Modify RBXL sends the place as it was. The project's own place file is not changed either way. roswaal export out.rbxl writes the modified place to a file.
Save as writes the place as .rbxl, or as Legacy .rbxlx, whichever the project keeps. A place saved in the other format leaves out the kinds of property Roswaal cannot write yet, and the menu names them first. When a graph has changed since it was compiled, Compile first compiles it before the export. Ticked, Start with these choices keeps them in roswaal.json, and Settings → Compiling → Exporting shows them.
A script is found by the id the import recorded, or by its path, and a merged file is written into every copy. A file whose script is not in the place yet — a graph made since — is added, with a Folder for each part of its path the place does not have. Nothing else in the place changes.
| Export says | Why the file was not written |
|---|---|
| No service in the place for | Its path starts at a service the place does not have |
| More than one script with that path | Two siblings share a name, so which one is meant is not certain |
| A different kind of script in the place | Module code where the place has a Script, or the other way round |
| Still in the place, with no file now | The file was removed or renamed. The script stays; delete it in Studio if it should go |
Last reviewed 30 September 2026 by @neopolitans