rblxsync is a Rust CLI + GitHub Action that declaratively manages Roblox
experience metadata via the Open Cloud API. One YAML file (rblxsync.yml) is the
source of truth for Universe settings, Game Passes, Developer Products, Badges,
and Places. Running it is idempotent: resources are matched by name
(case-insensitive), created if missing, updated (PATCH) if present.
Use this skill to set rblxsync up in a user's Roblox project, author/edit their
config, run syncs safely, and wire the generated Config.luau into game code.
Mental model (read this first)
rblxsync.yml= desired state, hand-edited, committed.rblxsync-lock.yml= generated state (resource IDs + icon hashes). Commit it. Never hand-edit it — it is overwritten on the next sync.Config.luau(only ifoutput_pathis set) = generated, typed Luau module of all resource IDs. Game coderequires it. Never hand-edit it.- Matching is by name. Renaming a resource in the YAML makes rblxsync think it is a new resource (it creates a second one) rather than renaming the old. To rename, change it in Roblox/lock state, not just the YAML. Flag this to the user before any rename.
Golden rules
- Never run a mutating sync without previewing first. Always do
rblxsync run --dry-runand show the user the diff beforerblxsync run. - Never commit, print, or paste
ROBLOX_API_KEYorROBLOX_COOKIE. They live in a gitignored.env(local) or CI secrets. Treat them like passwords. - The
--configflag is global and goes BEFORE the subcommand.rblxsync --config prod.yml run✅ —rblxsync run --config prod.yml✗. - Creating a badge costs 100 Robux each. Confirm with the user before a sync that adds new badges.
- Confirm before destructive or paid actions: new badges (Robux), publishing
places (goes live), any first real
run.
Setup workflow (new project)
Run these steps when adding rblxsync to a codebase that doesn't have it yet.
- Confirm install. Check
rblxsync --version/which rblxsync. If absent, install (cargo install --path .from source, or a tool-manager pin once binaries are published — seereferences/cli-and-ci.md). - Create
.envwithROBLOX_API_KEY=...and ensure.envis gitignored. AddROBLOX_COOKIE=...only if the config will set universe settings (see the cookie gotcha below). Never write real secret values yourself — leave placeholders and tell the user to fill them in. - Write a minimal
rblxsync.yml— onlyuniverse.idis required. Start small; add sections incrementally. Copyassets/rblxsync.example.ymlas a starting point and trim it to what the user actually needs. - Validate:
rblxsync validate(no API key / network needed). - Preview:
rblxsync --config rblxsync.yml run --dry-run. - Apply:
rblxsync runonce the user approves the preview. - Commit
rblxsync.ymlandrblxsync-lock.yml(NOT.env). Ifoutput_pathis set, commit the generatedConfig.luautoo.
Minimal config
Only universe.id is required:
universe:
id: 123456789
game_passes:
- name: "VIP Pass"
price: 100
For the full field-by-field schema, defaults, and every gotcha, read
references/config-schema.md. A complete annotated sample is in
assets/rblxsync.example.yml.
Commands
| Command | What it does |
|---|---|
rblxsync run [--dry-run] |
Sync universe settings + game passes, products, badges. Default command. Writes rblxsync-lock.yml and (if set) Config.luau. |
rblxsync publish |
Publish .rbxl places where publish: true. Always publishes (no "save"). Does NOT need the cookie. |
rblxsync validate |
Parse + check the YAML (dup names, etc.). No API key, no network. |
rblxsync export [-o PATH] [--lua] |
One-way snapshot of live resources to a flat Luau/Lua table. NOT a config you can feed back in, and NOT the same shape as Config.luau. |
Full command reference, flags, the GitHub Action, environment variables, and
Open Cloud permission scopes are in references/cli-and-ci.md.
The cookie gotcha (very common error)
rblxsync run hard-fails demanding ROBLOX_COOKIE whenever any universe
field is set — including genre and max_players, which are local-only and
never actually call a cookie API. So a config that sets only genre still
requires the cookie even though no cookie request is made.
If a user hits "ROBLOX_COOKIE is not set" and doesn't want to provide a cookie,
the fix is to remove all universe.* fields except id from the config (move
name/description/etc. tracking elsewhere). Universe settings updates use
.ROBLOSECURITY cookie auth against develop.roblox.com — an API key alone
cannot update them. See references/cli-and-ci.md for how to obtain the cookie
safely.
Fields that don't sync (surface these, don't silently rely on them)
genreandmax_players— tracked in lock/Config.luaubut never pushed to Roblox (max_playersis a per-place setting).- Developer Product
is_active— parsed but not synced; has no effect. - Game Pass
is_for_sale— this one is synced.
Do not type game code against a Developer Product IsActive field — the generated
DeveloperProduct type has no such field ({ Id, Name, Description, Price }).
Integrating with game code
If the user wants resource IDs available in Luau, set output_path (e.g.
src/shared/Config.luau or a Rojo-mapped path) and require the generated module:
local Config = require(game.ReplicatedStorage.Shared.Config)
local vipId = Config.GamePasses[1].Id
print(Config.Universe.Name)
Wiring it cleanly (lookup by name, Rojo paths, regenerate-on-sync, lock-file
commits) is covered in references/integration.md — read it before editing a
user's existing Luau to consume rblxsync output.
Adding to CI
A ready-to-use workflow template is in assets/github-workflow-sync.yml. Copy it
to .github/workflows/, set repo secrets (ROBLOX_API_KEY, optionally
ROBLOX_COOKIE), and pin the action to a published ref (e.g. @v0.1.0). The CI
gotchas (the args input word-splits and cannot contain spaces; only published
tags exist) are in references/cli-and-ci.md.
When unsure
- Schema / field semantics / defaults →
references/config-schema.md - CLI flags, Action inputs, env vars, permission scopes →
references/cli-and-ci.md - Consuming output in Luau, lock-file handling, idempotency →
references/integration.md - Authoritative upstream docs: the project's
README.mdanddocs/API.md.