ExoTheWicker (talk | contribs) No edit summary |
Fixed description for G-Resonite.UserSettings.Color.Tertiary |
||
(20 intermediate revisions by 12 users not shown) | |||
Line 1: | Line 1: | ||
= Overview = | == Overview == | ||
Cloud | Cloud variables are variables that persist across worlds. They work in a similar nature to [[Dynamic Variables|dynamic variables]] but instead of relying on parenting or the world hierarchy, they instead rely on paths and user/group ownership. You can think of them in a similar way to a settings or configuration file for your favorite game. Cloud variables are more lively than this though as they are synced between sessions, worlds and even your Resonite dash. | ||
For a quick-start guide to using cloud variables, see this tutorial: [[How_To_Use_Cloud_Variables|How To Use Cloud Variables]]. | |||
Cloud | |||
Cloud variables are comprised of two parts: | |||
* Definitions - Settings and configuration: owner, name, type, permissions, and default value. | * Definitions - Settings and configuration: owner, name, type, permissions, and default value. | ||
* Values - Actual values per user. | * Values - Actual values per user. | ||
== Cloud Variable Definition == | === Cloud Variable Definition === | ||
A cloud variable definition is made up of 4 Parts: | A cloud variable definition is made up of 4 Parts: | ||
* A path/name E.g. <code>AwesomeGadget.Version</code> or <code>PartyWorld.highQualityLights</code> | * A path/name E.g. <code>AwesomeGadget.Version</code> or <code>PartyWorld.highQualityLights</code> | ||
* [[#Supported Datatypes|Data type]] | * [[#Supported Datatypes|Data type]] | ||
* [[#Permissions|Permissions]] | * [[#Permissions|Permissions]] | ||
* A | * A default value | ||
** Default value would be an output of the [[To String (ProtoFlux Node)|To String]] node '''with spaces removed'''. An example would be [[Type:ColorX|ColorX]], which through To String results in: <code>[1;1.23;0;1;sRGB]</code> | |||
Definitions can also be registered against a user or a [[group]]. Registering a definition against a group has some benefits such as: | |||
Definitions can also be registered against a | * Higher [[#Limits|limits]] | ||
* Higher [[#Limits| | * Additional [[#Permissions|permission capabilities]] | ||
* Additional [[#Permissions| | |||
=== Default Values === | ==== Default Values ==== | ||
When [[#Creating Definitions|creating a definition]], you supply data and configuration in a series of stages with each command. Just in case you forget or omit a command here are the default values for various properties of a definition: | When [[#Creating Definitions|creating a definition]], you supply data and configuration in a series of stages with each command. Just in case you forget or omit a command here are the default values for various properties of a definition: | ||
* Read and | * Read and write permissions will default to '''variable_owner''' | ||
* List permissions will default to '''definition_owner''' | * List permissions will default to '''definition_owner''' | ||
* If no default value is specified, Resonite will return the default value for this data type as [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/default-values defined in C#]. | * If no default value is specified, Resonite will return the default value for this data type as [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/default-values defined in C#]. | ||
== Cloud Variable Values == | === Cloud Variable Values === | ||
Each | Each cloud variable definition can have multiple values, each value is tied to an individual Resonite user or group. A value just contains its value and has no details about the definition. You can think of it like a table with two columns an owner ID and the value. | ||
For example if a cloud variable definition was created with a data type of string and a name of "Favorite Fruit" then you can imagine its values looking like this: | |||
For example if a | |||
{| class="wikitable" | {| class="wikitable" | ||
!colspan="2"|Favorite Fruit | !colspan="2"|Favorite Fruit | ||
Line 55: | Line 54: | ||
|} | |} | ||
The last row shows a value that is specific for a group. This is only possible for cloud variables that belong to a group. | |||
The last row shows a value that is specific for a | |||
Variable owner IDs (user IDs or group IDs) with spaces need to be written with a hyphen. Example: Group "My Group" becomes "G-My-Group". Always double check your user ID and group IDs they can be completely different from a user's/group's displayed name. | |||
Variable | |||
== Using Cloud Variables == | === Using Cloud Variables === | ||
Before using | Before using cloud variables they must be created and registered. This is done by [[#List of Commands for Cloud Variables|sending commands]] of various types to [[Resonite Bot]]. These commands create and register a [[#Cloud Variable Definition|#cloud variable definition]] with Resonite. Once registered, cloud variable values can be read, written and manipulated against this definition using [[#ProtoFlux Nodes|ProtoFlux]] & [[#Components|components]]. | ||
= Usage Notes / Warnings = | == Usage Notes / Warnings == | ||
* Variable definitions are heavily cached and will typically take several minutes to update. It's recommended to set them up fully in advance. | |||
* Variable | |||
* Reads & writes are buffered, batched and cached and will take a bit to propagate. | * Reads & writes are buffered, batched and cached and will take a bit to propagate. | ||
* A current limitation of the cloud variable system is that they won’t be synchronized in real time across different sessions, unless they run on the same host/user. If you host multiple worlds/sessions on a single headless (or your own computer), the changes to the cloud variable will sync in real time within those sessions. | * A current limitation of the cloud variable system is that they won’t be synchronized in real time across different sessions, unless they run on the same host/user. If you host multiple worlds/sessions on a single headless (or your own computer), the changes to the cloud variable will sync in real time within those sessions. | ||
* If different users host the same world, changes in one world won’t be immediately reflected in another and will take a few minutes to refresh. The current plan is to add full real time synchronization in such cases by integrating SignalR into | * If different users host the same world, changes in one world won’t be immediately reflected in another and will take a few minutes to refresh. The current plan is to add full real time synchronization in such cases by integrating SignalR into the Resonite cloud infrastructure, which will help the cloud scale better for other things like active sessions or the messaging system as well. | ||
* Current limits, permissions, and other aspects are subject to change. | * Current limits, permissions, and other aspects are subject to change. | ||
* Changing data types is possible, however already stored values are not affected. | * Changing data types is possible, however already stored values are not affected. | ||
== Limits == | === Limits === | ||
Cloud variables do not take up any storage, but they do have limits. | Cloud variables do not take up any storage, but they do have limits. | ||
=== Definition limits === | ==== Definition limits ==== | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 90: | Line 86: | ||
|} | |} | ||
These limits only apply to created [[#Cloud Variable Definition|variable definitions]] and not to [[#Cloud Variable Values|values]] stored within them. For example a [[#Cloud Variable Definition|variable definition]] of "U-ProbablePrime.FavoriteColor" can still have an unlimited number of [[#Cloud Variable Values|values]] for it for each user's favorite color. | |||
These limits only apply to created [[#Cloud Variable Definition|variable definitions]] and not to [[#Cloud Variable Values|values]] stored within them. For example a [[#Cloud Variable Definition|variable definition]] of "U-ProbablePrime.FavoriteColor" can still have an unlimited number of [[#Cloud Variable Values|values]] for it for each user's | |||
=== Rate limits === | ==== Rate limits ==== | ||
When reading/writing from Cloud Variables the following limits are in place | When reading/writing from Cloud Variables the following limits are in place | ||
==== ProtoFlux ==== | ===== ProtoFlux ===== | ||
With [[ProtoFlux]], as the read or write is triggered by an impulse the read/write operation occurs immediately at the time the nodes receive the impulse. | With [[ProtoFlux]], as the read or write is triggered by an impulse the read/write operation occurs immediately at the time the nodes receive the impulse. | ||
Due to this the read/write process can be performed up to 30 times a minute. | |||
Due to this the | |||
==== Components ==== | When reading or writing data to a variable using ProtoFlux, the restrictions set in place for the defined variable exist for the ProtoFlux nodes. If the nodes exist in your local space, then the nodes can write/read to variables which only allow reading/writing inside a safe context. | ||
Cloud variable components operates on a schedule, periodically refreshing the values in both directions. These values are not that fast right now but with further enhancements to our SignalR{{Citation needed}} use | |||
===== Components ===== | |||
Cloud variable components operates on a schedule, periodically refreshing the values in both directions. These values are not that fast right now but with further enhancements to our SignalR{{Citation needed}} use, these values will update more promptly. | |||
Currently: | |||
* Reads occur every 5 minutes | * Reads occur every 5 minutes | ||
* Writes will be delayed(buffered) and sent every 30 seconds | * Writes will be delayed(buffered) and sent every 30 seconds | ||
** If the value on the component changes more frequently then the most recently set value at the time of the write will be sent to the cloud. | ** If the value on the component changes more frequently then the most recently set value at the time of the write will be sent to the cloud. | ||
== Update Rates == | === Update Rates === | ||
Please read the section above [[#Limits| | Please read the section above [[#Limits|limits]]. | ||
== Supported Datatypes == | === Supported Datatypes === | ||
When creating | When creating cloud variable definitions a valid type for them needs to be specified. The supported data types are listed below but generically any primitive data type is supported. Reference data types are not supported as references only work within one defined world/session. | ||
{| class="wikitable" | |||
* | |+Supported Cloud Variable Data Types | ||
* | !bool | ||
* | |bool2 | ||
** | |bool3 | ||
* | |bool4 | ||
** You can specify a maximum length for the string when setting the data type. | | | ||
| | |||
| | |||
|- | |||
!float | |||
|float2 | |||
|float3 | |||
|float4 | |||
|float2x2 | |||
|float3x3 | |||
|float4x4 | |||
|- | |||
!int | |||
|int2 | |||
|int3 | |||
|int4 | |||
| | |||
| | |||
| | |||
|- | |||
!long | |||
|long2 | |||
|long3 | |||
|long4 | |||
| | |||
| | |||
| | |||
|- | |||
!double | |||
|double2 | |||
|double3 | |||
|double4 | |||
|double2x2 | |||
|double3x3 | |||
|double4x4 | |||
|- | |||
!uint | |||
|uint2 | |||
|uint3 | |||
|uint4 | |||
| | |||
| | |||
| | |||
|- | |||
!ulong | |||
|ulong2 | |||
|ulong3 | |||
|ulong4 | |||
| | |||
| | |||
| | |||
|- | |||
!short | |||
|ushort | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!byte | |||
|sbyte | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!floatq | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!doubleq | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!color | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!datetime | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!timespan | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!decimal | |||
| | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!enum | |||
|* | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|- | |||
!string | |||
|* | |||
| | |||
| | |||
| | |||
| | |||
| | |||
|} | |||
* Enum: | |||
** You can now also use Enum types, the cloud variable definition must be set to string to sync properly. Once created you can use [[#ProtoFlux Nodes|ProtoFlux]] & [[#Components|components]] with their DataTypes set to the [[:Category:Enums|enum]] you wish to use. For example <code>CloudValueField<ShadowType></code>. | |||
* String: | |||
** You can specify a maximum length for the string when setting the data type. | |||
** The format is <code>string:<max_length></code>. | ** The format is <code>string:<max_length></code>. | ||
** By default, strings have a length of 256 characters. The maximum length is 8192. | ** By default, strings have a length of 256 characters. The maximum length is 8192. | ||
** Both | ** Both user and group variables are affected by these limits. | ||
'''More datatypes may be supported in the future.''' | '''More datatypes may be supported in the future.''' | ||
= Permissions = | == Permissions == | ||
Cloud variable permissions are composed of two parts: | Cloud variable permissions are composed of two parts: | ||
* Action | * Action permission - The type of action that a permission group can carry out. | ||
* Group/ | * Group/type permission - A group or classification of user. | ||
When reading and deciding on a permission set do remember that in '''most''' cases, each user has their own value for a cloud variable. | When reading and deciding on a permission set do remember that in '''most''' cases, each user has their own value for a cloud variable. | ||
As an example in the following command: <code>/setUserVarPerms test.color read,write,list anyone</code>. The actions are "read, write and list" and the permission type/group is "anyone". | As an example in the following command: <code>/setUserVarPerms test.color read,write,list anyone</code>. The actions are "read, write and list" and the permission type/group is "anyone". | ||
== Action Permission == | === Action Permission === | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 203: | Line 290: | ||
|} | |} | ||
You can also specify multiple permissions at once, separated by a comma so for example <code>/setUserVarPerms test.color read,write,list variable_owner</code> would set the read,write and list permissions on the <code>test.color</code> variable to <code>variable_owner</code>. | You can also specify multiple permissions at once, separated by a comma so for example <code>/setUserVarPerms test.color read,write,list variable_owner</code> would set the read,write and list permissions on the <code>test.color</code> variable to <code>variable_owner</code>. | ||
== Group/Type Permission == | === Group/Type Permission === | ||
=== Common Definition Permissions === | ==== Common Definition Permissions ==== | ||
These permissions, can be used with both | These permissions, can be used with both user and group owned definitions. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 222: | Line 307: | ||
| Anyone can read/write this variable's values. This is recommend for reading public variables but not recommend for writes as anyone can change anyone's value. | | Anyone can read/write this variable's values. This is recommend for reading public variables but not recommend for writes as anyone can change anyone's value. | ||
| Everywhere. | | Everywhere. | ||
| - Cannot be used with '''write''' permissions on User owned definitions.<br/>- Cannot be used with '''list''' permission on | | - Cannot be used with '''write''' permissions on User owned definitions.<br/>- Cannot be used with '''list''' permission on user owned definition. | ||
|- | |- | ||
| <code>definition_owner_only</code> | | <code>definition_owner_only</code> | ||
| Only the | | Only the user/group who defined the variable can read/write their own '''singular value'''. Useful for announcement/version control systems. | ||
| Userspace/safe contexts only. | | Userspace/safe contexts only. | ||
| None. | | None. | ||
|- | |- | ||
| <code>definition_owner_only_unsafe</code> | | <code>definition_owner_only_unsafe</code> | ||
| Only the | | Only the user/group who defined the variable can read/write their own '''singular value'''. Useful for announcement/version control systems. | ||
| Everywhere. | | Everywhere. | ||
| None. | | None. | ||
Line 245: | Line 330: | ||
|} | |} | ||
=== User Definition Permissions === | ==== User Definition Permissions ==== | ||
These permissions, can only be used with | These permissions, can only be used with user owned definitions. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 275: | Line 360: | ||
|} | |} | ||
=== Group Definition Permissions === | ==== Group Definition Permissions ==== | ||
These permissions, can only be used with | These permissions, can only be used with group owned definitions. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 297: | Line 381: | ||
|} | |} | ||
=== List Permissions === | ==== List Permissions ==== | ||
Due to the "list" permission having very limited valid permissions it is easier to list what permissions are allowed for list: | Due to the "list" permission having very limited valid permissions it is easier to list what permissions are allowed for list: | ||
* anyone - Only on | * anyone - Only on group based definitions. | ||
* definition_owner | * definition_owner | ||
* definition_owner_unsafe | * definition_owner_unsafe | ||
=== Safe Contexts === | ==== Safe Contexts ==== | ||
In most cases within Resonite, anyone can observe or even manipulate what you're doing. These are '''unsafe''' contexts. When in places such as | In most cases within Resonite, anyone can observe or even manipulate what you're doing. These are '''unsafe''' contexts. When in places such as userspace, where the Resonite dash is located, no one can see or modify what you're doing. This is a safe context. | ||
= | ==== Permission Matrix ==== | ||
This table shows you which permission can be applied to which [[#Action_Permission|action permission]], for user and group variables. | |||
= | {| class="wikitable" | ||
! | |||
! User Read | |||
! User Write | |||
! User List | |||
! Group Read | |||
! Group Write | |||
! Group List | |||
|- | |||
! anyone | |||
| Yes | |||
| No | |||
| Yes | |||
| Yes | |||
| Yes | |||
| Yes | |||
|- | |||
! definition_owner_only(_unsafe) | |||
| Yes | |||
| Yes | |||
| No | |||
| Yes | |||
| Yes | |||
| No | |||
|- | |||
! definition_owner(_unsafe) | |||
| Yes | |||
| No | |||
| Yes | |||
| Yes | |||
| Yes | |||
| Yes | |||
|- | |||
! variable_owner(_unsafe) | |||
| Yes | |||
| Yes | |||
| No | |||
| Yes | |||
| Yes | |||
| No | |||
|- | |||
! definition_owner_only_contacts(_unsafe) | |||
| Yes | |||
| Yes | |||
| No | |||
| No | |||
| No | |||
| No | |||
|- | |||
! variable_owner_only_contacts(_unsafe) | |||
| Yes | |||
| Yes | |||
| No | |||
| No | |||
| No | |||
| No | |||
|} | |||
=== User Definitions === | == Cloud Variable Commands == | ||
To create, update and modify cloud variables you will need to use commands. These commands can be sent to the [[Resonite Bot]] within Resonite, you'll be able to find it in your contacts section. | |||
Command arguments inside brackets <code>()</code> are optional. All other arguments are '''required'''. | |||
=== Creating Definitions === | |||
==== User Definitions ==== | |||
* <code>/createUserVar <path></code> - Creates a variable definition with the given path. | * <code>/createUserVar <path></code> - Creates a variable definition with the given path. | ||
* <code>/setUserVarType <path> <type></code> - Sets the variable definition's [[#Supported Datatypes| | * <code>/setUserVarType <path> <type></code> - Sets the variable definition's [[#Supported Datatypes|data type]]. | ||
* <code>/setUserVarDefaultValue <path> <value></code> - Sets the default value for a definition. | * <code>/setUserVarDefaultValue <path> <value></code> - Sets the default value for a definition. | ||
* <code>/setUserVarPerms <path> <action permission> <permission type></code> - Sets the [[#Permissions| | * <code>/setUserVarPerms <path> <action permission> <permission type></code> - Sets the [[#Permissions|permissions]] for a definition. | ||
There is also a command which can create a definition in one line: | |||
There is also a command which can create a definition in one | |||
=== Group Definitions === | * <code>/createUserVar <path> <type> <default value> <read perms> <write perms> <list perms></code> | ||
==== Group Definitions ==== | |||
* <code>/createGroupVar <group> <path></code> - Creates a variable definition with the given path. | * <code>/createGroupVar <group> <path></code> - Creates a variable definition with the given path. | ||
* <code>/setGroupVarType <group> <path> <type></code> - Sets the variable definition's [[#Supported Datatypes| | * <code>/setGroupVarType <group> <path> <type></code> - Sets the variable definition's [[#Supported Datatypes|data type]]. | ||
* <code>/setGroupVarDefaultValue <group> <path> <value></code> - Sets the default value for a definition. | * <code>/setGroupVarDefaultValue <group> <path> <value></code> - Sets the default value for a definition. | ||
* <code>/setGroupVarPerms <group> <path> <action permission> <permission type></code> - Sets the [[#Permissions| | * <code>/setGroupVarPerms <group> <path> <action permission> <permission type></code> - Sets the [[#Permissions|permissions]] for a definition. | ||
There is also a command which can create a definition in one line: | |||
There is also a command which can create a definition in one | |||
* <code> /createGroupVar <group> <path> <type> <default value> <read perms> <write perms> <list perms></code>. | |||
== | ==== Recommendations ==== | ||
Generally we recommend using the command which creates the entire definition in one go, this ensures you do not forget any steps or parts which can cause the variable to be unusable. | |||
=== User Values === | === Reading Values === | ||
For reading values using [[ProtoFlux]] / [[Components]], [[#Working_with_cloud_variables|see this later section]]. | |||
==== User Values ==== | |||
* <code>/getUserVar <path></code> - Gets the definition for a variable (type, perms, default value) | * <code>/getUserVar <path></code> - Gets the definition for a variable (type, perms, default value) | ||
* <code>/getUserVarValue <definition_owner> <path> <target user></code> - Gets a user's value for a definition. Example: <code>/getUserVarValue U-ProbablePrime testing.bool U-ProbablePrime</code> would get Prime's value for their variable testing.bool | * <code>/getUserVarValue <definition_owner> <path> <target user></code> - Gets a user's value for a definition. | ||
** Example: <code>/getUserVarValue U-ProbablePrime testing.bool U-ProbablePrime</code> would get Prime's value for their variable testing.bool | |||
* <code>/listUserVars (<user>)</code> - Lists variable definitions of a user (default: yours). Requires <code>list</code> permission. | * <code>/listUserVars (<user>)</code> - Lists variable definitions of a user (default: yours). Requires <code>list</code> permission. | ||
=== Group Values === | ==== Group Values ==== | ||
* <code>/getGroupVar <group> <path></code> - Gets the definition for a variable (type, perms, default value) | * <code>/getGroupVar <group> <path></code> - Gets the definition for a variable (type, perms, default value) | ||
* <code>/getGroupVarValue <group> <path> (<target user>)</code> - Gets a user's (default: yours) value for a definition. | * <code>/getGroupVarValue <group> <path> (<target user>)</code> - Gets a user's (default: yours) value for a definition. | ||
* <code>/listGroupVars <group></code> - Lists variable definitions of a group. Requires <code>list</code> permission. | * <code>/listGroupVars <group></code> - Lists variable definitions of a group. Requires <code>list</code> permission. | ||
== Writing Values == | === Writing Values === | ||
When setting/writing a value, ensure that your permissions are set correctly. | When setting/writing a value, ensure that your permissions are set correctly. | ||
For writing values using [[ProtoFlux]] / [[Components]] [[#Working_with_cloud_variables|see this later section]]. | For writing values using [[ProtoFlux]] / [[Components]] [[#Working_with_cloud_variables|see this later section]]. | ||
=== Writing Values with User owned Definitions === | ==== Writing Values with User owned Definitions ==== | ||
<code>/setUserVarValue (<user>) <path> (<target user>) <value></code> - Sets an individual user's value for a definition. | <code>/setUserVarValue (<user>) <path> (<target user>) <value></code> - Sets an individual user's value for a definition. | ||
For example: <code>/setUserVarValue U-ProbablePrime testing.bool U-Frooxius true</code> would set the value of <code>testing.bool</code> to true for Frooxius' value of ProbablePrime's definition. | For example: <code>/setUserVarValue U-ProbablePrime testing.bool U-Frooxius true</code> would set the value of <code>testing.bool</code> to true for Frooxius' value of ProbablePrime's definition. | ||
=== Writing Values with Group owned Definitions === | ==== Writing Values with Group owned Definitions ==== | ||
<code>/setGroupVarValue <group> <path> (<target user>) <value></code> - Sets an individual user's value for a definition. | <code>/setGroupVarValue <group> <path> (<target user>) <value></code> - Sets an individual user's value for a definition. | ||
For example: <code>/setUserVarValue G-Cheese testing.bool U-Frooxius true</code> would set the value of <code>testing.bool</code> to true for Frooxius' value of the group Cheese's definition. | |||
For example: <code>/setUserVarValue G-Cheese testing.bool U-Frooxius true</code> would set the value of <code>testing.bool</code> to true for Frooxius' value of the | |||
=== Setting Complex Values === | ==== Setting Complex Values ==== | ||
For complex values, you may struggle to know what to enter for this command. Here are some examples which may help: | For complex values, you may struggle to know what to enter for this command. Here are some examples which may help: | ||
* For complex strings, surround the value in | * For complex [[Type:String|strings]], surround the value in quotation marks <code>"</code>. E.g. "My Cool Value". | ||
* For float3 | * For [[Type:Float3|float3]] use <code>[1; 0; 1]</code> | ||
* For colors | * For [[Type:Color|colors]] use <code>[1; 0; 0; 1]</code> | ||
== Deleting Definitions == | === Deleting Definitions === | ||
You can delete definitions using the following commands: | You can delete definitions using the following commands: | ||
* <code>/deleteUserVar | * <code>/deleteUserVar <path></code> for user variables. | ||
* <code>/deleteGroupVar <group> <path></code> for | * <code>/deleteGroupVar <group> <path></code> for group variables. (Currently broken, see [https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/537 Issue #537]) | ||
This command deletes both the definition and '''all''' values linked to that definition. It also takes a while(around 30 minutes) for this command to fully execute as it needs to clear values, caches and other systems of the definition and values. | This command deletes both the definition and '''all''' values linked to that definition. It also takes a while(around 30 minutes) for this command to fully execute as it needs to clear values, caches and other systems of the definition and values. | ||
== Definition Examples == | |||
= | === User Boolean === | ||
Create a <code>User</code> variable of type <code>boolean</code> that anyone could read and the owner (each user for their own copy) could write from user and world space: | |||
<code>/createUserVar testing.enabled</code><br> | <code>/createUserVar testing.enabled</code><br> | ||
<code>/setUserVarType testing.enabled bool</code><br> | <code>/setUserVarType testing.enabled bool</code><br> | ||
Line 392: | Line 533: | ||
<code>/setUserVarPerms testing.enabled write variable_owner_unsafe</code> | <code>/setUserVarPerms testing.enabled write variable_owner_unsafe</code> | ||
=== User Color === | ==== User Color ==== | ||
Create a <code>User</code> variable of <code>color</code> type that only the owner could write from | Create a <code>User</code> variable of <code>color</code> type that only the owner could write from userspace and read from everywhere: | ||
<code>/createUserVar testing.myColor</code><br> | <code>/createUserVar testing.myColor</code><br> | ||
<code>/setUserVarType testing.myColor color</code><br> | <code>/setUserVarType testing.myColor color</code><br> | ||
Line 401: | Line 541: | ||
<code>/setUserVarPerms testing.myColor write variable_owner</code> | <code>/setUserVarPerms testing.myColor write variable_owner</code> | ||
=== Group Boolean === | ==== Group Boolean ==== | ||
Create a <code>Group</code> variable of <code>boolean</code> type that only the owner could read | Create a <code>Group</code> variable of <code>boolean</code> type that only the owner could read and write from everywhere: | ||
<code>/createGroupVar MyGroup testing.enabled</code><br> | <code>/createGroupVar MyGroup testing.enabled</code><br> | ||
<code>/setGroupVarType MyGroup testing.enabled bool</code><br> | <code>/setGroupVarType MyGroup testing.enabled bool</code><br> | ||
<code>/setGroupVarPerms MyGroup testing.enabled read,write | <code>/setGroupVarPerms MyGroup testing.enabled read,write variable_owner_unsafe</code> | ||
= Working with cloud variables = | == Working with cloud variables == | ||
== Components == | === Components === | ||
[[ActiveUserCloudField`1 (Component)]] - Like CloudValueField, but overrides OwnerId with local user. | |||
[[ActiveUserCloudField`1 (Component)]] - Like CloudValueField, but overrides OwnerId with | |||
[[ActiveUserCloudValueVariable`1 (Component)]] - Like CloudValueVariable, but overrides OwnerId with local user. | |||
[[ActiveUserCloudValueVariable`1 (Component)]] - Like CloudValueVariable, but overrides OwnerId with | |||
[[CloudValueField`1 (Component)]] - Uses target field to store the value, otherwise similar to CloudValueVariable. | [[CloudValueField`1 (Component)]] - Uses target field to store the value, otherwise similar to CloudValueVariable. | ||
[[CloudValueVariable`1 (Component)]] - Represents the cloud variable, can set OwnerId manually. | |||
[[CloudValueVariable`1 (Component)]] - Represents the | |||
[[CloudValueVariableDriver`1 (Component)]] - Drives target field with the value of the specified cloud variable. Overrides OwnerId with local user. | |||
[[CloudValueVariableDriver`1 (Component)]] - Drives target field with the value of the specified | |||
== ProtoFlux Nodes == | === ProtoFlux Nodes === | ||
[[Write Cloud Variable`1 (ProtoFlux Node)]] - On impulse, writes the specified cloud variable for specified owner. | |||
[[Write Cloud Variable`1 (ProtoFlux Node)]] - On impulse, writes the specified | |||
[[Read Cloud Variable`1 (ProtoFlux Node)]] - On impulse, reads the specified cloud variable for specified owner. | |||
[[Read Cloud Variable`1 (ProtoFlux Node)]] - On impulse, reads the specified | |||
== Headless Sessions and Auto-Startup World Options == | === Headless Sessions and Auto-Startup World Options === | ||
Cloud variables can be used with [[Headless Client| | Cloud variables can be used with [[Headless Client|headless server configuration files]] and [[Startup Config File|start-up configuration files]] in a number of ways: | ||
* Configuring roles in a session. | * Configuring roles in a session. | ||
* Allowing/ | * Allowing/denying users from joining/accessing sessions. | ||
* Provide custom denial messages for why a user is denied access to your sessions. | * Provide custom denial messages for why a user is denied access to your sessions. | ||
These options are '''NOT available in the UI within Resonite''' and require advanced setup from outside of the game. | These options are '''NOT available in the UI within Resonite''' and require advanced setup from outside of the game. | ||
We recommend using a g'''roup variable''' for these setups, due to the permission requirements. You can potentially get away with an appropriately configured user variable but group variables will give you the most control. | |||
We recommend using a ''' | |||
To set these up, you need to add the described parameters below, to your configuration JSON files. | To set these up, you need to add the described parameters below, to your configuration JSON files. | ||
=== Roles === | ==== Roles ==== | ||
To configure roles using cloud variables, add a <code>roleCloudVariable</code> parameter to your world start-up/headless session configuration. | To configure roles using cloud variables, add a <code>roleCloudVariable</code> parameter to your world start-up/headless session configuration. Its value should be the full path of the cloud variable you want to use. The session will then use the cloud variable to determine which role the user has. | ||
When doing this you need to keep in mind a few things: | When doing this you need to keep in mind a few things: | ||
# The variable data type must be a string. | # The variable data type must be a string. | ||
Line 460: | Line 589: | ||
# If no value is set for the variable and a user, the other methods for determining the role will be used. | # If no value is set for the variable and a user, the other methods for determining the role will be used. | ||
An example setup would be: | An example setup would be: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 484: | Line 612: | ||
|} | |} | ||
With the corresponding JSON property which needs to be added being: <code>"roleCloudVariable": "G-Cheese.awesomeHeadless.userRoles"</code> | |||
With the corresponding JSON property which needs to be added being: | |||
<code> | |||
"roleCloudVariable": "G-Cheese.awesomeHeadless.userRoles" | |||
</code> | |||
=== Access === | ==== Access ==== | ||
There are a few variables and settings which can control access to headless sessions. | There are a few variables and settings which can control access to headless sessions. | ||
==== Allowing User's Access ==== | ===== Allowing User's Access ===== | ||
To configure access to a headless session, using cloud variables add a <code>allowUserCloudVariable</code> parameter to your world start-up/headless session configuration. | To configure access to a headless session, using cloud variables add a <code>allowUserCloudVariable</code> parameter to your world start-up/headless session configuration. Its value should be the full path of the cloud variable you want to use. The session will then use the cloud variable to provide access to the session. | ||
This option take '''precedence over all other checks''', including regular session settings such as max users and visibility. | This option take '''precedence over all other checks''', including regular session settings such as max users and visibility. | ||
When doing this you need to keep in mind a few things: | When doing this you need to keep in mind a few things: | ||
# The variable data type must be a bool. | # The variable data type must be a bool. | ||
Line 509: | Line 631: | ||
# Users can join even if the session is private. They will need a link to the session though. | # Users can join even if the session is private. They will need a link to the session though. | ||
An example setup would be: | An example setup would be: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 527: | Line 648: | ||
|} | |} | ||
With the corresponding JSON property which needs to be added being: <code>"allowUserCloudVariable": "G-Cheese.awesomeHeadless.accessControl"</code> | |||
With the corresponding JSON property which needs to be added being: | |||
<code> | |||
"allowUserCloudVariable": "G-Cheese.awesomeHeadless.accessControl" | |||
</code> | |||
==== Denying User's Access ==== | ===== Denying User's Access ===== | ||
In a similar manner to <code>allowUserCloudVariable</code>, you can use <code>denyUserCloudVariable</code> to deny a user access to your world start-up/headless session configuration. Follow the guide above for allowing access but use <code>denyUserCloudVariable</code> instead. When a value for a user is <code>true</code>, they will be denied access. | In a similar manner to <code>allowUserCloudVariable</code>, you can use <code>denyUserCloudVariable</code> to deny a user access to your world start-up/headless session configuration. Follow the guide above for allowing access but use <code>denyUserCloudVariable</code> instead. When a value for a user is <code>true</code>, they will be denied access. | ||
When true, this option take '''precedence over all other checks''', including regular session settings such as max users and visibility. | |||
When true, this option take '''precedence over all other checks''', including regular session settings such as | |||
An example setup would be: | An example setup would be: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 561: | Line 676: | ||
|} | |} | ||
With the corresponding JSON property which needs to be added being: <code>"denyUserCloudVariable": "G-Cheese.awesomeHeadless.userAccess"</code> | |||
With the corresponding JSON property which needs to be added being: | |||
<code> | |||
"denyUserCloudVariable": "G-Cheese.awesomeHeadless.userAccess" | |||
</code> | |||
==== Joining Control ==== | ===== Joining Control ===== | ||
In addition to the above options, you also have the option to use <code>requiredUserJoinCloudVariable</code>. When this option is added to your world start-up/headless session configuration, its value for a user will be checked when they join. If it is true then the user will be allowed to join. If it is false then they will not be allowed to join. | In addition to the above options, you also have the option to use <code>requiredUserJoinCloudVariable</code>. When this option is added to your world start-up/headless session configuration, its value for a user will be checked when they join. If it is true then the user will be allowed to join. If it is false then they will not be allowed to join. | ||
Do note that this option does '''NOT''' take precedence over other session checks. Even if this value is set to true, if the session is full (at its maximum user count) the user will not be allowed in. | |||
Do note that this option does '''NOT''' take precedence over other session checks. Even if this value is set to true, if the session is full( | |||
An example setup would be: | An example setup would be: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 591: | Line 700: | ||
|} | |} | ||
With the corresponding JSON property which needs to be added being: <code>"requiredUserJoinCloudVariable": "G-Cheese.awesomeHeadless.userAccess"</code> | |||
With the corresponding JSON property which needs to be added being: | |||
<code> | |||
"requiredUserJoinCloudVariable": "G-Cheese.awesomeHeadless.userAccess" | |||
</code> | |||
===== Deny Messages ===== | ====== Deny Messages ====== | ||
'''When using <code>requiredUserJoinCloudVariable</code>''' with your headless, you can use a second configuration element in the configuration file; <code>requiredUserJoinCloudVariableDenyMessage</code>. | |||
'''When using <code>requiredUserJoinCloudVariable</code>''' | |||
This allows you to specify a '''single''' message that is sent to users who are restricted from joining due to their value being absent or false, in the variable defined in <code>requiredUserJoinCloudVariable</code>. | This allows you to specify a '''single''' message that is sent to users who are restricted from joining due to their value being absent or false, in the variable defined in <code>requiredUserJoinCloudVariable</code>. | ||
You must use, <code>requiredUserJoinCloudVariable</code> for this to work as they are linked together. These systems cannot be combined with other cloud variables or other access controls. | |||
You must use, <code>requiredUserJoinCloudVariable</code> for this to work as they are linked together. These systems cannot be combined with other | |||
These options may be confusing at first but it is useful for controlling session access, '''without''' bypassing regular checks such as visibility and max user counts. We often see it uses for things like events which require registration such as conventions. | |||
These options may be confusing at first but it is useful for controlling session access, '''without''' bypassing regular checks such as visibility and | |||
= Additional Reading = | == Additional Reading == | ||
{{stub}} | {{stub}} | ||
= Default Cloud Variables = <!--T:107--> | = Default Cloud Variables = <!--T:107--> | ||
Resonite has a few | Resonite has a few cloud variables that are used internally or automatically set up for a user. These are as follows: | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 624: | Line 724: | ||
|- | |- | ||
| <code>G-Resonite.Favorites.AudioPlayer</code> | | <code>G-Resonite.Favorites.AudioPlayer</code> | ||
| Contains a Uri for the user's favorite [[Audio Player]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Audio Player|audio player]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.AudioStreamController</code> | | <code>G-Resonite.Favorites.AudioStreamController</code> | ||
| Contains a Uri for the user's favorite [[Audio Stream Controller]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Audio Stream Controller|audio stream controller]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.Avatar</code> | | <code>G-Resonite.Favorites.Avatar</code> | ||
| Contains a Uri for the user's favorite [[ | | Contains a [[Type:Uri|Uri]] for the user's favorite [[avatar]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.Camera</code> | | <code>G-Resonite.Favorites.Camera</code> | ||
| Contains a Uri for the user's favorite [[ | | Contains a [[Type:Uri|Uri]] for the user's favorite [[camera]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.Home</code> | | <code>G-Resonite.Favorites.Home</code> | ||
| Contains a Uri for the user's favorite [[ | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Homes#Cloud_Home|cloud home]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.Keyboard</code> | | <code>G-Resonite.Favorites.Keyboard</code> | ||
| Contains a Uri for the user's favorite [[Resonite Keyboard| | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Resonite Keyboard|keyboard]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.NamePlate</code> | | <code>G-Resonite.Favorites.NamePlate</code> | ||
| Contains a Uri for the user's favorite [[ | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Nameplate|nameplate]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.NoticeDisplay</code> | | <code>G-Resonite.Favorites.NoticeDisplay</code> | ||
| Contains a Uri for the user's favorite [[Notice Display]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Notice Display|notice display]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.ProgressBar</code> | | <code>G-Resonite.Favorites.ProgressBar</code> | ||
| Contains a Uri for the user's favorite [[Progress Bar]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Progress Bar|progress bar]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.TextDisplay</code> | | <code>G-Resonite.Favorites.TextDisplay</code> | ||
| Contains a Uri for the user's favorite [[Text Display]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Text Display|text display]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.UrlDisplay</code> | | <code>G-Resonite.Favorites.UrlDisplay</code> | ||
| Contains a Uri for the user's favorite [[Url Display]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Url Display|Url display]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.VideoPlayer</code> | | <code>G-Resonite.Favorites.VideoPlayer</code> | ||
| Contains a Uri for the user's favorite [[Video Player]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[Video Player|video player]]. | ||
|- | |- | ||
| <code>G-Resonite.Favorites.WorldLoadingIndicator</code> | | <code>G-Resonite.Favorites.WorldLoadingIndicator</code> | ||
| Contains a Uri for the user's favorite [[World Loading Indicator]]. | | Contains a [[Type:Uri|Uri]] for the user's favorite [[World Loading Indicator|world loading indicator]]. | ||
|- | |||
| <code>G-Resonite.CloudHome.FeaturedPanel.BackgroundImage</code> | |||
| Contains a [[Type:Uri|Uri]] for the image on the background of the featured cloudhome panel(s) | |||
|- | |||
| <code>G-Resonite.CloudHome.AvatarPanel.AvatarWorldList</code> | |||
| Contains a [[Type:String|string]] that is a list for the different featured avatar worlds in the cloudhome panel | |||
|- | |||
| <code>G-Resonite.CloudHome.FeaturedPanel.WorldCredit</code> | |||
| Contains a [[Type:String|string]] for the credits of the featured world in the cloudhome panel | |||
|- | |||
| <code>G-Resonite.CloudHome.FeaturedPanel.WorldLink</code> | |||
| Contains a [[Type:Uri|uri]] for the world link of the featured world in the cloud home | |||
|- | |||
| <code>G-Resonite.CloudHome.FeaturedPanel.WorldName</code> | |||
| Contains a [[Type:String|string]] for the world name of the featured world in the cloud home | |||
|- | |||
| <code>G-Resonite.CloudHome.HasVisited</code> | |||
| Contains a [[Type:Bool|bool]] for if the user has ever visited the cloud home | |||
|- | |||
| <code>G-Resonite.UserSettings.Accessibility.ReducedMotion</code> | |||
| Contains a [[Type:Bool|bool]] for if the user has reduced motion on. | |||
|- | |||
| <code>G-Resonite.UserSettings.Color.Enabled</code> | |||
| Contains a [[Type:Bool|bool]] to determine whether to use the user's primary, secondary, and tertiary color cloud variables | |||
|- | |||
| <code>G-Resonite.UserSettings.Color.Primary</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's primary color. Usually used on the head and hands. | |||
|- | |||
| <code>G-Resonite.UserSettings.Color.Secondary</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's secondary color. Usually used on the head and hands. | |||
|- | |||
| <code>G-Resonite.UserSettings.Color.Tertiary</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's tertiary color. Usually used on the head and hands. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.LastOpenedTab</code> | |||
| Contains a [[Type:Int|int]] for the last tab the user opened in their color picker. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.Swatch1</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's color picker for slot 1. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.Swatch2</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's color picker for slot 2. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.Swatch3</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's color picker for slot 3. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.Swatch4</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's color picker for slot 4. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.Swatch5</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's color picker for slot 5. | |||
|- | |||
| <code>G-Resonite.UserSettings.ColorPicker.Swatch6</code> | |||
| Contains a [[Type:ColorX|ColorX]] for the user's color picker for slot 6. | |||
|- | |||
| <code>G-Resonite.cloud_home.current</code> | |||
| Contains a [[Type:Uri|Uri]] previously used for the user's favorite [[Homes#Cloud_Home|cloud home]] in a legacy infrastructure. This was superseded by <code>G-Resonite.Favorites.Home</code>. | |||
|- | |||
| <code>G-Resonite.common_avatar.current</code> | |||
| Contains a [[Type:Uri|Uri]] previously used for the user's favorite [[avatar]] in a legacy infrastructure. This was superseded by <code>G-Resonite.Favorites.Avatar</code>. | |||
|- | |||
| <code>G-Resonite.interactive_camera.current</code> | |||
| Contains a [[Type:Uri|Uri]] previously used for the user's favorite [[camera]] in a legacy infrastructure. This was superseded by <code>G-Resonite.Favorites.Camera</code>. | |||
|- | |||
| <code>G-Resonite.virtual_keyboard.current</code> | |||
| Contains a [[Type:Uri|Uri]] previously used for the user's favorite [[Resonite Keyboard|keyboard]] in a legacy infrastructure. This was superseded by <code>G-Resonite.Favorites.Keyboard</code>. | |||
|- | |||
| <code>G-Resonite.CustomUserColor</code> | |||
| Contains a [[Type:ColorX|ColorX]] previously used for the user's primary color such as for the default head and hands avatar. This was superseded by <code>G-Resonite.UserSettings.Color.Primary</code>. | |||
| | |||
|- | |||
| <code>G-Resonite.test.byte</code> | |||
| Contains a [[Type:Byte|byte]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.color</code> | |||
| Contains a [[Type:Color|color]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.definitionOwnerUnsafe</code> | |||
| Contains a [[Type:String|string]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.definitionOwnerWriteOnly</code> | |||
| Contains a [[Type:Uri|Uri]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.enum</code> | |||
| Contains a [[Type:String|string]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.float</code> | |||
| Contains a [[Type:Float|float]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.float2</code> | |||
| Contains a [[Type:Float2|float2]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.float3</code> | |||
| Contains a [[Type:Float3|float3]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.float3x3</code> | |||
| Contains a [[Type:Float3x3|float3x3]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.float4</code> | |||
| Contains a [[Type:Float4|float4]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.int</code> | |||
| Contains a [[Type:Int|int]] for users to test with. | |||
|- | |||
| <code>G-Resonite.test.longString</code> | |||
| Contains a [[Type:String|string]] that is 8192 characters long for users to test with. | |||
|- | |||
| <code>G-Resonite.test.ownerOnlyVariable</code> | |||
| Contains a [[Type:String|string]] that has the permission OwnerOnly for users to test with. | |||
|- | |||
| <code>G-Resonite.test.ownerWriteOnly</code> | |||
| Contains a [[Type:String|string]] that has the permission OwnerWriteOnly for users to test with. | |||
|- | |||
| <code>G-Resonite.test.publicVariable</code> | |||
| Contains a [[Type:String|string]] that has the permissions set to public for users to test with. | |||
|- | |||
| <code>G-Resonite.test.shortString</code> | |||
| Contains a [[Type:String|string]] that is 8 characters for users to test with. | |||
|- | |||
| <code>G-Resonite.test.string</code> | |||
| Contains a [[Type:String|string]] that is the default length for users to test with. | |||
|} | |} | ||
{{stub}} | {{stub}} |
Latest revision as of 13:44, 1 November 2024
Overview
Cloud variables are variables that persist across worlds. They work in a similar nature to dynamic variables but instead of relying on parenting or the world hierarchy, they instead rely on paths and user/group ownership. You can think of them in a similar way to a settings or configuration file for your favorite game. Cloud variables are more lively than this though as they are synced between sessions, worlds and even your Resonite dash.
For a quick-start guide to using cloud variables, see this tutorial: How To Use Cloud Variables.
Cloud variables are comprised of two parts:
- Definitions - Settings and configuration: owner, name, type, permissions, and default value.
- Values - Actual values per user.
Cloud Variable Definition
A cloud variable definition is made up of 4 Parts:
- A path/name E.g.
AwesomeGadget.Version
orPartyWorld.highQualityLights
- Data type
- Permissions
- A default value
Definitions can also be registered against a user or a group. Registering a definition against a group has some benefits such as:
- Higher limits
- Additional permission capabilities
Default Values
When creating a definition, you supply data and configuration in a series of stages with each command. Just in case you forget or omit a command here are the default values for various properties of a definition:
- Read and write permissions will default to variable_owner
- List permissions will default to definition_owner
- If no default value is specified, Resonite will return the default value for this data type as defined in C#.
Cloud Variable Values
Each cloud variable definition can have multiple values, each value is tied to an individual Resonite user or group. A value just contains its value and has no details about the definition. You can think of it like a table with two columns an owner ID and the value.
For example if a cloud variable definition was created with a data type of string and a name of "Favorite Fruit" then you can imagine its values looking like this:
Favorite Fruit | |
---|---|
Variable Owner ID | Value |
U-Frooxius | Strawberry |
U-Nexulan | Orange |
U-Shifty | Pineapple |
U-ProbablePrime | Blueberry |
G-MyGroup | Banana |
The last row shows a value that is specific for a group. This is only possible for cloud variables that belong to a group.
Variable owner IDs (user IDs or group IDs) with spaces need to be written with a hyphen. Example: Group "My Group" becomes "G-My-Group". Always double check your user ID and group IDs they can be completely different from a user's/group's displayed name.
Using Cloud Variables
Before using cloud variables they must be created and registered. This is done by sending commands of various types to Resonite Bot. These commands create and register a #cloud variable definition with Resonite. Once registered, cloud variable values can be read, written and manipulated against this definition using ProtoFlux & components.
Usage Notes / Warnings
- Variable definitions are heavily cached and will typically take several minutes to update. It's recommended to set them up fully in advance.
- Reads & writes are buffered, batched and cached and will take a bit to propagate.
- A current limitation of the cloud variable system is that they won’t be synchronized in real time across different sessions, unless they run on the same host/user. If you host multiple worlds/sessions on a single headless (or your own computer), the changes to the cloud variable will sync in real time within those sessions.
- If different users host the same world, changes in one world won’t be immediately reflected in another and will take a few minutes to refresh. The current plan is to add full real time synchronization in such cases by integrating SignalR into the Resonite cloud infrastructure, which will help the cloud scale better for other things like active sessions or the messaging system as well.
- Current limits, permissions, and other aspects are subject to change.
- Changing data types is possible, however already stored values are not affected.
Limits
Cloud variables do not take up any storage, but they do have limits.
Definition limits
Limit Type | Limit |
---|---|
Users | 256 |
Groups | 8192 |
These limits only apply to created variable definitions and not to values stored within them. For example a variable definition of "U-ProbablePrime.FavoriteColor" can still have an unlimited number of values for it for each user's favorite color.
Rate limits
When reading/writing from Cloud Variables the following limits are in place
ProtoFlux
With ProtoFlux, as the read or write is triggered by an impulse the read/write operation occurs immediately at the time the nodes receive the impulse.
Due to this the read/write process can be performed up to 30 times a minute.
When reading or writing data to a variable using ProtoFlux, the restrictions set in place for the defined variable exist for the ProtoFlux nodes. If the nodes exist in your local space, then the nodes can write/read to variables which only allow reading/writing inside a safe context.
Components
Cloud variable components operates on a schedule, periodically refreshing the values in both directions. These values are not that fast right now but with further enhancements to our SignalR[Citation needed] use, these values will update more promptly.
Currently:
- Reads occur every 5 minutes
- Writes will be delayed(buffered) and sent every 30 seconds
- If the value on the component changes more frequently then the most recently set value at the time of the write will be sent to the cloud.
Update Rates
Please read the section above limits.
Supported Datatypes
When creating cloud variable definitions a valid type for them needs to be specified. The supported data types are listed below but generically any primitive data type is supported. Reference data types are not supported as references only work within one defined world/session.
bool | bool2 | bool3 | bool4 | |||
---|---|---|---|---|---|---|
float | float2 | float3 | float4 | float2x2 | float3x3 | float4x4 |
int | int2 | int3 | int4 | |||
long | long2 | long3 | long4 | |||
double | double2 | double3 | double4 | double2x2 | double3x3 | double4x4 |
uint | uint2 | uint3 | uint4 | |||
ulong | ulong2 | ulong3 | ulong4 | |||
short | ushort | |||||
byte | sbyte | |||||
floatq | ||||||
doubleq | ||||||
color | ||||||
datetime | ||||||
timespan | ||||||
decimal | ||||||
enum | * | |||||
string | * |
- Enum:
- You can now also use Enum types, the cloud variable definition must be set to string to sync properly. Once created you can use ProtoFlux & components with their DataTypes set to the enum you wish to use. For example
CloudValueField<ShadowType>
.
- You can now also use Enum types, the cloud variable definition must be set to string to sync properly. Once created you can use ProtoFlux & components with their DataTypes set to the enum you wish to use. For example
- String:
- You can specify a maximum length for the string when setting the data type.
- The format is
string:<max_length>
. - By default, strings have a length of 256 characters. The maximum length is 8192.
- Both user and group variables are affected by these limits.
More datatypes may be supported in the future.
Permissions
Cloud variable permissions are composed of two parts:
- Action permission - The type of action that a permission group can carry out.
- Group/type permission - A group or classification of user.
When reading and deciding on a permission set do remember that in most cases, each user has their own value for a cloud variable.
As an example in the following command: /setUserVarPerms test.color read,write,list anyone
. The actions are "read, write and list" and the permission type/group is "anyone".
Action Permission
Action Permission | Description |
---|---|
read
|
Grants the ability to read values of a cloud variable. |
write
|
Grants the ability to write values of a cloud variable. |
list
|
Grants the ability to list all values or a variable. |
all
|
Grants all above permissions at once. |
You can also specify multiple permissions at once, separated by a comma so for example /setUserVarPerms test.color read,write,list variable_owner
would set the read,write and list permissions on the test.color
variable to variable_owner
.
Group/Type Permission
Common Definition Permissions
These permissions, can be used with both user and group owned definitions.
Permission Type | Description | Locations | Limitations |
---|---|---|---|
anyone
|
Anyone can read/write this variable's values. This is recommend for reading public variables but not recommend for writes as anyone can change anyone's value. | Everywhere. | - Cannot be used with write permissions on User owned definitions. - Cannot be used with list permission on user owned definition. |
definition_owner_only
|
Only the user/group who defined the variable can read/write their own singular value. Useful for announcement/version control systems. | Userspace/safe contexts only. | None. |
definition_owner_only_unsafe
|
Only the user/group who defined the variable can read/write their own singular value. Useful for announcement/version control systems. | Everywhere. | None. |
variable_owner
|
Only the user who owns the variable value can write/read their own value. In this case the definition owner cannot read/write values for other people. | Userspace/safe contexts only. | Cannot be used for list permissions |
variable_owner_unsafe
|
Only the user who owns the variable value can write/read their own value. In this case the definition owner cannot read/write values for other people. | Everywhere. | Cannot be used for list permissions |
User Definition Permissions
These permissions, can only be used with user owned definitions.
Permission Type | Description | Locations | Limitations |
---|---|---|---|
definition_owner_only_contacts
|
TODO | Userspace/safe contexts only. | Cannot be used for list permissions |
definition_owner_only_contacts_unsafe
|
TODO | Everywhere. | Cannot be used for list permissions |
variable_owner_only_contacts
|
TODO | Userspace/safe contexts only. | Cannot be used for list permissions |
variable_owner_only_contacts_unsafe
|
TODO | Everywhere | Cannot be used for list permissions |
Group Definition Permissions
These permissions, can only be used with group owned definitions.
Permission Type | Description | Locations | Limitations |
---|---|---|---|
definition_owner
|
Only the group who defined the variable can read/write it. | Userspace/safe contexts only. | None. |
definition_owner_unsafe
|
Only the group who defined the variable can read/write it. | Everywhere. | None. |
List Permissions
Due to the "list" permission having very limited valid permissions it is easier to list what permissions are allowed for list:
- anyone - Only on group based definitions.
- definition_owner
- definition_owner_unsafe
Safe Contexts
In most cases within Resonite, anyone can observe or even manipulate what you're doing. These are unsafe contexts. When in places such as userspace, where the Resonite dash is located, no one can see or modify what you're doing. This is a safe context.
Permission Matrix
This table shows you which permission can be applied to which action permission, for user and group variables.
User Read | User Write | User List | Group Read | Group Write | Group List | |
---|---|---|---|---|---|---|
anyone | Yes | No | Yes | Yes | Yes | Yes |
definition_owner_only(_unsafe) | Yes | Yes | No | Yes | Yes | No |
definition_owner(_unsafe) | Yes | No | Yes | Yes | Yes | Yes |
variable_owner(_unsafe) | Yes | Yes | No | Yes | Yes | No |
definition_owner_only_contacts(_unsafe) | Yes | Yes | No | No | No | No |
variable_owner_only_contacts(_unsafe) | Yes | Yes | No | No | No | No |
Cloud Variable Commands
To create, update and modify cloud variables you will need to use commands. These commands can be sent to the Resonite Bot within Resonite, you'll be able to find it in your contacts section.
Command arguments inside brackets ()
are optional. All other arguments are required.
Creating Definitions
User Definitions
/createUserVar <path>
- Creates a variable definition with the given path./setUserVarType <path> <type>
- Sets the variable definition's data type./setUserVarDefaultValue <path> <value>
- Sets the default value for a definition./setUserVarPerms <path> <action permission> <permission type>
- Sets the permissions for a definition.
There is also a command which can create a definition in one line:
/createUserVar <path> <type> <default value> <read perms> <write perms> <list perms>
Group Definitions
/createGroupVar <group> <path>
- Creates a variable definition with the given path./setGroupVarType <group> <path> <type>
- Sets the variable definition's data type./setGroupVarDefaultValue <group> <path> <value>
- Sets the default value for a definition./setGroupVarPerms <group> <path> <action permission> <permission type>
- Sets the permissions for a definition.
There is also a command which can create a definition in one line:
/createGroupVar <group> <path> <type> <default value> <read perms> <write perms> <list perms>
.
Recommendations
Generally we recommend using the command which creates the entire definition in one go, this ensures you do not forget any steps or parts which can cause the variable to be unusable.
Reading Values
For reading values using ProtoFlux / Components, see this later section.
User Values
/getUserVar <path>
- Gets the definition for a variable (type, perms, default value)/getUserVarValue <definition_owner> <path> <target user>
- Gets a user's value for a definition.- Example:
/getUserVarValue U-ProbablePrime testing.bool U-ProbablePrime
would get Prime's value for their variable testing.bool
- Example:
/listUserVars (<user>)
- Lists variable definitions of a user (default: yours). Requireslist
permission.
Group Values
/getGroupVar <group> <path>
- Gets the definition for a variable (type, perms, default value)/getGroupVarValue <group> <path> (<target user>)
- Gets a user's (default: yours) value for a definition./listGroupVars <group>
- Lists variable definitions of a group. Requireslist
permission.
Writing Values
When setting/writing a value, ensure that your permissions are set correctly.
For writing values using ProtoFlux / Components see this later section.
Writing Values with User owned Definitions
/setUserVarValue (<user>) <path> (<target user>) <value>
- Sets an individual user's value for a definition.
For example: /setUserVarValue U-ProbablePrime testing.bool U-Frooxius true
would set the value of testing.bool
to true for Frooxius' value of ProbablePrime's definition.
Writing Values with Group owned Definitions
/setGroupVarValue <group> <path> (<target user>) <value>
- Sets an individual user's value for a definition.
For example: /setUserVarValue G-Cheese testing.bool U-Frooxius true
would set the value of testing.bool
to true for Frooxius' value of the group Cheese's definition.
Setting Complex Values
For complex values, you may struggle to know what to enter for this command. Here are some examples which may help:
- For complex strings, surround the value in quotation marks
"
. E.g. "My Cool Value". - For float3 use
[1; 0; 1]
- For colors use
[1; 0; 0; 1]
Deleting Definitions
You can delete definitions using the following commands:
/deleteUserVar <path>
for user variables./deleteGroupVar <group> <path>
for group variables. (Currently broken, see Issue #537)
This command deletes both the definition and all values linked to that definition. It also takes a while(around 30 minutes) for this command to fully execute as it needs to clear values, caches and other systems of the definition and values.
Definition Examples
User Boolean
Create a User
variable of type boolean
that anyone could read and the owner (each user for their own copy) could write from user and world space:
/createUserVar testing.enabled
/setUserVarType testing.enabled bool
/setUserVarPerms testing.enabled read anyone
/setUserVarPerms testing.enabled write variable_owner_unsafe
User Color
Create a User
variable of color
type that only the owner could write from userspace and read from everywhere:
/createUserVar testing.myColor
/setUserVarType testing.myColor color
/setUserVarPerms testing.myColor read variable_owner_unsafe
/setUserVarPerms testing.myColor write variable_owner
Group Boolean
Create a Group
variable of boolean
type that only the owner could read and write from everywhere:
/createGroupVar MyGroup testing.enabled
/setGroupVarType MyGroup testing.enabled bool
/setGroupVarPerms MyGroup testing.enabled read,write variable_owner_unsafe
Working with cloud variables
Components
ActiveUserCloudField`1 (Component) - Like CloudValueField, but overrides OwnerId with local user.
ActiveUserCloudValueVariable`1 (Component) - Like CloudValueVariable, but overrides OwnerId with local user.
CloudValueField`1 (Component) - Uses target field to store the value, otherwise similar to CloudValueVariable.
CloudValueVariable`1 (Component) - Represents the cloud variable, can set OwnerId manually.
CloudValueVariableDriver`1 (Component) - Drives target field with the value of the specified cloud variable. Overrides OwnerId with local user.
ProtoFlux Nodes
Write Cloud Variable`1 (ProtoFlux Node) - On impulse, writes the specified cloud variable for specified owner.
Read Cloud Variable`1 (ProtoFlux Node) - On impulse, reads the specified cloud variable for specified owner.
Headless Sessions and Auto-Startup World Options
Cloud variables can be used with headless server configuration files and start-up configuration files in a number of ways:
- Configuring roles in a session.
- Allowing/denying users from joining/accessing sessions.
- Provide custom denial messages for why a user is denied access to your sessions.
These options are NOT available in the UI within Resonite and require advanced setup from outside of the game.
We recommend using a group variable for these setups, due to the permission requirements. You can potentially get away with an appropriately configured user variable but group variables will give you the most control.
To set these up, you need to add the described parameters below, to your configuration JSON files.
Roles
To configure roles using cloud variables, add a roleCloudVariable
parameter to your world start-up/headless session configuration. Its value should be the full path of the cloud variable you want to use. The session will then use the cloud variable to determine which role the user has.
When doing this you need to keep in mind a few things:
- The variable data type must be a string.
- It is strongly recommended that you use the
definition_owner
permission group for this variable. Other permission groups may allow users to override their roles. - If no value is set for the variable and a user, the other methods for determining the role will be used.
An example setup would be:
G-Cheese.awesomeHeadless.userRoles | |
---|---|
Variable Owner ID | Value |
U-Frooxius | Admin |
U-Nexulan | Builder |
U-Shifty | Guest |
U-ProbablePrime | Spectator |
U-Vegasx | Spectator |
With the corresponding JSON property which needs to be added being: "roleCloudVariable": "G-Cheese.awesomeHeadless.userRoles"
Access
There are a few variables and settings which can control access to headless sessions.
Allowing User's Access
To configure access to a headless session, using cloud variables add a allowUserCloudVariable
parameter to your world start-up/headless session configuration. Its value should be the full path of the cloud variable you want to use. The session will then use the cloud variable to provide access to the session.
This option take precedence over all other checks, including regular session settings such as max users and visibility.
When doing this you need to keep in mind a few things:
- The variable data type must be a bool.
- If it is set to true, the user will be allowed to join the session.
- If it is set to false, or a value is not present, the other methods for determining access will be used.
- If its value is true, the server will allow access to the user.
- This is the equivalent of sending an invite to the user.
- Users can join regardless of the MaxUsers setting.
- Users can join even if the session is private. They will need a link to the session though.
An example setup would be:
G-Cheese.awesomeHeadless.userAccess | |
---|---|
Variable Owner ID | Value |
U-Frooxius | true |
U-Nexulan | true |
U-BadGuy | false |
With the corresponding JSON property which needs to be added being: "allowUserCloudVariable": "G-Cheese.awesomeHeadless.accessControl"
Denying User's Access
In a similar manner to allowUserCloudVariable
, you can use denyUserCloudVariable
to deny a user access to your world start-up/headless session configuration. Follow the guide above for allowing access but use denyUserCloudVariable
instead. When a value for a user is true
, they will be denied access.
When true, this option take precedence over all other checks, including regular session settings such as max users and visibility.
An example setup would be:
G-Cheese.awesomeHeadless.userAccess | ||
---|---|---|
Variable Owner ID | Value | Description |
U-Frooxius | false | Allowed Access |
U-Nexulan | false | Allowed Access |
U-BadGuy | true | Denied Access |
With the corresponding JSON property which needs to be added being: "denyUserCloudVariable": "G-Cheese.awesomeHeadless.userAccess"
Joining Control
In addition to the above options, you also have the option to use requiredUserJoinCloudVariable
. When this option is added to your world start-up/headless session configuration, its value for a user will be checked when they join. If it is true then the user will be allowed to join. If it is false then they will not be allowed to join.
Do note that this option does NOT take precedence over other session checks. Even if this value is set to true, if the session is full (at its maximum user count) the user will not be allowed in.
An example setup would be:
G-Cheese.awesomeHeadless.userAccess | |
---|---|
Variable Owner ID | Value |
U-Frooxius | true |
U-Nexulan | true |
U-BadGuy | false |
With the corresponding JSON property which needs to be added being: "requiredUserJoinCloudVariable": "G-Cheese.awesomeHeadless.userAccess"
Deny Messages
When using requiredUserJoinCloudVariable
with your headless, you can use a second configuration element in the configuration file; requiredUserJoinCloudVariableDenyMessage
.
This allows you to specify a single message that is sent to users who are restricted from joining due to their value being absent or false, in the variable defined in requiredUserJoinCloudVariable
.
You must use, requiredUserJoinCloudVariable
for this to work as they are linked together. These systems cannot be combined with other cloud variables or other access controls.
These options may be confusing at first but it is useful for controlling session access, without bypassing regular checks such as visibility and max user counts. We often see it uses for things like events which require registration such as conventions.
Additional Reading
This article or section is a Stub. You can help the Resonite Wiki by expanding it.
Default Cloud Variables
Resonite has a few cloud variables that are used internally or automatically set up for a user. These are as follows:
Variable | Description | |
---|---|---|
G-Resonite.Favorites.AudioPlayer
|
Contains a Uri for the user's favorite audio player. | |
G-Resonite.Favorites.AudioStreamController
|
Contains a Uri for the user's favorite audio stream controller. | |
G-Resonite.Favorites.Avatar
|
Contains a Uri for the user's favorite avatar. | |
G-Resonite.Favorites.Camera
|
Contains a Uri for the user's favorite camera. | |
G-Resonite.Favorites.Home
|
Contains a Uri for the user's favorite cloud home. | |
G-Resonite.Favorites.Keyboard
|
Contains a Uri for the user's favorite keyboard. | |
G-Resonite.Favorites.NamePlate
|
Contains a Uri for the user's favorite nameplate. | |
G-Resonite.Favorites.NoticeDisplay
|
Contains a Uri for the user's favorite notice display. | |
G-Resonite.Favorites.ProgressBar
|
Contains a Uri for the user's favorite progress bar. | |
G-Resonite.Favorites.TextDisplay
|
Contains a Uri for the user's favorite text display. | |
G-Resonite.Favorites.UrlDisplay
|
Contains a Uri for the user's favorite Url display. | |
G-Resonite.Favorites.VideoPlayer
|
Contains a Uri for the user's favorite video player. | |
G-Resonite.Favorites.WorldLoadingIndicator
|
Contains a Uri for the user's favorite world loading indicator. | |
G-Resonite.CloudHome.FeaturedPanel.BackgroundImage
|
Contains a Uri for the image on the background of the featured cloudhome panel(s) | |
G-Resonite.CloudHome.AvatarPanel.AvatarWorldList
|
Contains a string that is a list for the different featured avatar worlds in the cloudhome panel | |
G-Resonite.CloudHome.FeaturedPanel.WorldCredit
|
Contains a string for the credits of the featured world in the cloudhome panel | |
G-Resonite.CloudHome.FeaturedPanel.WorldLink
|
Contains a uri for the world link of the featured world in the cloud home | |
G-Resonite.CloudHome.FeaturedPanel.WorldName
|
Contains a string for the world name of the featured world in the cloud home | |
G-Resonite.CloudHome.HasVisited
|
Contains a bool for if the user has ever visited the cloud home | |
G-Resonite.UserSettings.Accessibility.ReducedMotion
|
Contains a bool for if the user has reduced motion on. | |
G-Resonite.UserSettings.Color.Enabled
|
Contains a bool to determine whether to use the user's primary, secondary, and tertiary color cloud variables | |
G-Resonite.UserSettings.Color.Primary
|
Contains a ColorX for the user's primary color. Usually used on the head and hands. | |
G-Resonite.UserSettings.Color.Secondary
|
Contains a ColorX for the user's secondary color. Usually used on the head and hands. | |
G-Resonite.UserSettings.Color.Tertiary
|
Contains a ColorX for the user's tertiary color. Usually used on the head and hands. | |
G-Resonite.UserSettings.ColorPicker.LastOpenedTab
|
Contains a int for the last tab the user opened in their color picker. | |
G-Resonite.UserSettings.ColorPicker.Swatch1
|
Contains a ColorX for the user's color picker for slot 1. | |
G-Resonite.UserSettings.ColorPicker.Swatch2
|
Contains a ColorX for the user's color picker for slot 2. | |
G-Resonite.UserSettings.ColorPicker.Swatch3
|
Contains a ColorX for the user's color picker for slot 3. | |
G-Resonite.UserSettings.ColorPicker.Swatch4
|
Contains a ColorX for the user's color picker for slot 4. | |
G-Resonite.UserSettings.ColorPicker.Swatch5
|
Contains a ColorX for the user's color picker for slot 5. | |
G-Resonite.UserSettings.ColorPicker.Swatch6
|
Contains a ColorX for the user's color picker for slot 6. | |
G-Resonite.cloud_home.current
|
Contains a Uri previously used for the user's favorite cloud home in a legacy infrastructure. This was superseded by G-Resonite.Favorites.Home .
| |
G-Resonite.common_avatar.current
|
Contains a Uri previously used for the user's favorite avatar in a legacy infrastructure. This was superseded by G-Resonite.Favorites.Avatar .
| |
G-Resonite.interactive_camera.current
|
Contains a Uri previously used for the user's favorite camera in a legacy infrastructure. This was superseded by G-Resonite.Favorites.Camera .
| |
G-Resonite.virtual_keyboard.current
|
Contains a Uri previously used for the user's favorite keyboard in a legacy infrastructure. This was superseded by G-Resonite.Favorites.Keyboard .
| |
G-Resonite.CustomUserColor
|
Contains a ColorX previously used for the user's primary color such as for the default head and hands avatar. This was superseded by G-Resonite.UserSettings.Color.Primary .
|
|
G-Resonite.test.byte
|
Contains a byte for users to test with. | |
G-Resonite.test.color
|
Contains a color for users to test with. | |
G-Resonite.test.definitionOwnerUnsafe
|
Contains a string for users to test with. | |
G-Resonite.test.definitionOwnerWriteOnly
|
Contains a Uri for users to test with. | |
G-Resonite.test.enum
|
Contains a string for users to test with. | |
G-Resonite.test.float
|
Contains a float for users to test with. | |
G-Resonite.test.float2
|
Contains a float2 for users to test with. | |
G-Resonite.test.float3
|
Contains a float3 for users to test with. | |
G-Resonite.test.float3x3
|
Contains a float3x3 for users to test with. | |
G-Resonite.test.float4
|
Contains a float4 for users to test with. | |
G-Resonite.test.int
|
Contains a int for users to test with. | |
G-Resonite.test.longString
|
Contains a string that is 8192 characters long for users to test with. | |
G-Resonite.test.ownerOnlyVariable
|
Contains a string that has the permission OwnerOnly for users to test with. | |
G-Resonite.test.ownerWriteOnly
|
Contains a string that has the permission OwnerWriteOnly for users to test with. | |
G-Resonite.test.publicVariable
|
Contains a string that has the permissions set to public for users to test with. | |
G-Resonite.test.shortString
|
Contains a string that is 8 characters for users to test with. | |
G-Resonite.test.string
|
Contains a string that is the default length for users to test with. |
This article or section is a Stub. You can help the Resonite Wiki by expanding it.