State and reconciliation
The state file is how Lithos remembers what it created. Without it, every deploy would have to re-discover every asset on Roblox, and there is no generic API for "list everything I own." With it, a deploy is a fast, predictable diff.
What is in the state file
A versioned YAML document keyed by environment. In the current v7 format, each environment stores two things:
current— the resource graph from the latest successful deploy or undo.deployments— a short history of checkpoints, results, and journals used for recovery andlithos undo.
Concretely:
version: 7
environments:
dev:
current:
- id: experience_singleton
inputs:
experience:
groupId: ~
outputs:
experience:
assetId: 3296599132
startPlaceId: 8667346609
- id: placeFile_start
inputs:
placeFile:
filePath: game.rbxlx
fileHash: 0c3a…
outputs:
placeFile:
version: 2
deployments:
- id: deploy-1736370930123
kind: deploy
status: succeeded
startedAt: 2026-01-08T01:15:30Z
finishedAt: 2026-01-08T01:15:42Z
baseline: []
desired:
- id: experience_singleton
resulting:
- id: experience_singleton
journal:
- resourceId: experience_singleton
action: create
status: applied
summary: Applied create for experience_singletonYou will rarely edit this by hand. The important parts are:
fileHashis how Lithos decides if a place file changed. Editinggame.rbxlxflips the hash, which produces an update. Touching the file without changing bytes does not.outputs.assetIdis the canonical link between a Lithos resource and a real Roblox asset. Lose it and the next deploy will re-create the asset from scratch.deploymentsis the recovery trail. It records recent deploys and undos, including the baseline snapshot and a short journal of what changed.
Where the state file lives
There are two options. They store the same data; only the backend differs.
Local (the default)
.lithos-state.yml is written next to your lithos.yml. Commit it.
Local state is fine when:
- You are the only developer.
- You only deploy from one machine.
- You are happy to merge state-file conflicts in Git when collaborators deploy from different branches.
Remote (S3, R2)
State is written to a single object in S3 or Cloudflare R2. Multiple machines see the same state automatically.
Remote state is the right answer when:
- More than one person, machine, or CI job deploys.
- You want CI to be the only thing that deploys to
prod, with developers deploying todevfrom their laptops. - You don't want a state file in source control.
Setup: Remote state guide.
Lithos does not support "no state." Pick local or remote.
Drift, in one paragraph
Drift is when the live Roblox state and the Lithos state file disagree. Most often, someone changed something through Creator Hub or Studio. The live reconciliation pass detects drift for the resource types Lithos can verify cheaply and updates state before planning the diff. See The resource graph.
You can run the reconciliation pass on its own without applying anything:
lithos diff --liveThat prints the same diff a deploy would, against the reconciled state,
without prompting and without writing.
Legacy mantle.yml / .mantle-state.yml
Lithos reads both Mantle and Lithos config and state files. New writes use the Lithos names. See Migrating from Mantle.
Common state-file questions
Q: My teammate and I both deployed dev and now Git cannot merge the
state file.
Use remote state, or make one machine the only writer for that environment.
Q: Can I delete the state file and start over?
Yes, but Lithos will think nothing exists and try to re-create every
resource. The old assets stay on Roblox, orphaned, and you lose the rollback
checkpoints recorded in deployments. Better: use
lithos import to attach an existing experience to a fresh state file
(experimental).
Q: Can I edit the state file by hand? Only as a last resort, and always with a backup. Wrong asset IDs can make Lithos create duplicates, fail auth, or point at the wrong Roblox asset.