1. Neos VR
  2. News

Neos VR News

2021.5.4.471 - UI Aligned Camera for desktop, expanded cloud variables abilities

Hello everyone, sorry this build took a bit longer to make, but here's a bunch of new goodies! The new desktop mode now has UI Camera mode! Simply hold Ctrl and Left click on some UI to align the view with it! Doing Ctrl+Left Click in empty space will reset. While active you can also use Ctrl+Right Mouse to pan or Ctrl+Scroll to adjust zoom. This should make interacting with UI's and LogiX much easier in desktop! There's still some glitches and things to be implemented though, so you'll probably run into a few issues.

The cloud variable system has also been expanded with new permissions for more flexibility (notably adding a lot more to User defined variables) and a bunch of bugfixes and tweaks too! You can now also use them for access & role control on headless!

There's some other goodies, like ability to bake non-driven blendshapes to optimize your meshes, new +/i LogiX node and some more. Model importing robustness has been improved too to fix cases where import gets stuck on some models or fixing cases where users who haven't played in a while would run into Neos crashing on startup. The Contacts+ issue should also be fixed for good now, sorry it took so long!

[h2]New Features:[/h2]
- Added UI Camera mode to the new desktop mode, which aligns the view with the plane of the UI and frees the cursor for easy interaction
-- To activate, hold the Ctrl key and click with the Left Mouse Button on the UI you want to focus. You can repeat this to align to another UI element
-- To deactivate, hold the Ctrl key and click with Left Mouse Button into empty space (alternatively press F5 to toggle camera mode)
-- While active, you can hold the Ctrl+Right Mouse button to pan the view around
-- While active, you can hold the Ctrl and use the Scroll wheel to zoom in and out
-- While this mode is active, grabbed items and spawned LogiX nodes will be moved on the plane of the currently focused UI
- Added roleCloudVariable configuration option for auto-startup/headless worlds, which allows auto-assigning a role based on a cloud variable (based on requests by @Geenz | Graphics Programmer, @Avinash | WeMakeVR and others for organizing events)
-- This lets you define a cloud variable and assign value to users to determine their role in given world
-- The variable needs to be of type string. The value you assign equals the name of the role you want to grant to given user
-- It is STRONGLY recommended to make sure you're using cloud variable that you can write into on behalf of other users (definition_owner), otherwise users might be able to assign themselves a high permission role
-- If no value is set for given user, the usual method to determine default role is used
- Added allowUserCloudVariable configuration option for auto-startup/headless worlds which allows using cloud variable to always allow user into a session (based on the same request above)
-- The cloud variable needs to be of type bool and set to true for given user
-- This is equivalent of the user being sent an invite - they can join regardless of MaxUsers limit and even if the session is set to Private (they need to obtain)
-- Same recommendations as above apply, please make sure you use the right cloud variables that you have proper control over
- Added new cloud variable permissions to provide more flexibility (this resolves some issues brought up by @Epsilion, @DrFrank, @Robyn (QueenHidi), @Toxic_Cookie and others)
-- definition_owner_only and definition_owner_only_unsafe
--- These mean that the variable value can only exist (and be written to) by the owner of the definition (meaning other users cannot have a value at all), making it useful for "central" annoucement variables
--- These permissions work with User defined variables as well
-- definition_owner_only_contacts and definition_owner_only_contacts_unsafe
--- The variable value can be written to only by the definition owner for any user who is an accepted contact of the definition owner
--- This permission is valid only for User defined variables and allows for the tagging use-case of cloud variables without needing a group
-- variable_owner_only_contacts and variable_owner_only_contacts_unsafe
--- This allows anyone who is a contact of given value owner to read/write given value (meaning your contacts can read/write your value)
--- This is valid permission for both User and Group variables

- Added "Bake Non-driven BlendShapes" to SkinnedMeshRenderer
-- This will bake any of the blendshapes that are not driven into the base geometry. For models with lots of configuration blendshapes that are only altered once, this can provide significant optimization, reducing memory usage and load times of given mesh
-- Note that this is destructive operation. If you want to alter those blendshapes later, it's recommended to keep an un-baked copy and bake for public use
-- You can also chain this with the blendshape split optimization - if the baking bakes all the body blendshapes, leaving only face animation, the split will be much more efficient
- Added +/- LogiX node (under operators) (requested by @Ukilop and @KierDran)
-- This takes a value and offset as input and outputs the value with offset added and another with offset subtracted

[h2]Tweaks:[/h2]
- Switching between different camera modes (first person, third person and UI currently) now has a brief transition
- Fast CDN server for asset downloads is now enabled for everyone (it's not 100% final, we're testing the impact on the infrastructure cost for this change and might change back)
- /listGroupVars command now uses the same argument parsing as rest of commands (based on feedback by @AlienInArea51 (MR-Alex))
-- This makes /listGroupVars "Group Name" work, rather than requiring /listGroupVars Group Name
- Bone/blendshape chirality detection heuristics will now suppress isolated letters when they're part of a common known name
-- This fixes cases where some bones/blendshapes are detected as left or right despite having no chirality (based on report by @3x1t_5tyl3)
- Gizmo scale is now based on the distance to the actual viewpoint, rather than avatar head
- Removed obsolete temporary code for the Metamovie event from a few months ago

- Merged English locale addition by @Turk
- Merged Korean locale update by @MirPASEC
- Merged Russian locale addition by @Shadow Panther [RU/EN, UTC+3]
- Merged Esperanto locale additions and fixes by @Yellow
- Merged French locale additions (including new MTC strings) by @brodokk
- Merged Polish locale additions (including new MTC strings) by @art0007i

[h2]Bugfixes:[/h2]
- Added path validation to all cloud variable commands, to report when the path contains invalid characters
- Fixed floatQ and doubleQ cloud variables fetching the parser incorrectly, causing exceptions when trying to use these datatypes (reported by @jeana)
- Fixed bone/blendshape name heuristics incorrectly determining chirality as right when it should be left in some cases
- Fixed UI elements Z-fighting when viewed directly from the front
-- Existing custom UI's will be attempted to be auto-upgraded as well (setting OffsetUnits to 5) to fix any custom UI's, but depending on your setup you might need to update them manually to fix this issue
-- This should also fix the context menu options flikering in some cases when in desktop mode
- Fixed variable_owner write permission being writable in a world due to new ActiveUser variants (reported by @Shadow Panther [RU/EN, UTC+3])
- Fixed rigged mesh import breaking when there is a hand rig, but it's not weightpainted to any actual geometry (based on report and sample model by @GearBell)
- Fixed Neos using the default string variable validator on read, rather than the actual type, resulting in strings over 256 characters being read as null (reported by @Epsilion)
- Fixed not being able to join Contacts+ sessions when not friends with the host (re-reported by @Raith (CytraX), @Shifty | Quality Control Lead, @Shadow Panther [RU/EN, UTC+3] and others)
- Fixed broken audio setting upgrade process due to the new async/await local database API (repoted and logs provided by @H3BO3 and @Flip)
-- This fixes Neos not being able to start up for users who haven't played in a while
- Fixed input gates not disabling after the last key is released
-- This also fixes the Ctrl+Right Mouse Button touble tap not working to reset the camera in 3rd person mode
Known Issues:
- In UI Camera mode the near clipping doesn't adjust yet, resulting in the avatar and other items sometimes intersecting
- Grabbing items further away in UI Camera mode will snap them to the plane, rather than preserving their current distance
- Deleting LogiX wires in UI Camera Mode doesn't work well yet

2021.4.29.1307 - Contacts+ bugfix, Cloud Variable fixes and additions (enums)

Hello everyone! Just a small patch now, sorry, just want to get an improtant bugfix out breaking Contacts+. There's some more improvements for cloud variables as well, notably you can now use them with enum fields.

This build is compatible with previous one, but if you run into the fixed issues or want to use the new features, make sure everyone's on this patch, otherwise you get a bit of weirdness.

[h2]New Features:[/h2]
- You can now use Enum types for cloud variable components
-- The cloud variable must be of type string to sync properly
-- E.g. creating CloudValueField will now work properly

- Added variants of commands to create and setup cloud variables in a single command (based on feedback by @Turk)
-- /createUserVar
-- /createGroupVar

- Added internal support for Surround 5.1 samples, which should allow for audio clips with this layout to be played and audio intput/output devices to work as well
-- This should potentially fix crashing on systems with 5.1 audio systems when selecting it as audio output device (reported by @Khosumi)

[h2]Bugfixes:[/h2]
- Fixed variable definition paths not being properly validated, causing errors when trying to create variables with some punctuation symbols (e.g. '/')
- Fixed ActiveUserCloudField and CloudValueField not updating the cloud variable when the target field is changed
- Fixed users not being able to join Contacts+ sessions if not friends with the host (reported by @Shifty | Quality Control Lead, @/home/JellyOsaurusPC)

2021.4.28.1415 - Cloud Variable improvements and bugfixes, other tweaks & fixes

Some more improvements and additions for cloud variables, as well as a bunch of other tweaks and bugfixes! This build's a bit smaller sorry, the weekly update took most of the time today to do! ^^; I should have more stuff tomorrow, but I wanted to push this out so it doesn't have to wait!

[h2]New Features:[/h2]
- Added ActiveUserCloudValueVariable and ActiveUserCloudField
-- These will sync value/field to the cloud variable owned by the user under which the component is currently parented
-- Everyone in the session will see this user's value, unlike CloudValueVariableDriver which locally drives it for each user
- Added CloudValueField
-- This is similar to CloudValueVariable, but uses external field instead of one on the component

- Added definition_owner_unsafe permission
-- This is same as definition_owner, but allows read/write in unsafe context (e.g. Worldspace, rather than just Userspace)

- Added RandomBool node that randomly outputs true or false (requested by @̣)
-- You can control probability of true with the Change input (default 0.5, meaning 50/50 chance between True and False)

- Added ReferenceCast which allows driving target reference of type O using a reference of type I
-- Note that currently there is not a nice way to instantiate this component, as the UI doesn't support multiple generic arguments at the time and it serves more as foundational addition. You can however setup casts with LogiX in the meanwhile

[h2]Tweaks:[/h2]
- Added validation for Write and List permissions on Cloud Variables to avoid setting invalid permissions
-- List permissions cannot be set to variable_owner or variable_owner_unsafe anymore, only definition_owner or anyone
-- Write permissions on User-defined variable cannot be anyone or definition_owner anymore to reflect their limitations (Group defined variables do not have this restriction)
-- Existing variable definitions were auto-updated to respect those rules
- Added missing type aliases for uint2/3/4, long2/3/4 and ulong2/3/4
-- This fixes cloud variables of these types not working (reported by @Robyn (QueenHidi))
-- This also lets you use those aliases when attaching components in the inspector
- Desktop reticle will stay activated when clicking and scrolling now, in addition to mouse movement (based on feedback by @Psychpsyo)
- Laser cursor texture now uses Clamp edge mode rather than Repeat, preventing some visual artifacts (reported by @Psychpsyo)

[h2]Bugfixes:[/h2]
- Fixed Neos Components not handling permissions for variables defined or values owned by groups properly, making it impossible to read/modify them even though the user is member of given group (based on report by @Robyn (QueenHidi))
-- Note that for group-owned variable values, the host must be member of the group for the read/write to work
- Fixed /getUserVar command without arguments not working properly
- Fixed components using RefID as generic argument failing to load on the latest build (reported by @Raith (CytraX), @Shifty | Quality Control Lead, @Kal, @orange, @Epsilion, @H3BO3 and others)
-- Note that when possible, it's recommended to avoid using RefID's directly though and instead use casts
- ButtonValueShift will now wrap around properly when going in reverse (reported by @̣ and @Epsilion)
- DynamicValueVariableDriver, UserDistanceValueDriver, ValueUserOverride and Slider now initialize their default values to valid quaternions for floatQ and doubleQ datatypes (based on report by @̣ and @Ukilop)
- Fixed Leap Motion ignoring the Enabled setting (reported by @Strydr)

Introducing Cloud Variables, interviewing Creator Jam, over concurrent 300 users

Hello and welcome to another of our weekly updates!

We have very exciting updates for you. This week we have released our Cloud Variable system, a new powerful tool for persistence independently of objects and worlds, allowing you to sync settings across worlds and avatars, build world with progression system, synchronize values between your private UI and the world in real time, sync data across sessions and instances of items and much more!

The system is designed for many different use cases and usage patterns, to learn more about how you can start using it, check out the details below.

The weekly Creator Jam has also reached the magical number 100! On our last Friday live stream, we have interviewed Medra, VegasX and Cataena to learn more about Creator Jam, their background and experiences, if you missed the interview definitely give it a watch!

In more great news, we have reached over 300 concurrent users a few days ago! Our community has been constantly growing for past two and half years and we're very excited every time we reach a new record number. While it's not as high as the absolute peak at the New Years, it's one that appeared organically almost out of nowhere.

We also showcase some amazing community creations and events, like a brand new MurderX game by the Japanese community, DJ event and talk about new mentor applications. Check out the details below!



Interview with Medra, VegasX and Cataena from Creator Jam

Creator Jam is the longest running weekly collaborative event on Neos started by Medra. Every Sunday users both old and new come together to build something fun and awesome based on a theme. Last Sunday, the Creator Jam hit the magical 100 - a hundred creator jams!

In preparation for this amazing achievement, we have interviewed Medra along with VegasX and Cataena on our last Friday stream, to learn more about their background, how they got to Neos, Creator Jam and their experiences. If you missed the live stream, watch the interview here:

[previewyoutube][/previewyoutube]

Introducing Cloud Variables

This week, we have implemented a new powerful system for persistence, dubbed cloud variables! While persisting individual objects and worlds is at the core of Neos, sometimes it’s necessary to persist and synchronize data across multiple objects, worlds and sessions for each user and that’s where the cloud variables come in!

We have designed this system with a high degree of flexibility, making it useful for several different scenarios and workflows, from being able to sync settings and toggles on objects, avatars and worlds across sessions without having to save a separate copy to your inventory, saving a state, scores and progression in game worlds, to syncing state across multiple worlds and sessions or between your private Userspace UI and the world or tagging users by external applications for custom tailored experiences and events.

[previewyoutube][/previewyoutube]

This way one powerful system tackles multiple different problems that content creators and event organizers have been facing for a while, adding to the repertoire of powerful world building tools and improving the overall user experience.

[h2]Variable Definitions and Variable Values[/h2]
To understand the cloud variables, you must first understand two core concepts - what are variable definitions and what are variable values. To use a variable in your creations, you must first create a definition - a structure of said variable - its name, data type, default value and access permissions.

Variable definitions can be owned by both users and groups, with the latter having greater flexibility in both the usage patterns, permission settings and higher limit for number of definitions. To create a definition, you’d use following commands:

/createUserVar 
/createGroupVar


Once a definition is created, a value can be stored and read for every individual user and group based on this definition. Typically as content builder, you’d define variables for your worlds and items, for example “Quality.Shadows” if you’d like users to be able to toggle shadows on and off in your world.

Within the world, you’ll then link the fields, for example the Enabled boolean of the shadow casting light to the cloud variable using the CloudValueVariableDriver component, using the full path of the variable you have created.

The full path is obtained by prefixing the ID of the user or group who owns the variable definition to the variable name. For example if you have created the variable definition “Quality.Shadows” on your user account with ID “U-MyUsername”, the full path will be “U-MyUsername.Quality.Shadows”.

Neos will then sync the boolean to the corresponding value of each user and automatically update their cloud variable if they change the setting, without you having to do anything extra!

[h2]Read, Write and List Permissions[/h2]
To provide control over how the variable values and definitions are used and give them a lot of their flexibility in access patterns, each variable definition has a list of read, write and list permissions.

Read and Write permissions do pretty much what you’d expect them to - control who can read the value and who can write to it. The List permission is specifically for the variable definition and determines who can see a given definition on the profile of the owner (group or user). By default this is private, allowing you to create private variables that nobody will know that they exist, unless you publish their name somewhere.

Currently following permissions are available, with each permission type supporting any combination of these (although some are redundant):

  • definition_owner - variable can be read/written only by the user/group who owns the definition. This lets you make variables that you write/read on behalf of other users/groups and can be useful for tagging purposes - e.g. event organizer will create variable definition that can be written to only by them and write values to assign given user a role or trigger specific behavior in LogiX
  • definition_owner_unsafe - same as above, but can be read/written in “unsafe” contexts - e.g. public worlds. Requires presence of the user owning the definition
  • variable_owner - variable can be read/written by the user/group who owns the value. This means the user can change/read their own value based on the definition. Even if you own the definition, this means that you cannot read/write it, only the user can! The value can also only be read/written only in a safe context - currently the Userspace (private UI)
  • variable_owner_unsafe - same as above, except the value can be read/written in “unsafe” contexts - e.g. in a public world. It requires the presence of the user owning the value, but anything in the world can access the value. This is useful for things like settings or saving progress in a game world - but please note that it technically allows for cheating, by the user writing arbitrary value and so you should avoid using it for anything sensitive.
  • anyone - the variable can be read/written by absolutely anyone, without the user being present. This is generally recommended only for read/list permissions, as writes will allow anyone to mess with the value arbitrarily (unless that’s what you want)


There is also an important distinction between User and Group variable definitions - variables defined by Users can only have variable_owner or variable_owner_unsafe write permission. This means that you cannot write the value on behalf of another user - they can only do that themselves.

This still lets you make items and worlds with settings, toggles and other persistent state for each individual user, but disallows for usage patterns where you (or someone else) modifies those values without the user being present - e.g. tagging them for an event. You will need to use Groups for that.

[h2]Supported data types[/h2]
Currently cloud variables support all the basic Neos primitives - numbers, booleans, vectors, colors, matrices, strings and URLs. Picking the right data type is important, as it ensures that any stored values are properly validated - e.g. when you pick float3, the User won’t be able to store arbitrary string.

The string datatype specifically allows for additional validation - you can specify maximum length, using string: as the datatype. For example string:8 won’t allow strings that are longer than 8 characters.

By default, string can be 256 characters, but you can manually increase this limit to 8192. We’ll likely revisit those limits in the future and provide a way to increase them. We also plan to allow for more complex datatypes as well, such as arrays and other collections.

Here is the full list of supported primitives:

bool,
sbyte, short, int, long,
byte, ushort, uint, ulong,
float, double, decimal,
float2, float3, float4,
double2, double3, double4,
int2, int3, int4,
uint2, uint3, uint4,
long2, long3, long4,
ulong2, ulong3, ulong4,
floatQ, doubleQ,
bool2, bool3, bool4,
color,
float2x2, float3x3, float4x4,
double2x2, double3x3, double4x4,
datetime, timespan
string,
string:


[h2]Cloud variable management commands[/h2]
Currently cloud variables are created and managed using commands sent to the Neos account in your Contacts list. Alternatively you can use the AdminX (requires .NET 5.0 runtime) tool bundled with the Steam installation (under Tools folder), which lets you type those commands directly - if you use that one omit the forward slash.

Here is the list of commands you can use:

-- /getUserVar  - lists definition
-- /getGroupVar
-- /getUserVarValue () () - gets current value of given variable for given user
-- /getGroupVarValue ()
-- /setUserVarValue () - sets current value of given variable for yourself
-- /setGroupVarValue () - sets current value of given variable for specific user
-- /listUserVars () - lists all variable definitions
-- /listGroupVars
-- /createUserVar - creates new user variable definition
-- /createGroupVar - creates new group variable definition
-- /setUserVarType - sets the datatype of given variable definition
-- /setGroupVarType
-- /setUserVarDefaultValue - sets the default value for given definition
-- /setGroupVarDefaultValue
-- /setUserVarPerms - sets read/write/list permissions for given variable definition
-- /setGroupVarPerms


[h2]Usage patterns[/h2]
To get started, here are a few samples for some common usage patterns for the cloud variable that you can use and how to set them up:

[h3]User settings and toggles[/h3]
You can use this pattern to create items and worlds that have user-customizable settings that persist/sync across sessions or to have toggles for your own avatars (e.g. switching clothing options that persists without having to save the avatar itself).

For example this will allow you to create a toggle for fancy graphics in your world that persist:

/createUserVar myWorld.fancyGraphics
/setUserVarType myWorld.fancyGraphics bool
/setUserVarPerms myWorld.fancyGraphics read,write variable_owner_unsafe


Then use component CloudValueVariableDriver to drive whatever you need in the world to toggle the fancy graphics on and off and make a visual toggle that toggles the boolean value. That’s all you need, once the user toggles the value, the state will automatically be synced to their cloud variable value!

[h3]Controlling avatar/world options securely from private UI (dash)[/h3]
If you’d like to make private UI to control settings in your worlds or on your avatar without any gadgets in the world being able to alter the value for you, you can use similar pattern to above:

/createUserVar myAvatar.glowColor
/setUserVarType myAvatar.glowColor color
/setUserVarPerms myAvatar.glowColor read variable_owner_unsafe
/setUserVarPerms myAvatar.glowColor write variable_owner


This will allow the variable to be read in the world, but won’t allow the world to write the value. However you can still make a custom UI as a Facet and place it on your dash to control it. Neos will sync the value in real time!

[h3]Globally syncing state across worlds/items[/h3]
If you’d like to control some aspect of your world across all of its sessions or perhaps display a global announcement/message on an item you distribute (for example when there’s a new version available), you could use the following pattern:

/createGroupVar MyGroup gadget.globalMessage
/setGroupVarType MyGroup gadget.globalMessage string
/setGroupVarPerms MyGroup gadget.globalMessage read anyone
/setGroupVarPerms MyGroup gadget.globalMessage write definition_owner


Once you set this up, use the CloudValueVariable component to get the current value. Instead of getting the value for each individual user, you get the value owned by the same group:

Path = G-MyGroup.gadget.globalMessage
VariableOwnerId = G-MyGroup


Then set the value as such:
/setGroupVarValue MyGroup gadget.globalMessage “Eat plenty of fruits!”

If you don’t own a group, you can use similar pattern with user variables too and simply link the component to the variable value of your user account:

/createUserVar gadget.globalMessage
/setUserVarType gadget.globalMessage string
/setUserVarPerms gadget.globalMessage read anyone
/setUserVarPerms gadget.globalMessage write variable_owner


Path = U-SomeUser.gadget.globalMessage
VariableOwnerId = U-SomeUser


[h3]Tagging users for events[/h3]
If you’re hosting an event and you’d like to assign different users different roles and trigger things to happen depending on their role. You can do following:

/createGroupVar MyGroup experience.role
/setGroupVarType MyGroup experience.role string
/setGroupVarPerms MyGroup experience.role write definition_owner
/setGroupVarPerms MyGroup experience.role read definition_owner_unsafe


Make sure that your sessions are hosted by an account that is part of the MyGroup so it can read the variable value. Once you have this setup, you can tag users, either using the command or in the future through the API with OAuth 2.0 integration:

/setGroupVarValue MyGroup experience.role U-Visitor VIP


You can read the current variable using the ReadCloudVariable LogiX node, by firing an impulse with the path of the variable, ID of the user who joined and then perform arbitrary logic based on its value.

[h2]Current limitations of real time synchronization of cloud variables[/h2]
One of the current limitations 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.

However 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. Our current plan is to add full real time synchronization in such cases by integrating SignalR into our cloud infrastructure, which will help the cloud scale better for other things like active sessions or the messaging system as well, but is a bigger chunk of work.

Even with this current limitation the cloud variables should be a very powerful and flexible tool for many use cases and one that will grow as we continue pushing forward. We’re just at the beginning of its possibilities and we can’t wait to see all the awesome stuff you’ll make with it!

Community Highlights


Hello everyone! Your friendly neighborhood Turk is here! I hope your weekend was fun because boy was Neos jam packed this weekend! Let dig into some of the goodies!

[h2]Community Achievements[/h2]
Guess what happened this week folks? We hit the milestone of 300 users organically this week! Not without other platforms just having issues and using Neos as an alternative! We had about 3-4 different music events this weekend on top of folks just checking out the platform! This means so much for us and Neos as a platform going forward as well too! This means we are going to have more Mentors and more things are in store too soon(™)



[h2]Community Maps[/h2]
[h3]MurderX by NEJ and NOF[/h3]
A recreation and upgrade of a popular game mode across multiple platforms, it’s MurderCross! In this map you can actively live build, and live create your murder map, allowing you to have templates or all kinds of interesting setups, so you not beholden to just one map all the time! Thanks Neos East Japan and Neos Onaka Force! This map is sooo cool!


https://twitter.com/mikan3134/status/1385171527319101441

[h3]CJ 100: Ghost Talk & Centijampaede[/h3]
This week at Creator Jam we have Creator Jam 100! That means the folks at CJ have done 100 events where every week they have had a creation theme different each week! This week they went through all previous 100 jams to find the goodies and treats that folks really enjoyed from past jams, along with a surprise! Some folks at the CJ have been hard at work this week to make Ghost Talk! A game akin to Jar’s Spirit Speak from VRC, we now have our own version in Neos! So grab a bunch of friends and hop in and try to see how you can hint what cards are which to you friends. (P.S Yes the hints are still horrible, good luck)



[h2]Community Events[/h2]
[h3]Rebirth[/h3]
Some folks from the Wave Community have been starting to run shows in Neos! This is only the start of the weekend parties that will usually happen in VR! Orchestrated and Assisted by Rez in “Rez-A-Light” folks got together and got their boogie down in Neos!



[h3]The Bassarisk[/h3]
This weekend on Saturday we had a DJ event that is run by Kulza and has a different DJ each time! This week we had FuzeWasTrash doing some nice Synthstep tracks for folks to dance and groove too. It was pretty popping, there were people dancing on bread!



[h3]Secret Sky Saturday[/h3]
This weekend was Porter Robinson’s Music Festival Secret Sky. Being well known in the VR Community, it’s a VR Music Festival that folks can throw on a headset and chat and tune into a live performance all within the confines of a nice session to chill and chat with friends. We had about a couple different watch parties full to the brim with a whole collective of users!



[h3]Neos hit 300: More Mentors Unlocked[/h3]
Congrats Neos you did it! You achieved the secret (not so secret achievement) We now can onboard more mentors to be a part of the Mentor Program! Mentors are a mixture of Community Helpers but also Community Guides and help keep Neos with its charm and community. If you're interested in joining and want to help with the community, feel free to put in an application! https://wiki.neos.com/Mentors If you want to know more and contribute to helping out Neos!



---------------------------------------------------------

Anyway that's all for this update! And as usual, huge thanks to you, our community, Patrons and everyone else for supporting this project. Without you none of this would be possible and we couldn't dedicate our time to improving the platform every day. See you next week for more Neos news!

2021.4.27.1385 - Introducing Cloud Variables, inspector reference improvements

2021.4.27.1385
Hello everyone, I've got an exciting update, the first release of cloud variables is here! :smile: There provide a brand new mechanism to easily persist data/state independently from the objects/worlds that use them, but also provide a way for cross-world/session communication, synchronizing values between your Userspace and Worldspace (e.g. to control stuff on your avatar from private UI) or tag users for events and more.

This is just the first version, so there are likely to be some bugs, but hopefully this will open up some new cool options for building interactive content in Neos. I've designed the system to be quite versatile and there's a few more things that are coming (e.g. using them to control access on headless), but I hope you'll already have lots of fun with them!

I'll also do a bit more of a writeup for weekly update, but I'll have to do that tomorrow since I'm already in a bit of a zombie state. There's a few other things too, like improvements for the inspector and few bugfixes.

[h2]New Features:[/h2]
- Introducing cloud variable system! A new way to persist and synchronize data independently from items and worlds (previously requested by @Toxic_Cookie#8064, @Hidi#1111 and many others)
-- You can use this to create items that will save their settings (and other state) for the user across sessions and worlds
-- All linked instances of the same variable are synced in realtime across worlds (including between Userspace and Worldspace), providing a mechanism for cross-world/session synchronization and for synchronizing values from Userspace to the World
-- Group-defined variables can also be used to store custom information on users, for example to tag them with specific role for events and similar
- To be able to use a variable, you first need to create a variable definition
-- Definition includes name/path (essentially a key), datatype (all Neos primitives should be supported), default value and read/write/list permissions
-- The definition allows each user/group to store the variable value on their account based on this definition. You cannot store variables without them being defined first
-- Both users and groups can define variables. The ID of the user/group becomes first part of the path (e.g. G-Neos.test.string)
-- User-defined variables cannot be written to by anyone else other than the user owning the value (in other words you cannot write value on behalf of another user). Group variables don't have this limitation

- Added CloudValueVariable (under Cloud/Variables) which outputs/syncs in-world value with a cloud variable
-- You can specify both the variable Path and VariableOwnerId, allowing you to read/write cloud variables for any user/group (assuming the right permission)
-- You can specify change handling, which lets you ignore changes to the field or sync them to the cloud variable, either only when owner is present or always

- Added CloudValueVariableDriver which drives target field with a state of a cloud variable
-- The value is locally driven by the value of the cloud variable for each user, allowing you to completely replace ValueUserOverride to provide customized settings
-- WriteBack will update the CloudVariable (when permission allows) when the driven field is changed
-- FallbackValue provides value for when one isn't available. This is not default value, once the variable is linked it will use the default value from the variable definition if user hasn't changed it yet
- Added ReadCloudVariable and WriteCloudVariable LogiX nodes for reading/writing cloud variables (under Storage)
-- Read will force the value to be updated as soon as possible. Do not spam this, otherwise you might get throttled by the cloud server

- Added following Neos commands to create and manage variable definitions and variable values (you can use the AdminX tool in Steam install to send these - exclude the forward slash)
-- /getUserVar - lists definition
-- /getGroupVar
-- /getUserVarValue () () - gets current value of given variable for given user
-- /getGroupVarValue ()
-- /setUserVarValue () - sets current value of given variable for yourself
-- /setGroupVarValue () - sets current value of given variable for specific user
-- /listUserVars () - lists all variable definitions
-- /listGroupVars
-- /createUserVar - creates new user variable definition
-- /createGroupVar - creates new group variable definition
-- /setUserVarType - sets the datatype of given variable definition
-- /setGroupVarType
-- /setUserVarDefaultValue - sets the default value for given definition
-- /setGroupVarDefaultValue
-- /setUserVarPerms - sets read/write/list permissions for given variable definition
-- /setGroupVarPerms `

- Following datatypes are supported:
-- Neos/C# primitives - bool, byte, int, float, double, float3, bool3, double4, float3x3, color and so on
-- string and string: (default length of string is 256, maximum is 8192)
-- uri, datetime and timespan
-- More datatypes will be supported in the future
- Following types of permission are supported:
-- read who can read the value of given variable
-- write who can write to the value of given variable
-- list who can see the definition of given variable
-- all - shortcut to set all of them
-- You can also do multiple like so: /setGroupVarPerms Neos test.string read,write anyone

- Following permissions are supported:
-- definition_owner only the user/group who defined the variable can read/write/list it
-- variable_owner only the user/group who own the variable (the value) can read/write it in safe context (e.g. Userspace)
-- variable_owner_unsafe same as above, but works in public (outside Userspace). Requires presence of the user owning the variable value, but anyone in the public world could potentially alter the value
-- anyone - anyone can read/write/list given variable, recommended for read/list for public variables, generally not recommended for writes (means absolutely anyone can change anyone's value)

- Some more important notes:
-- Reads/writes are buffered, batched and cached and will take a bit to propagate. All active instances within Neos are synced in realtime
-- Variable Definitions are heavily cached and will typically take several minutes to update. It's recommended to set them up fully in advance
-- Written values are validated according to datatype and will be rejected if they do not conform
-- Users can define up to 256 variables, Groups 8192. These limits will likely be extended for Patreon supporters and through other means
-- Current limits, permissions and other aspects are subject to change

[h2]Tweaks:[/h2]
- Inspector reference fields will now try to show the name/path of the target/field (when available) instead of the type (requested by @Psychpsyo)
- Added a mechanism for providing custom member/field names for display and implemented on SkinnedMeshRenderer for blendshape weights
-- Combined with above, the inspector and other sources will now show the actual name of the blendshape when possible, rather than its index

- Record upsert on the cloud API is now idempotent, rather than generating conflict when already updated record is tried to be inserted again
-- This fixes unecessary "Sync Error" message in Neos when the sync succeeds, but the request times out or fails due to network connectivity issues
- Added health check to cloud instances, to automatically restart misbehaving servers in the pool
-- This should improve cloud reliability in case one of the instances in the load balancer pool becomes unresponsive
- Optimized cloud variable definition fetching

- Merged Korean locale additions by@MirPASEC
- Merged Japanese locale additions by @Aesc
- Merged Spanish locale additions and tweaks by @Ruzert
- Merged Czech locale additions by @rampa_3 (UTC +1, DST UTC +2)
- Merged Russian locale additions by @Shadow Panther [RU/EN, UTC+3]

[h2]Bugfixes:[/h2]
- Fixed not being able to join Contacts+ sessions when not friends with the host (reported by @Santus_Lupinus#9753, @H3BO3, @Turk, @Froppy and @Chris Filvazt)
- Added extra diagnostics to errors when formatting locale strings

[h2]Known Issues:[/h2]
- You cannot delete variable definitions yet
- Unregistered users cannot store cloud variable values. A system for local storage will likely be added at some point
- Currently all sessions must be on the same host/user to sync in realtime. For different hosts the sync is only done once every few minutes. This will change in the future