Docs
Concepts
Environments
Concepts

Environments

Most projects need at least two deployments: one for testing and one for players. Lithos calls those environments. Each environment has its own state and its own Roblox assets, but they share one config file.

You select the environment at the command line:

lithos deploy --environment dev
lithos deploy --environment prod

The basic shape looks like this:

lithos.yml
environments:
  - label: dev
    targetNamePrefix: environmentLabel
  - label: prod
    targetAccess: public
 
target:
  experience:
    configuration:
      genre: building
    places:
      start:
        file: game.rbxlx
        configuration:
          name: My Experience

target describes the shared graph. Each entry under environments describes how one environment differs from it.

What you can override per environment

Each entry under environments accepts the following keys (all optional):

KeyEffect
labelIdentifier you pass to --environment. Required.
branchesRestrict this environment to specific Git branches. CI uses this.
targetAccessOverride visibility for this environment. private, friends, or public.
targetNamePrefixPrefix the experience and place names. See below.
targetOverridesArbitrary deep merge into target for this environment.

Naming with targetNamePrefix

The most common use is making dev visibly different from prod:

environments:
  - label: dev
    targetNamePrefix: environmentLabel    # "[DEV] My Experience"
  - label: prod
    targetNamePrefix: none                 # "My Experience"

environmentLabel prefixes names with [<LABEL>]. none means no prefix. You can also pass a custom string with { custom: "STAGING" }.

Visibility with targetAccess

environments:
  - label: dev
    targetAccess: private
  - label: prod
    targetAccess: public

private means only you can launch the experience. friends means you and your Roblox friends. public means everyone.

Arbitrary overrides with targetOverrides

For anything else, deep-merge the override into target:

environments:
  - label: dev
    targetOverrides:
      experience:
        configuration:
          maxPlayers: 10            # smaller dev servers
        places:
          start:
            configuration:
              maxPlayerCount: 10
  - label: prod
    targetOverrides:
      experience:
        places:
          start:
            configuration:
              maxPlayerCount: 50

This is a deep merge: lists replace wholesale, while maps and scalars merge by key.

State is per-environment

Each environment has its own slice of the state file. dev and prod do not share state.

Concretely, in the state file you'll see:

.lithos-state.yml
environments:
  dev: {  }
  prod: {  }

Branch gating in CI

If CI runs the same deploy command on every branch, use branches to restrict environments:

environments:
  - label: dev
    branches: [develop]
  - label: prod
    branches: [main]

Now lithos deploy --environment prod refuses to run anywhere except main.

Common patterns

Two-environment baseline

environments:
  - label: dev
    targetNamePrefix: environmentLabel
    targetAccess: private
  - label: prod
    targetAccess: public
    branches: [main]

Per-developer playgrounds

For each engineer, a personal environment:

environments:
  - label: alice
    targetNamePrefix: { custom: "[ALICE]" }
    branches: [feature/alice/*]
  - label: bob
    targetNamePrefix: { custom: "[BOB]" }
    branches: [feature/bob/*]

Combined with remote state, this lets developers iterate without stepping on each other.

⚠️

Per-developer environments create more Roblox assets. Clean up old ones with lithos destroy --environment <name>.

Next steps