1. Neos VR
  2. News

Neos VR News

2020.9.17.639 - Named Dynamic Variable Spaces, tweaks and bugfixes

Sorry for smallish build again, but here are some new Dynamic Variable Space goodies! I've finally settled on some implementation details, more stuff coming for them soon (mainly LogiX bindings). Some more small additions, tweaks and bugfixes.

[h2]New Features:[/h2]
- Added support for named dynamic variable spaces, allowing variables to selectively link up with a particular space
-- DynamicVariableSpace now has SpaceName property. Changing this property is relatively expensive operation and recommended to setup only once
-- It also has "OnlyDirectBinding" property. When enabled, variables won't be bound to this space unless they specify it by name (meaning anonymous variables will go through)
-- You cannot use punctuation and symbols in the variable or space name except for ., _ and (space), others are reserved for future syntax. It's recommended to stick to latin letters and digits, but most Unicode letters will work
-- Variable name can specify binding to particular space using following syntax: space name/variable name. It will bind to the nearest parent space with given name. Any other spaces in the way will be ignored
-- Only direct linking with particular space name is supported right now, more will come as needed (e.g. optional preference, multiple names, ignoring specific names, potential multi-level linking)
-- When no space is specified, it will link nearest variable space with any name (including none)

[h2]Tweaks:[/h2]
- Userspace dash now has "Dash" variable space, which is shared across all screens the title header (you can use it to interlink your facets)
- Each spawned user is now setup with "User" dynamic variable space, with only direct binding
- Each world is setup with "World" dynamic variable space at the root slot, with only direct binding (existing worlds are auto-upgraded)
- Exposed "SetActive" on DataPreset as impulse target to LogiX (based on discussion with @ProbablePrime)
- Merged additions fixes for Japanese locale from @orange and @Melnus
- Merged additions for Chinese and Esperanto locales by @Melnus
- Merged Turkish and English locale fixes from @Blaze

[h2]Bugfixes:[/h2]
- Fixed BipedRig "Detect Right hand" incorrectly finding left hand fingers when used on a full body rig
- Fixed component lookup in parents ignoring the components on the root slot
- Added fallback to MessageFormat.NET for cultures not supported on given platform, defaulting to invariant culture (based on report by @Melnus)
- Fixed the set null button in Inspector not working for delegates (reported by @ProbablePrime)

2020.9.16.596 - Korean & Turkish, LogiX color sample, World UI tweaks, fixes

Sorry for another small build! Here are a few new things and also new languages! Neos is now in Korean and Turkish as well, other translations have been updated as well.

Some small additions and tweaks to world browser and new LogiX node to directly sample color (the same way the ColorTip does) along a direction.

[h2]New Features:[/h2]
- Added Korean (ko) localization by @MirPASEC, @LUA and @R3C0D3r
- Added Turkish (tr) localization by @Blaze
- WorldThumbnailItem now has "PressAction" field, which determines what happens when it's pressed. This can be set to null and a custom button event be handled instead (based on request by @ProbablePrime)
- Added "Sample Color" LogiX node under Rendering, which will sample visible color from particular point in a given direction on Impulse (based on request by @ontodistro and others before)
-- This is done by rendering a very small and narrow view, so it's relatively-ish expensive operation (depending on the complexity of the geometry, you can save a lot if you use a short far clip)
- Added "OverrideOnLink" to DynamicVariable and DynamicField
-- When enabled, the value will always override all other dynamic variables with the same name when it's linked to a new dynamic variable space
-- This can be used when you want particular instance to always be the "authority" - however if possible it's recommended to use write-only variable readers like DynamicVariableDriver in such scenarios
- Added "Headless Sessions" world category, which shows all headless sessions, including empty ones (based on feedback by @Salivenand @Shifty | Quality Control Lead)

[h2]Tweaks:[/h2]
- WorldListManager and WorldItem (WorldThumbnailItem and WorldDetail) now have UpdatingUser reference to determine which user is updating the UI (requested by @Turk)
-- If null, it's the host, otherwise it's the referenced user
- Tweaked the visual of LogiX impulse debug display to prevent it from becoming blinding with rapid impulses (based on feedback by @Rue Shejn | Artist 3D)
- Merged new translation strings for Japanese, Chinese and Esperanto (by @Melnus)

[h2]Bugfixes:[/h2]
- Fixed mismatched assembly on the headless client, causings some behaviors to break (e.g. generating some inspector UI, discovered by @Kal, @Shifty | Quality Control Lead and others)
- Fixed incorrect Live email warning and Cancel button translation keys in the login dialog (reported by @Shifty | Quality Control Lead)

2020.9.15.571 - German, Icelandic, Chinese translations, proper plurals, fixes

Sorry for small build again, but there are some important fixes and tweaks, as well as more localization! Neos is now in German, Icelandic and Chinese!

I've also implemented proper pluralization algorithm for MessageFormat.NET instead of the simplified one the original library had, the updated version is available in our fork here: https://github.com/Frooxius/messageformat.net

[h2]New Features:[/h2]
- Added German translation by @AlienInArea51 (MR-Alex)
- Added Icelandic translation by @Nammi
- Added Chinese (zn-cn and zn-tw) translations by @Melnus
- Added MeshAssetMetadata (under Assets/Utility) which outputs metadata of referenced mesh (number of vertices, triangles, points, submeshes, bones, blendshapes and presence of various data channels)
- Added Texture2DAssetMetadata (under Assets/Utility) which outputs metadata of referenced texture (size, format, memory usage)

- Implemented proper pluralization rule selection logic in MessageFormat.NET so it generates proper pluralization operands, allowing the Unicode CLDR plural forms to be implemented 1:1
-- This ensures that correct plural forms are displayed for all languages, respecting any decimal points and trailing zeroes (e.g. English will have "1 item" and "1.0 items", even if they're the same number)
- Implemented pluralizer for Icelandic (requested by @Nammi)
- Implemented pluralizer for Russian and Ukrainian

[h2]Tweaks:[/h2]
- Switch Locomotion Module will now check against the localization key (e.g. "Locomotion.Fly.Name") rather than the localized locomotion name, providing more consistent behavior across cultures (based on feedback from @フリック)
- Mesh inspector statistics (vertex, triangle count and others) now update in realtime and don't require refresh
- Added Blenshapes count and channel statistics to the mesh info in the inspector
- Texture inspector statistics (size, format, memory) now update in realtime and don't require refresh

- Mesh actions and stats in the inspector are now localizable
- Texture actions and state in the inspector are now localizable
- GrabWorld locomotion is now localizable
- Slide locomotion is now localizable

[h2] Bugfixes:[/h2]
- Fixed CurrentCulture node returning invariant culture when the "Override Locale" is an empty string (@Alex from Alaska and @Enkiko)
- Fixed ChildRemoved events not firing correctly in some cases, breaking certain behaviors
-- This fixes aligners with Auto Add Children not cleaning up removed objects (reported by @Alex from Alaska)
-- This also fixes the inspector not updating list of children immediatelly when destroying children (reported by @art0007i)
- Merged Espranto locale file fixes from @Melnus

2020.9.14.511 - Japanese and Esperanto translations, tweaks and bugfixes

Sorry for smaller build today, but here are some tweaks and bugfixes and first two community contributed translations. Neos is now in Japanese and Esperanto!

I've also added pluralizer for more languages, should include Spanish and a bunch of others (see language codes below).

Updating the Unity SDK to latest version as well, check the #💻unity-sdk channel for updated build (will be a bit later after this is posted).

[h2]New Features:[/h2]
- Added Japanese (ja) localization by @orange
- Added Esperanto (eo) localization by @Melnus

[h2]Tweaks:[/h2]
- Leap Motion, Vive Hand Tracking and Windows settings are now localizable (based on report by @Shifty | Quality Control Lead)
- CurrentCulture LogiX node now outputs the user's overriden culture
- Added pluralizer for following language codes:
af an asa az bem bez bg brx ce cgg chr ckb dv ee el eo es eu fo fur gsw ha haw hu jgo jmc ka kaj kcg kk kkj kl ks ksb ku ky lb lg mas mgo ml mn mr nah nb nd ne nn nnh no nr ny nyn om or os pap ps rm rof rwk saq sd sdh seh sn so sq ss ssy st syr ta te teo tig tk tn tr ts ug uz ve vo vun wae xh xog

- Unity SDK now converts PBS detail textures by default (requested by @Enverex)
- Unity SDK now respects the "Emission" checkbox on PBS materials and won't convert the emission color if the emission is off (based on report by @Enverex)

[h2]Bugfixes:[/h2]
- Increased the tolerance range for the difference in userspace and world laser position and angle
-- This should fix cases where certain avatars would have the private lasers permanently in a different position (reported by @Little Helper and @Shifty | Quality Control Lead)
- Bumped version of the World List Facet, forcing it to regenerate
-- This should fix cases where the search bar has broken after the update, reported by @Conduit and @Shifty | Quality Control Lead)
- Ensured that tutorial controller visuals have no colliders, which could block the lasers (reported by @Duskitty and @Shifty | Quality Control Lead)
- Fixed regression with Autojoin LAN sessions opening all sessions, instead of just LAN ones (reported by @maxer1)
- Restructured how are ChildAdded and ChildRemoved events dispatched internally, to ensure that any changes during those events do not mess up the internal state of the data model
-- This should fix cases of immediatelly destroying child objects when added causing null parents and causing the world to be unsaveable (reported by @Coffee | Programmer, @Turk, @H3BO3, @Hayden (PolyLogiX - ZyroDesign) and @Zyzyl)
-- IMPORTANT!!! This might have some subtle (or not so much) side effects, watch out of potential bugs for anything reacting to children
- Fixed Full Body Calibrator height value not applying after some security improvements (reported by @Shifty | Quality Control Lead)

Neos goes multilingual with full localization support - help us translate Neos!

Hello and welcome to another weekly update!

This week we have a great news for all of our non-English users, Neos is now going multilingual! Majority of the core UI can now be translated into different languages, making Neos easier to use if English isn't your native tongue. We hope this will help bring more users and creators onto the platform and grow the community as a whole.

We're not finished with the system yet either. Not only it provides some improvements for the English text as well, but later on the system will be expanded so you can integrate it into your own creations, whether they're tools, items or worlds, allowing them to be translatable as well.

That way your creations can reach a wider community and conversely you'll be able to use creations that were originally made in a different language than your own.

Currently the only translation for Neos is Czech, but our community has already started on translating it into other languages like German, Turkish or Japanese. If you'd like to contribute, check out the details below!



[h2]Neos Localization System[/h2]

With us being a non-US based company, we understand how important localization is. We want everyone to be able to use and enjoy Neos, even if English isn’t their native language, so we devoted a part of this week towards a push to enable the majority of Neos’ core UI to be localizable.

We introduced a new type of asset called “LocaleResource”, which contains strings in a particular language. These assets are then used to drive the in-game text based on your active locale.

By default, Neos will use your system locale, but you can override it in the Settings, using the “Override Locale” setting, by providing an appropriate language code. Most of the UI will change language immediately, but for parts that do not, simply close and reopen them or restart Neos if needed.

[previewyoutube][/previewyoutube]

The system will automatically fallback from a specific locale to English, so any parts of the UI that are not translated will show in the original form. This allows them to be gradually translated. Currently we only have Czech translation, but the community has already started on translations to various languages.

For the strings we have chosen the ICU MessageFormat syntax by the Unicode organization. This syntax supports the majority of different languages and has enough flexibility to correctly follow the grammar rules of different languages, particularly when it comes to the plural forms.

[previewyoutube][/previewyoutube]

Coincidentally this helps the English version as well, as plural messages are displayed correctly as well (e.g. “Synchronizing 1 item” instead of “Synchronizing 1 items”) and other places now use proper percentage formatting, rather than value (e.g. “Volume: 42%” rather than “Volume: 0.42).

[h2]Future plans for the Locale Resource system[/h2]
At the moment the localization system works only for the core UI and you can’t import your own custom LocaleResource files. This is done so we could introduce the system sooner. However we have designed it in such a way so it can be extended later on, to enable translations of user-made content as well.

Using it for the core Neos UI also helps test out the design and make necessary tweaks before we extend it further. Once the time comes, you’ll be able to create and import your own LocaleResource files to drive strings on your own items, worlds, tools and other things you create.

With that in place, other users will be able to contribute translations, with the cloud infrastructure helping to find and resolve them across different versions of the translation files or even multiple translations of the same language.

We’re also looking into the best way to add the ability to translate other resources, like textures, audio and video files as well, but haven’t decided on a particular approach yet.

[h2]Help us translate Neos![/h2]
If you’d like to help us translate Neos into different languages, we have created a GitHub repository called NeosLocale. It contains the latest versions of the LocaleResource files (the same ones that ship with Neos) and allow anyone to contribute changes or additions via Pull Requests.

After the community contributions get merged into the repository, they will be available to anyone on the public Neos build. You can also install those localizations manually by copying them to the “Locale” folder in the Neos installation.

[h3]How To Contribute[/h3]
If you'd like to contribute translations, create a branch of fork of the repository, make the changes and once they are ready to be merged create a Pull Request, so the contributions can be checked and merged. You don't need to translate everything at once, if you cover part of the UI, the changes can be merged, with more translations coming later.

[h3]If you're contributing a new language[/h3]
  1. Create a new Issue for given language in format "Language [lang-code]", for example "English [en]", which will help coordinate efforts of different translators.

  2. Verify that Neos' fork of ICU MessageFormat.NET has pluralizer for your language, by checking the "AddStandardPluralizers()" function in this file.

    If you can't find your language code in this file, please make a Issue either on the official Neos issue tracker or in this repository.

    Alternatively you can implement the pluralizer yourself based on the reference from the Unicode CLDR repository and make a pull request for it to be merged with our fork or MessageFormat.NET

  3. Add a new [lang-code].json file to your fork. We highly recommend creating a skeleton file first wihout any translation strings, just containing the Locale and Authors and creating a pull request, so it's clearer to other contributors that translations are being worked on by someone.


[h3]Contributing translations to a language[/h3]
If you'd like to contribute translations for existing language file (or one you have just created), we recommend the following:
  1. Make a fork of the repository or your own branch.
  2. Update the language file, either by modifying the translation strings or adding new ones for missing translations.
  3. Ensure you do not have any left-over English strings in the file. Your file should only contain actually translated strings. Any missing strings will automatically fallback (see below for details)
  4. Ensure your modified translation file works correctly in Neos (see below how to test)
  5. Create a Pull Request for your translations to be merged into the main repository. After merging they will be available publicly in the next public build of Neos.


As Neos develop, we'll be constantly adding new strings in English or modifying the existing ones. We recommend watching the repository for activity through GitHub, so you can get notified when there are changes and new strings to be translated.

[h3]Testing your translation in Neos[/h3]
As you work on the translation we recommend that you periodically check it inside of Neos. This will not only help ensure that you don't have any syntax errors, but also make sure that the strings are correct in the context.

To test the translation, find folder where Neos.exe is installed (on Steam, you can do so by right clicking Neos, going to Properties -> LOCAL FILES -> BROWSE LOCAL FILES...) and then locate the "Locale" folder. Simply place your modified file into this folder and Neos will load it up.

By default, Neos uses your system locale to determine which file to load. You can override this by going to Settings and changing the "Override Locale" to a different language code.

  • You can edit the translation file on the fly without shutting down Neos. To force it to reload, change the locale to "en" and then back to your own.
  • Note that while most UI will change language immediatelly, not all of it would. Simply close and reopen the UI dialog to load the translated strings
  • If the string is showing in English, you probably have a typo in the string key. It needs to match exactly
  • If the translation isn't loading in Neos, it is likely JSON syntax error preventing it from being loaded
  • If you see "ERROR!!!" instead of your translated string, you have a syntax error in the particular string. Check Neos' log file, which will contain details.


[h3]The ICU MessageFormat Syntax for translation strings[/h3]
Neos uses the ICU MessageFormat Syntax defined by the Unicode organization for its localized strings. This offers high amount of flexibility on how you translate strings and ensures that you can correctly follow the grammar rules of your language, particularly with regards to pluralization (e.g. displaying "1 item" vs "1 items"). This is why it's important to ensure that your language has a pluralizer implemented in our fork of MessageFormat.NET

To learn more about the ICU MessageFormat Syntax check the following links:

Official Documentation Formatting guide with examples (the C# version of the library currently doesn't implement all the formatters, but they will be added as needed).
Language pluralization rules

Typically most strings are straight up replacements, with no complex syntax. Some use just a simple variable replacement (e.g. {name}), which will replace part of the message with given variable.

For cases when the structure of sentence changes based on the value of a number, you'll see pattern {variable, plural, ...}. Each language has a set of plural categories, like zero, one, two, few, many and other. Some languages have only "other", some (like English) have "one" and "other", while other languages have multiple. Make sure that you familiarize yourself with the plural categories in your language (using the links above) so you can correctly translate strings using this syntax.

Another common syntax is using the {variable, select, ...} form. This lets you match the variable against specific values and provide translated versions of each. You can either replace a single word (e.g. "Server status is {status, select, good {Good} bad {Not Good} }") or the whole sentence (e.g. "{status, select, good {Server is good!} bad {Oh no, servers are down!}}") depending on what works better in your language.

Please let us know if you have any questions or are unsure about certain things.

[h3]Language codes and fallbacks[/h3]
Neos uses the IETF language tags to load locales. These consist of a single primary language tag (typically two-letter language code from ISO 639-1 or a three-letter code from ISO 639-2 (1998), ISO 639-3 (2007) or ISO 639-5 (2008)) and and optional region subtag with country code.

When loading locale file, Neos will first check for the most specific locale file. Then it will load any missing strings from the general locale file and last it will load any missing strings from the English locale.

For example if your system locale is British English (en-gb), it will first look for "en-gb.json" file and then for the more general one "en.json".

We recommend putting most translations into the general language file (single two letter or three letter code) and if necessary only put specific overrides into the more specific language file. That way, most translations can be shared across variants of the language if possible.

Any strings you don't translate at all will also fall back into their English variants, so you don't have to worry about missing some of them, they can be translated later (or by another contributor). This also ensures that newly added strings in the English will show up and can be gradually translated as they come.

[h3]What if I find string that cannot be translated?[/h3]
While majority of Neos' UI has been converted to the localizatoin system, there are likely a few stragglers and some parts that aren't translatable right now. If you encounter such place, create an Issue on this repository, ideally with screenshot of the non-translatable part, so we can convert it as well.

Currently there are a few known parts that cannot be translated, but are planned to:
  • Enumerations (e.g. certain tool options that cycle through several options)
  • Component names and categories (component names will still show original for technical reasons, but will show optional translation for non-English languages)
  • LogiX node names and categories (same as above)
  • Component fields (those will only show optional translated names on hover once tooltip system is implemented)


[h3]Any questions?[/h3]
If you have questions or are unsure about something, you can create an Issue on this repository or reach out to our team on the official Discord.

[h2]What's Next?[/h2]
Originally our plan was to work on the workshop system, but after starting the work it quickly became obvious that this would lead to a rabbit hole of more extensive UI additions and reworks, so we have opted to leave it for later and instead shift our focus towards optimizations.

There are still a few smaller, but important things to go through, like extending the dynamic variable system with new behaviors and polishing some parts of its design. After that, we'd like to focus on various optimizations for a while, starting with some data model optimizations and then doing bigger ones. We'll have more info on that as we go.

If you'd like to see more, keep an eye out on the #devlog and #neos-updates channels on our official Discord. And as always, thanks for all your support bringing this project forward!