Live Objects: one thing, several views
The spatial object metaphor
Think of a file as a physical thing, and its representations as windows onto that thing. Opening the same shared object in a second program should feel like looking through another portal, not secretly making a new copy that will drift out of sync. The view can differ—a thumbnail, text editor, scene inspector or read-only monitor—while referring to the same underlying identity and accepted state.
This is the Human Interface goal of Live Objects. A view is not the object, a pathname is not a permission, and two matching names do not necessarily identify the same thing. The responsible authority owns its identity, generation, accepted revisions and rights. An application chooses a suitable projection and presents it through an appropriate view.
Live, copied and transient
| Attachment | What changes affect | When to use it |
|---|---|---|
| Live editable view | The shared authority, after validation and commit | Work on the same document/resource from multiple permitted views. |
| Live read-only projection | The view follows permitted shared changes; it cannot author them | Preview, monitor or inspect another application's output. |
| Detached transient copy | Your independent in-memory copy | Experiment without changing the source; lifetime follows the app/session. |
| Permanent copy | A separately saved object with its own identity/path | Make a template, fork, export or independent version. |
| Running-world projection | Selected authoritative simulation state at a declared epoch/tick | Observe a game or server, rather than its authored scene file. |
Live is the intended default for capable views unless you explicitly request a copy or disable it. The new common LiveView path works for authorized schema/JSON model projections. It provides live/read-only/transient attachments, actual permanent JSON copies, Lua methods and typed GUI options. Existing rich-text, asset and full 3D-world views still need their specific adapters; this is not automatic adoption by every widget or native file format.
Disabling Live behavior should detach or reopen a clearly identified snapshot. A transient copy is not saved merely because the original is. A permanent copy needs an authorized destination and a successful file receipt. “Copy beside original” must resolve a collision-safe name and return the actual identity/path/name to the caller; an arbitrary client path string must not bypass storage permissions. For the common JSON-model route, copy_adjacent implements collision-safe creation and returns the actual name/path. It exports canonical model JSON; preserving a native scene, image or rich-text format needs its domain exporter and the host’s file/resource registration.
What an edit means
A view can show a speculative draft immediately. The edit is submitted to the authority under current permissions, with a base revision or operation identity. Accepted effects update other authorized views. A stale edit may conflict or need rebasing; a disconnected client may need a fresh baseline. Resource generation fencing stops an old operation from changing a newly created replacement object.
Plain-text collaboration uses sequence/causal operations; general scalar and structural data can use revision-checked transactions. Rich text, embedded media and custom assets need their specific adapters. A generic JSON transaction is not a universal merge of arbitrary concurrent changes.
Presence, selection hints and field leases help people coordinate but do not make another user's uncommitted draft canonical. A field lease is advisory unless the owning operation actually enforces it. A read-only spectator still needs disclosure authorization. Revocation stops future access; it cannot retract content already delivered.
Scene file or running world?
Consider a 3D scene open in Game Creator. A Live Asset connection to the scene's authored data should show committed changes to objects, components and asset references. Entering Play may create transient simulation state: a player moves, a projectile exists for half a second, a physics body falls. Those changes should not be written into the authored scene merely because another app has its file open.
A connection to a world-sync-enabled backend is a different request. It follows a declared live-world projection with epoch/tick, entity identities, pinned assets, baselines/deltas and interest policy. Its view may render a running world without owning simulation authority. A new epoch or missing baseline requires reset/resynchronization, not applying patches to whatever scene happens to be visible.
This boundary is represented by the current world-session contract, projection adapter and developer host. Displaying world state does not prove deterministic replay or complete continuation of Lua stacks, physics solver state, timers or procedural history. A source-of-truth authored scene and a source-of-truth running server can legitimately show different things.
Use in Lua and Rust
For schema-bound models, the host uses platinum-lua to bind a model into Lua. Ordinary property access consults that shared model; assignments use its validation/revision route. The host supplies the model and permission gate. A script does not acquire another application's data simply by constructing its ID.
-- `settings` is supplied by the trusted host as a schema-bound model.
-- This is ordinary Lua property syntax, not a new global SDK lookup API.
local previous = settings.title
settings.title = "My workspace"Keep the host's binding object and its snapshot/commit helpers when detached tables are needed. JSON null is distinct from Lua nil. Reacquire nested proxies after a commit that can reorder/change their paths; these proxies are revision-fenced positional paths, not stable collaborative array identities. Mixed/sparse/cyclic tables and invalid schema values can be rejected.
Rust uses binding::BoundModel, live authority operations and the appropriate application adapter. Registered managed roots can connect to platinum-sync/state-worker recovery. Local, pending, ready, off and unavailable are different states. Default values remain speculative until a provider has established the authoritative state; an unavailable restore must not be silently interpreted as a new blank document.
The text/asset adapters expose staged previews and authoritative commits. Host publication after a durable transaction requires the correct publication witness/authorization path; a public receipt DTO or cached snapshot alone is not permission to disclose a resource. Refer to the module guide and reference for the exact exported types in the chosen build.
Configuring and living with Live Objects
Use read-only sharing for inspection, copy for experimentation, and live editing for shared work. Show which mode the view uses and which authority owns it. Shared state is helpful, but it also means a bad edit can propagate. Undo must be operation-aware where other people are editing; replacing an entire shared object with your old snapshot can erase their work.
Large objects and remote providers consume memory, CPU and bandwidth. A thumbnail should request the necessary projection, not a full game world. Keep subscription/copy budgets, cancellation and disconnection behavior visible. A unified interface must allow new view types to register projections without duplicating storage or bypassing grants.
Applications should distinguish source revision, speculative preview, accepted revision and saved/exported revision. A Live Object acknowledgment is not automatically a saved disk file. Copy/export needs separate permission and its own successful completion. Closing a view releases its subscriptions and advisory leases; permanent copies and other participants' authorized views can remain.
Common LiveView in Lua, GUI data and native code
The trusted host starts from an existing authorized BoundModel and creates a LiveViewAuthority with a resource/generation/projection descriptor. It issues an opaque LiveViewHandle and retains a revocation control. Resource IDs or Lua strings cannot mint those handles. Real broker permission/expiry changes must be forwarded by the installed host.
The handle attaches live by default. A read-only attachment follows changes without edit authority. A transient attachment requires copy/export rights and uses an independent schema-bound model at revision zero. A permanent copy also needs an opaque host-issued LiveCopyDirectory, or a LiveSourceFileLocation for an adjacent copy. Creation never replaces an existing file and returns the actual filename/path plus source provenance. The portable copy backend assumes a trusted directory and does not contain a host attacker swapping paths; hostile-filesystem brokers need their platform handle backend.
The actual Lua binder is platinum_lua::live_view::bind_live_view. Its host-supplied userdata supports:
local data, revision, source = view:snapshot()
data.title = "A shared edit"
view:commit(revision, data)
local experiment = view:copy_transient()
local saved_copy = view:copy_to(export_directory, "Scene-model.json")
print(saved_copy.path, saved_copy.name)
-- view:copy_adjacent(source_location) chooses a collision-safe adjacent name.The host supplies view, export_directory and source_location; the sample does not authorize paths. Snapshot returns detached data, an exact decimal revision string and provenance. A copy already disclosed remains independent after source revocation; future live reads/edits/exports are denied.
The core XML model validates these LiveView options:
<ui width="640" height="480">
<panel id="1" live-mode="live" live-projection="model-json"/>
<panel id="2" live="false" live-projection="model-json"/>
<panel id="3" live-mode="permanent-copy" live-copy-destination="exports"/>
</ui>live="false" requests a transient copy. Other explicit modes are live, read-only, transient-copy and permanent-copy. The exports alias is inert until a host resolves it to its directory capability. LiveJsonView::from_element uses these options for a real revision-aware JSON editor; copy_from_definition completes a permanent-copy request. Adding the attributes to an arbitrary old widget does not automatically attach a resource or install a new renderer.
game::live_view_adapter::WorldSummaryLiveView bridges an already accepted WorldProjectionStore to the same Lua/GUI route. It exposes a small read-only summary: session/world identity, epoch/tick, sequence, entity count and consistency. Old-epoch handles are fenced. It does not copy the entire world or replace GameWorldView's entity renderer. The existing authored model and running-world model stay separate.
See the implementation guide, core reference, Lua reference and GUI reference. Remaining adoption work includes rich projections, native-format exporters, saved-copy resource registration and actual cross-process/broker lifecycle integration. Tests distinguish the usable common model route from these wider goals.