mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-10-23 05:51:39 +00:00
- Incremented the protocol version from 5 to 6 in the Atlas API documentation, reflecting the latest changes in server/plugin compatibility. - Added new API endpoints for live patch streaming and updated the server info response structure to include additional fields such as `unexpectedPlaceIds` and `gameId`. - Improved the WebSocket protocol documentation to align with the new versioning. - Enhanced metadata handling in the syncback rules and clarified the structure of meta files, including the introduction of new properties and adjustments to existing ones. These updates improve clarity and maintainability of the API documentation and ensure better alignment with the latest implementation changes.
370 lines
12 KiB
Text
370 lines
12 KiB
Text
---
|
|
description: "Project file format specification: .project.json5 schema, file extensions, middleware types, init files, sync rules, and property reference."
|
|
globs:
|
|
- "**/*.project.json5"
|
|
- "**/*.project.json"
|
|
- "**/*.meta.json5"
|
|
- "**/*.meta.json"
|
|
- "**/*.model.json5"
|
|
- "**/*.model.json"
|
|
---
|
|
|
|
# Atlas Project File Format
|
|
|
|
> Atlas is a fork of Rojo. Many internal identifiers, API endpoints, and struct names still reference the original "Rojo" naming.
|
|
|
|
## Project File Schema
|
|
|
|
**Recognized files:** `*.project.json5` (preferred) | `*.project.json` (legacy)
|
|
|
|
**Special:** `default.project.json5` inherits parent folder name.
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `name` | string | Yes* | Instance name (*optional if `default.project.json5`) |
|
|
| `tree` | ProjectNode | Yes | Root instance tree structure |
|
|
| `servePort` | number | No | Port for `atlas serve` (default: 34872) |
|
|
| `serveAddress` | string | No | Address to bind (default: `"127.0.0.1"`) |
|
|
| `servePlaceIds` | number[] | No | Only allow sync to these place IDs |
|
|
| `blockedPlaceIds` | number[] | No | Block sync to these place IDs |
|
|
| `placeId` | number | No | Set place ID on plugin connect |
|
|
| `gameId` | number | No | Set game/universe ID on plugin connect |
|
|
| `globIgnorePaths` | string[] | No | Glob patterns to ignore during sync |
|
|
| `syncRules` | SyncRule[] | No | Custom file type mappings |
|
|
| `syncbackRules` | SyncbackRules | No | Syncback configuration |
|
|
| `syncScriptsOnly` | bool | No | Only sync script instances (default: false) |
|
|
| `ignoreHiddenServices` | bool | No | Ignore internal services (default: true) |
|
|
|
|
```json5
|
|
{
|
|
"$schema": "https://raw.githubusercontent.com/UserGeneratedLLC/vscode-rojo/master/schemas/project.schema.json",
|
|
"name": "MyProject",
|
|
"tree": { /* ProjectNode */ },
|
|
"servePort": 34872,
|
|
"serveAddress": "0.0.0.0",
|
|
"servePlaceIds": [123456],
|
|
"blockedPlaceIds": [111111],
|
|
"placeId": 123456,
|
|
"gameId": 789012,
|
|
"globIgnorePaths": ["**/*.md", "**/node_modules/**"],
|
|
"syncRules": [/* SyncRule */],
|
|
"syncbackRules": { /* SyncbackRules */ },
|
|
"syncScriptsOnly": false,
|
|
"ignoreHiddenServices": true
|
|
}
|
|
```
|
|
|
|
## ProjectNode Schema
|
|
|
|
Used in `tree` and recursively for all children.
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `$className` | string | Instance class (required for non-services) |
|
|
| `$path` | string | Filesystem path to sync from |
|
|
| `$id` | string | Unique ID for Ref property linking |
|
|
| `$properties` | object | Instance properties to set |
|
|
| `$attributes` | object | Instance attributes to set |
|
|
| `$ignoreUnknownInstances` | bool | Whether to ignore instances not in project during sync |
|
|
|
|
**Keys without `$` prefix are child instances.**
|
|
|
|
```json5
|
|
{
|
|
"$className": "Folder",
|
|
"$path": "src/MyFolder",
|
|
"$id": "unique-id",
|
|
"$properties": { "Anchored": true },
|
|
"$attributes": { "Health": 100 },
|
|
"$ignoreUnknownInstances": false,
|
|
|
|
// Children
|
|
"ChildFolder": { "$className": "Folder" },
|
|
"MyScript": { "$path": "src/MyScript.luau" }
|
|
}
|
|
```
|
|
|
|
**Services auto-inferred:** Workspace, ReplicatedStorage, ServerScriptService, ServerStorage, StarterGui, StarterPlayer, Lighting, Teams, Chat, SoundService, LocalizationService, TestService, etc.
|
|
|
|
## File Extension Mappings
|
|
|
|
### Scripts
|
|
|
|
| Extension | Result | RunContext | Note |
|
|
|-----------|--------|------------|------|
|
|
| `*.luau` | ModuleScript | — | Preferred |
|
|
| `*.server.luau` | Script | Server | Preferred |
|
|
| `*.client.luau` | Script | Client | Preferred |
|
|
| `*.plugin.luau` | Script | Plugin | |
|
|
| `*.local.luau` | LocalScript | — | |
|
|
| `*.legacy.luau` | Script | Legacy | |
|
|
| `*.lua` | ModuleScript | — | Legacy |
|
|
| `*.server.lua` | Script | Legacy | Legacy |
|
|
| `*.client.lua` | LocalScript | — | Legacy |
|
|
| `*.plugin.lua` | Script | Plugin | Legacy |
|
|
|
|
**Prefer `.luau`** — modern RunContext. `.lua` is legacy (still supported).
|
|
|
|
### Models & Data
|
|
|
|
| Extension | Result | Note |
|
|
|-----------|--------|------|
|
|
| `*.rbxm` | Binary model | |
|
|
| `*.rbxmx` | XML model | |
|
|
| `*.model.json5` | JSON model | Preferred |
|
|
| `*.model.json` | JSON model | Legacy |
|
|
| `*.txt` | StringValue | |
|
|
| `*.csv` | LocalizationTable | |
|
|
| `*.json5` | ModuleScript (Lua table) | Preferred |
|
|
| `*.json` | ModuleScript (Lua table) | Legacy |
|
|
| `*.toml` | ModuleScript (Lua table) | |
|
|
| `*.yaml`, `*.yml` | ModuleScript (Lua table) | |
|
|
|
|
### Meta & Project
|
|
|
|
| Extension | Purpose | Note |
|
|
|-----------|---------|------|
|
|
| `*.meta.json5` | Add properties/attributes to sibling | Preferred |
|
|
| `*.meta.json` | Add properties/attributes to sibling | Legacy |
|
|
| `*.project.json5` | Nested project | Preferred |
|
|
| `*.project.json` | Nested project | Legacy |
|
|
|
|
## Init File Priority
|
|
|
|
When directory has multiple init files, first match wins:
|
|
|
|
1. `default.project.json5` → Nested project (preferred)
|
|
2. `default.project.json` → Nested project (legacy)
|
|
3. `init.luau` → ModuleScript (preferred)
|
|
4. `init.server.luau` → Script (Server)
|
|
5. `init.client.luau` → Script (Client)
|
|
6. `init.plugin.luau` → Script (Plugin)
|
|
7. `init.local.luau` → LocalScript
|
|
8. `init.legacy.luau` → Script (Legacy)
|
|
9. `init.csv` → LocalizationTable
|
|
10. `init.lua` → ModuleScript (legacy)
|
|
11. `init.server.lua` → Script (Legacy)
|
|
12. `init.client.lua` → LocalScript (legacy)
|
|
|
|
**No init file?** → Directory becomes Folder. **Prefer `.luau` and `.json5` extensions.**
|
|
|
|
## Sync Rules Schema
|
|
|
|
Custom file type handling in `syncRules` array:
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `pattern` | string | Yes | Glob pattern to match files |
|
|
| `use` | string | Yes | Middleware type (see table below) |
|
|
| `suffix` | string | No | Extension to strip from instance name |
|
|
| `exclude` | string | No | Glob pattern to exclude from matching |
|
|
|
|
```json5
|
|
{
|
|
"syncRules": [{
|
|
"pattern": "*.foo",
|
|
"use": "moduleScript",
|
|
"suffix": ".foo",
|
|
"exclude": "*.test.foo"
|
|
}]
|
|
}
|
|
```
|
|
|
|
### `use` Values
|
|
|
|
| Value | Result |
|
|
|-------|--------|
|
|
| `serverScript` | Script (Server) |
|
|
| `clientScript` | Script (Client) |
|
|
| `moduleScript` | ModuleScript |
|
|
| `pluginScript` | Script (Plugin) |
|
|
| `localScript` | LocalScript |
|
|
| `legacyScript` | Script (Legacy) |
|
|
| `json`, `toml`, `yaml` | ModuleScript |
|
|
| `csv` | LocalizationTable |
|
|
| `text` | StringValue |
|
|
| `jsonModel`, `rbxm`, `rbxmx` | Instance tree |
|
|
| `project` | Nested project |
|
|
| `ignore` | Skip file |
|
|
|
|
## Syncback Rules Schema
|
|
|
|
Configure `syncbackRules` object for Roblox → filesystem sync:
|
|
|
|
| Field | Type | Default | Description |
|
|
|-------|------|---------|-------------|
|
|
| `ignoreTrees` | string[] | `[]` | Roblox tree paths to skip (e.g., `"ServerStorage/Secrets"`) |
|
|
| `ignorePaths` | string[] | `[]` | Filesystem glob patterns to skip (e.g., `"src/generated/*"`) |
|
|
| `ignoreProperties` | object | `{}` | Properties to skip per class: `{"ClassName": ["Prop1", "Prop2"]}` |
|
|
| `ignoreClasses` | string[] | `[]` | Instance classes to skip entirely |
|
|
| `syncCurrentCamera` | bool | `false` | Whether to sync `Workspace.CurrentCamera` |
|
|
| `syncUnscriptable` | bool | `true` | Whether to sync unscriptable properties |
|
|
| `ignoreReferents` | bool | `false` | Whether to skip Ref properties (e.g., `Model.PrimaryPart`) |
|
|
| `createIgnoreDirPaths` | bool | `false` | Whether `/**` in ignore paths also matches the directory itself |
|
|
| `ignoreHiddenServices` | bool | — | Override root-level `ignoreHiddenServices` for syncback |
|
|
| `warnDuplicateNames` | bool | `false` | Warn on duplicate child names during syncback |
|
|
|
|
```json5
|
|
{
|
|
"syncbackRules": {
|
|
"ignoreTrees": ["ServerStorage/Secrets", "Workspace/Camera"],
|
|
"ignorePaths": ["src/generated/*", "src/temp/**"],
|
|
"ignoreProperties": {
|
|
"BasePart": ["Color", "BrickColor"],
|
|
"Script": ["Disabled"]
|
|
},
|
|
"ignoreClasses": ["Terrain", "Camera"],
|
|
"syncCurrentCamera": false,
|
|
"syncUnscriptable": true,
|
|
"ignoreReferents": false,
|
|
"createIgnoreDirPaths": false,
|
|
"warnDuplicateNames": false
|
|
}
|
|
}
|
|
```
|
|
|
|
## Meta Files
|
|
|
|
Add metadata to file-based instances. Meta files use **camelCase keys** (no `$` prefix -- that's only for ProjectNode).
|
|
|
|
**Adjacent meta** (e.g. `MyScript.server.meta.json5` for `MyScript.server.luau`):
|
|
|
|
```json5
|
|
{
|
|
"name": "Key:Script", // Override filename-derived instance name (slugify support)
|
|
"id": "unique-id", // For Ref property linking
|
|
"properties": { "Disabled": false },
|
|
"attributes": { "Priority": 1 },
|
|
"ignoreUnknownInstances": true
|
|
}
|
|
```
|
|
|
|
**Directory meta** (e.g. `init.meta.json5` inside a directory):
|
|
|
|
```json5
|
|
{
|
|
"name": "My:Folder", // Override directory-derived instance name
|
|
"className": "Configuration", // Override class (directory meta only)
|
|
"id": "unique-id",
|
|
"properties": { "Anchored": true },
|
|
"attributes": { "Health": 100 },
|
|
"ignoreUnknownInstances": false
|
|
}
|
|
```
|
|
|
|
**Key differences from ProjectNode:** Meta uses `className`, `properties`, `attributes` (camelCase, no `$` prefix). Adjacent meta does NOT support `className`.
|
|
|
|
**`name` field (slugify support):** When an instance name contains forbidden filesystem characters (`: / ? * < > | " \`), syncback slugifies the filename (forbidden chars → `_`) and stores the real name in the `name` field. On forward sync, `name` overrides the filename-derived instance name. On collisions (e.g. `A/B` and `A_B` both slugify to `A_B`), `~1`, `~2` suffixes are appended and meta `name` fields distinguish them.
|
|
|
|
**Meta files CAN'T:** Set `$path`, have children.
|
|
|
|
## Model.json5 Format
|
|
|
|
Inline instance definition. Like meta files, model files use **camelCase keys** (no `$` prefix).
|
|
|
|
```json5
|
|
{
|
|
"name": "What?Model", // Override filename-derived name (slugify support)
|
|
"className": "Tool",
|
|
"id": "unique-id",
|
|
"properties": { "CanBeDropped": false },
|
|
"attributes": { "Damage": 50 },
|
|
"children": {
|
|
"Handle": {
|
|
"className": "Part",
|
|
"properties": { "Size": [1, 1, 3] }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** Children are nested under a `"children"` key (not flattened like in ProjectNode).
|
|
|
|
## Property Formats
|
|
|
|
### Shorthand (Recommended)
|
|
|
|
```json5
|
|
{
|
|
"$properties": {
|
|
"Anchored": true, // Bool
|
|
"Health": 100, // Number
|
|
"Position": [0, 5, 0], // Vector3
|
|
"ImageRectSize": [100, 100], // Vector2
|
|
"Color": [1, 0, 0], // Color3 (normalized RGB)
|
|
"BrickColor": "Bright red", // BrickColor name
|
|
"Shape": "Ball", // Enum name
|
|
"Tags": ["Collectible", "PowerUp"], // Array
|
|
"Size": { "X": {"Scale": 1, "Offset": 0}, "Y": {"Scale": 0, "Offset": 100} }, // UDim2
|
|
"CFrame": { "position": [0, 5, 0], "orientation": [[1,0,0],[0,1,0],[0,0,1]] } // CFrame
|
|
}
|
|
}
|
|
```
|
|
|
|
### Explicit Type
|
|
|
|
Use when ambiguous or specifying enum by number:
|
|
|
|
```json5
|
|
{
|
|
"$properties": {
|
|
"Position": { "Vector3": [0, 5, 0] },
|
|
"Shape": { "Enum": 1 },
|
|
"BrickColor": { "BrickColor": 21 }
|
|
}
|
|
}
|
|
```
|
|
|
|
## Attributes
|
|
|
|
Same format as properties. Limitations: no Ref, no NumberSequence/ColorSequence, enums use string names only.
|
|
|
|
```json5
|
|
{
|
|
"$attributes": {
|
|
"Health": 100,
|
|
"Position": [0, 5, 0],
|
|
"MyFont": { "family": "rbxasset://fonts/families/SourceSansPro.json", "weight": "Regular", "style": "Normal" }
|
|
}
|
|
}
|
|
```
|
|
|
|
## Ref Property Linking
|
|
|
|
Link instances via `$id` and special attributes:
|
|
|
|
```json5
|
|
{
|
|
"tree": {
|
|
"Target": { "$className": "Part", "$id": "myTarget" },
|
|
"Pointer": {
|
|
"$className": "ObjectValue",
|
|
"$attributes": { "Rojo_Target_Value": "myTarget" }
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**Attribute format:** `Rojo_Target_<PropertyName>`
|
|
|
|
## Property Types
|
|
|
|
`String`, `Bool`, `Int32`, `Int64`, `Float32`, `Float64`, `Vector2`, `Vector3`, `Vector2int16`, `Vector3int16`, `UDim`, `UDim2`, `CFrame`, `Color3`, `Color3uint8`, `BrickColor`, `NumberRange`, `Rect`, `NumberSequence`, `ColorSequence`, `Enum`, `Ref`, `Content`, `Font`, `PhysicalProperties`, `Axes`, `Faces`, `Tags`, `Attributes`
|
|
|
|
See `rbx_reflection_database` for property listings per class.
|
|
|
|
## Validation Errors
|
|
|
|
1. Unknown fields (except children)
|
|
2. Reserved names starting with `$` as children
|
|
3. Missing `$className` or `$path`
|
|
4. `$path` to non-existent file
|
|
5. Invalid property types
|
|
6. Invalid glob syntax
|
|
7. Duplicate `$id`
|
|
|
|
## Source Files
|
|
|
|
- `src/project.rs` - Project parsing
|
|
- `src/snapshot_middleware/mod.rs` - Extension mappings
|
|
- `src/snapshot/` - Instance tree structure
|