Ownership and permissions

Ownership is a paradigm we use in Normcore to enforce who is allowed to make changes to a model at any given time. It can be used on any model, and you may have encountered it while working with some of our built-in components, like RealtimeTransform. The value of a model’s owner can be set to either: a particular client ID, to denote the respective client as the owner; or -1, to denote that it has no owner.

How is ownership enforced

Models are stored in our datastore in a nested hierarchy, with the root of each networked prefab being represented by a RealtimeViewModel - a model that represents RealtimeView. That model contains all models for the RealtimeComponents on that given prefab. Ownership for a model cascades down this hierarchy - if a root RealtimeViewModel is owned by a particular client, that client is also considered the owner of any models nested beneath it.

A model can be owned by either a particular client or can have no owner. If a model is owned by a particular client, only that client is able to make changes to properties within it. If a model has no owner, and all of its parent models in the hierarchy have no owner, anybody can make changes to it at any time.

RealtimeTransform relies extensively on this concept of ownership. By default, if you add a RealtimeTransform to an object, and try to move it while connected to a room, it’ll immediately jump back to its initial position. This is because RealtimeTransform determines if it should apply changes to the transform based on the current owner. If it’s owned by the local client, then the model is updated to reflect the current transform position, rotation, and scale. Otherwise, the transform is updated to reflect the model’s position, rotation, and scale.

If you’re wanting to move an object with a RealtimeTransform on it, you’ll need to request ownership of the RealtimeTransform model first. You can do so by calling the RequestOwnership() method on the RealtimeTransform instance for the object. Then, if the object isn’t already owned by another client, your local client will become the new owner, and you are now free to modify the transform. Similarly, to relinquish ownership of an object owned by the local client, you can call the ClearOwnership() method on RealtimeTransform.