Lifecycle and saves
A calm experience is also a well-behaved one. It starts quickly, rests when nobody is looking, never loses a save and never writes one twice.
The handshake
- The platform loads your entry with
#zc_parent=…&zc_instance=…in the hash. connect()sendszc.readywith your id and version every 250 milliseconds until it is answered.- The platform checks your id, version and protocol against the approval and answers
zc.connectedwith the context and a private port, or rejects you. - From then on, every call goes through that port. If your page reloads, the session ends and the visitor starts again from the platform.
Be ready within 15 seconds
Call loading.start() first and loading.ready() as soon as the visitor can begin. Load heavy assets after that. If you are not ready after 15 seconds, the platform tells the visitor something is wrong. If you cannot start, call loading.fail(message).
Lifecycle commands
| Command | What to do |
|---|---|
pause | Stop sound, animation and input. Report paused. |
resume | Continue where the visitor left off. Report running. |
visibility | Sent once after connecting and then on every change. When visible is false, rest as if paused. |
dispose | Stop timers and let the SDK flush your saves. The frame is removed as soon as you answer, or after one second at most. |
Report the session, don't count time
Call session.report({state, mode}) whenever the state changes, and repeat it every few seconds while it runs. The platform measures time from these reports on the server. It stops counting when it hears paused, or when it hears nothing for 12 seconds.
Revisions protect every save
Each save has a revision that grows by one with every write. You pass the revision you last saw. If someone else wrote in the meantime, such as another tab or another device, the write fails with CONFLICT instead of overwriting their progress.
Retry with the same request id
A TIMEOUT or INTERNAL error doesn't mean the write failed, only that you don't know. Send the same data again with the same requestId. The server returns the first result instead of writing twice. Reusing an id with different data fails with IDEMPOTENCY_CONFLICT.
Let autosave set the pace
storage.createAutosave(save) calls your function at most once per interval: 10 seconds by default, anywhere from 10 seconds to 5 minutes. Call schedule() whenever something changes. On pause, hide and dispose, and before a run is finished or the visitor leaves, the SDK flushes right away. After three failed attempts it reports SAVE_UNCONFIRMED through onError. Return false from your function if newer changes still need a save.
When the channel closes
onDisconnect fires once. Keep what the visitor sees, stop saving and say gently that they can reopen the experience to continue. Never try to reconnect on your own.