Conflicts & locking
Skein never silently overwrites another person's work. Here is exactly what happens for every kind of change.
The model: ownership through leases
- Editing an object requires its lock. With Lock objects when I select them (default), selecting an object requests its lock.
- The server grants each lock to exactly one connection (an atomic Redis script; tested with simultaneous requests from many clients).
- Everyone sees locks: in the Scene view (a thick outline with Editing: Chris) and in the Skein window.
- Locks are leases (20 s), renewed by the editor's heartbeat every 5 s. If the editor disappears, the lease expires.
- An unclean disconnect keeps the slot and locks for a 15 s resume window (enough for Wi-Fi blips and Unity script reloads). After that, locks are released (
reason: disconnected). - Leaving a session releases locks immediately. Deselecting releases them after 1.5 s.
- Owners and admins can force-unlock from the Skein window (audited as
lock.force_release).
What happens per change type
| Change | Strategy | If someone else holds the lock |
|---|---|---|
| Move / rotate / scale | Lock required. Live previews while dragging; final value committed once, sequenced. | Your edit is reverted to the shared state; you're told who is editing. |
| Rename, enable/disable | Lock required. | Reverted. |
| Component fields (supported types) | Lock required; whole compound values are sent (e.g. the full Color). |
Reverted to the previous value. |
| Re-parent / reorder | Lock required on the moved object (not the new parent). | Change not shared; you're told. |
| Create (empty / primitive / prefab) | New n: id — no conflict possible. Creator gets the lock. |
— |
| Delete | Lock required. | Not shared; you're told to press Undo to restore it locally. |
| Camera, selection, activity | Ephemeral, last-write-wins per person. | — |
| Snapshot restore | Admin-only; everyone is asked to reload the scene. | — |
If an object isn't locked by anyone when you edit it (auto-lock disabled, or you edited without selecting), the editor requests the lock right away: granted → your change is sent; denied → your change is reverted.
While you're offline
- The UI shows Reconnecting… and how many changes are waiting to sync — they are not shown as shared.
- Edits are queued locally (up to 1000 mutations).
- On reconnect within the resume window you still own your locks: queued edits are delivered (duplicates are ignored server-side).
- After the window: the editor re-requests the locks first. Edits to objects someone else took in the meantime are reverted, and you're told.
Merging scene files: "Share scene with team"
Live sync keeps everyone's open scene identical, but Unity scene files can still differ: objects created during a session get different local file ids on each machine when saved, which would conflict in Git/Plastic.
Before committing, anyone with edit access clicks Share scene with team in the Skein window. Their saved scene file is uploaded and every editor in the session loads that exact file (automatically if it has no unsaved edits there, otherwise after a prompt). Every machine now has a byte-identical scene, so:
- objects created during the session get the same identity everywhere from then on;
- any one person can commit the scene and the others simply pull — no merge conflicts.
Why not last-write-wins or merging?
Two transforms can't be meaningfully merged, and last-write-wins means someone's work disappears without them noticing. Explicit ownership is predictable and visible. Snapshots cover the "we need to go back" case.