Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rbx init

Bootstrap Roblox resources from the command line: create groups, universes, and places, then list IDs to plug into the other rbx subcommands.

rbx init covers the missing first step in a Roblox project bootstrap. You start with nothing and you need a group, a universe, and a few places before rbx place, rbx meta, rbx config, or rbx shop have anything to point at. It hits Roblox’s authenticated creation endpoints (cookie-based, since Open Cloud doesn’t expose these yet) and the listing endpoints so you can pipe fresh IDs straight into your other configs.

Features

  • Create a group: rbx init create-group --name ... --icon icon.png
  • Create a universe: rbx init create-universe [--group <id>], returns the universe ID and the root place ID in one call
  • Create a place inside an existing universe: rbx init create-place --universe-id <id>
  • Auto-record into rbxplace.toml: both creates append their new ids to the shared env map, prompting for the env/place name — comments and formatting in the file are preserved
  • Rename a place / universe by id: rbx init rename-place / rbx init rename-universe
  • List your groups: rbx init list-groups (cookie required)
  • List a group’s universes: rbx init list-universes --group <id> (no credential needed; see what these listings expose)
  • List a universe’s places: rbx init list-places --universe-id <id> (no credential needed)
  • Cookie auto-detect: offers to use the .ROBLOSECURITY of a local Roblox Studio install when no cookie was supplied. Opt-in: an interactive run is asked once, a run with nowhere to ask declines and says so. --auto-cookie is the standing yes. See docs/cookie.md
  • Friendly errors: common cases (name already taken, moderation rejection) are surfaced with a clear message instead of raw HTTP

Quick start

Bootstrap a brand-new project with a group, a universe, and an extra lobby place:

# 1. Create the group (returns id 123456789)
rbx init create-group --name "My Studio" --icon assets/group-icon.png --public

# 2. Create a universe under that group (returns universe_id + root_place_id)
rbx init create-universe --group 123456789 --name "[TEST] My Game" --env test

# 3. Add a second place inside the universe
rbx init create-place --universe-id 987654321 --name "Lobby" --place lobby

Steps 2 and 3 record their ids in rbxplace.toml as they go, so there’s nothing to copy by hand. Omit --env/--place/--name and you’ll be asked for them instead.

Starting from an existing group with universes already created? rbx init list-universes --group <id> prints their ids; write the [<env>] sections yourself, then check the result with rbx env list. See the field reference for what goes where.

Commands

rbx init create-group

Create a new Roblox group. An icon is required by Roblox (PNG or JPEG).

FlagRequiredDescription
--nameYesGroup display name
--iconYesPath to a PNG/JPEG icon file
--descriptionNoGroup description (default: empty)
--publicNoMake the group publicly joinable (default: invite-only)
--yes / -yNoSkip the confirmation prompt

Roblox requires the authenticated user to be eligible to create groups (verified email + minimum account age). If the chosen name is already taken, rbx init prints a clear message instead of a raw HTTP error.

rbx init create-universe

Create a new universe with a root place. The default template is Roblox’s empty baseplate; override with --template-place-id to clone from a specific place you own.

The new universe is recorded in rbxplace.toml as a new [<env>] block, so you don’t have to copy ids by hand afterwards.

FlagRequiredDescription
--groupNoGroup ID to create the universe under
--userNoUser ID to create the universe under. Mutually exclusive with --group
--template-place-idNoTemplate place ID to clone from (defaults to Roblox’s empty baseplate)
--nameNoRename the universe’s root place to this name after creation (Roblox displays the root place name as the universe name). Prompted for when omitted
--envNoEnv name to record the universe as. Prompted for when omitted. Refused with --no-record
--placeNoPlace key for the root place (default main). Refused with --no-record
--no-recordNoDon’t touch rbxplace.toml. Refused alongside --env or --place, which would be asking for the record and refusing it in one command
--yes / -yNoSkip the confirmation prompt. Whether the universe is still recorded depends on --env — see below

Owning it without a group. Omitting both --group and --user is not an error and does not require a group: the owner falls back to [owner] in rbxplace.toml, and with no [owner] either, to your own user account. So a personal universe is rbx init create-universe with neither flag.

Run it bare and it asks for what it needs, then confirms everything in one line:

$ rbx init create-universe
  Universe name (empty to keep the template's): My Test Game
  Env name in rbxplace.toml: (my_test_game) test
⚠ Create universe 'My Test Game' under group 1234567 and record it as [test]? [y/N] y
Creating universe under group 1234567 ...
Renaming root place 111222333 to My Test Game ...
Created universe (id 9876543299) with root place (id 111222333)
  name: My Test Game
Added [test] to rbxplace.toml

Or name everything up front for an unattended run:

rbx init create-universe --name "[TEST] My Game" --env test -y

Both prompts appear only when the corresponding flag is missing and stdin is a terminal.

Whether anything is recorded follows one rule, and --env is what decides it:

The runRecorded?
--no-recordNever, whatever else is passed
--env <name> givenYes, including under --yes and off a terminal. A missing rbxplace.toml or an env that already exists is an error, not a silent skip
neither, on a terminal, with the file presentYes, after asking for the env name
neither, under --yes, off a terminal, or with no rbxplace.tomlNo, silently

The middle row is the one worth knowing: --env is a request, so it is honoured rather than suppressed by --yes. That is what makes the unattended example above record. Without --env, --yes means “ask me nothing”, and since recording is driven by the prompt it is skipped rather than guessed at.

This command extends an existing rbxplace.toml; it does not create one.

If --name is given, the env name is suggested from it: a [TEST] ... prefix becomes test, otherwise the name is slugified.

Every question is asked before the universe is created. Creating one is irreversible, so aborting at a prompt costs nothing more than a re-run.

rbx init create-place

Add a new place inside an existing universe.

The new place is recorded under the env whose universe_id matches --universe-id, so there’s no env to pick: only the key name is asked for.

FlagRequiredDescription
--universe-idYesUniverse ID to create the place in
--template-place-idNoTemplate place ID to clone from (defaults to Roblox’s empty baseplate)
--nameNoRename the new place to this name after creation. Prompted for when omitted
--placeNoPlace key to record in rbxplace.toml. Prompted for when omitted (suggested from --name). Refused with --no-record
--no-recordNoDon’t touch rbxplace.toml. Refused alongside --env or --place
--yes / -yNoSkip the confirmation prompt. Same recording rule as create-universe
$ rbx init create-place --universe-id 9876543299
  Place name (empty to keep the template's): Lobby
  Place name under [test.places]: (lobby) 
⚠ Create place 'Lobby' under universe 9876543299 and record it as [test].places.lobby? [y/N] y
Created place (id 444555666) in universe 9876543299
  name: Lobby
Added places.lobby to [test] in rbxplace.toml

Same skip rules as create-universe. If no env points at --universe-id, recording is skipped silently — unless you asked for it explicitly with --env/--place, in which case it’s an error. If several envs point at the same universe, pass --env to disambiguate.

rbx init rename-place

Rename a place by id.

FlagRequiredDescription
--placeYesPlace ID to rename, not a place name
--nameYesNew display name
--yes / -yNoSkip the confirmation prompt

--place means something different here than anywhere else in rbx. Everywhere else it is a key from [<env>.places]; on this one subcommand it shadows that with a raw place id, so --place lobby fails to parse rather than resolving. Pass the number.

rbx init rename-universe

Rename a universe by id. Roblox stores the display name on the root place; this resolves the universe’s root place and renames it.

FlagRequiredDescription
--universe-idYesUniverse ID
--nameYesNew display name
--yes / -yNoSkip the confirmation prompt
rbx init list-groups

List every group the authenticated user belongs to, with role and rank. Cookie required.

rbx init list-universes

List the universes owned by a group, published or not. No credential is required and a cookie adds nothing to the result: see the listings need no credential.

FlagRequiredDescription
--groupYesGroup ID
rbx init list-places

List every place inside a universe.

FlagRequiredDescription
--universe-idYesUniverse ID

Authentication

rbx init only uses cookie auth. Roblox does not expose group, universe, or place creation through Open Cloud, so there’s no API key option. The cookie is supplied via the global --cookie flag, the RBX_COOKIE env var, or a local Roblox Studio install.

That last one is opt-in: finding a signed-in Studio is not the same as being allowed to send its session. --auto-cookie is the standing yes, an interactive run is asked once, and a run with nowhere to ask — CI, a pipe, a cron job — declines and says so. --no-auto-cookie is the standing no.

This is the command with the least choice about it, so it is worth knowing what you are handing over: see docs/cookie.md for the resolution order in full, the stderr notice on auto-detection, and why the cookie never reaches disk.

CommandCookie required?
create-groupYes
create-universeYes
create-placeYes
rename-placeYes
rename-universeYes
list-groupsYes
list-universes --group <id>No. The listing answers in full without one
list-places --universe-id <id>No. The listing answers in full without one

The listings need no credential

list-universes and list-places are the two read commands here, and neither one is gated. Measured against a private universe that has never had a player, with no cookie, no API key and no session:

GET develop.roblox.com/v1/universes/{id}/places  → 200, every place, with names
GET games.roblox.com/v2/groups/{id}/gamesV2      → 200, every game

The second one is worth being precise about, because the query parameter looks like a permission and is not. Measured on one group, anonymously:

RequestGames returned
accessFilter=20
accessFilter=14
no accessFilter4

accessFilter=2 is the public filter. 1, and omitting it, are the unfiltered form, and unfiltered means unfiltered for anybody. rbx init sends 1, so it sees a group’s staging copies and unreleased projects, and so does anyone else who asks.

Roblox treats the existence, id and name of a universe or place as public. What stays behind a session is the content: develop.roblox.com/v1/places/{id} answers 404 anonymously, and whether a place is playable is not in these listings at all.

Two practical consequences. Do not rely on a universe being unlisted to keep a project quiet before announcing it. And rename test places before creating them under a real account: Roblox’s default place names embed the owner’s username, and those names come back to an anonymous caller.

How it works

  • Group creation hits groups.roblox.com/v1/groups/create (multipart upload with the icon).
  • Universe creation hits apis.roblox.com/universes/v1/universes/create with a templatePlaceId.
  • Place creation hits apis.roblox.com/universes/v1/user/universes/{id}/places.
  • Listing a group’s universes uses games.roblox.com/v2/groups/{id}/gamesV2?accessFilter=1. accessFilter=2 is the public-only filter; 1 is unfiltered, for any caller (see above).
  • Listing a universe’s places uses develop.roblox.com/v1/universes/{id}/places.

All write endpoints transparently handle CSRF: a 403 response with an x-csrf-token header caches the token and retries once. Listing endpoints retry on 429 / 5xx with exponential backoff (max 3 attempts).