Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Collections

From Resonite Wiki
While very powerful even in it's current state, full collection support is as yet to be implemented. See #Limitations for current status and future plans.

'Collections' is C#'s name for all types of arrays, such as lists, dictionaries and bags. Because Resonite is written in this language, a lot of the available types are based on this core concept. Along with the generic, Resonite also exposes a number of of higher level types as well for dealing with more specialized applications, such as the 'Hits' array from RaycastAll. The ProtoFlux Collections Category can be useful for building with such collections.

These have existed from the first days of FrooxEngine but previously were only accessible in limited ways, by using mods or or through specialised nodes or components. As of 2026.8.26.1047('Collections Part 1') they have become accessible as a general concept in ProtoFlux.

Resonite Specific. (Sync* and others)

One major thing to note is the number of Collections and Values that start with 'Sync', these are special in that they interact with and are synchronized over the network as part of the Data model. For an idea of how they relate, see Type:Sync`1.

Some elements have other properties, for example Type:IReadOnlyList or Type:IReadOnlyCollection can only be read from and never modified as they access data from elsewhere that cannot be changed through this interface.

Another special type is 'dummy', if you need something to fill in a search field, there is a good chance that you can use that to get a more generic result that can then be overloaded to give you what you want. All Collections related nodes on this wiki describe how to properly fill in their type inputs.

Types of collections

While words like 'Value' is used in the following examples, it should be reminded that this can also refer to Objects(References), not just simple numbers.

List

Often known as just arrays in other languages, these are represented as a list(ha!) of values of any data type that can accessed by an index. They can have items added or removed to the list.

They are accessed by their location in the list. The index is an Int and nodes such as GetAt can be used to get a value and InsertAt to add to it.

ISyncList allow a number of users to write to the same list at the same time and so long as there are no conflicts between values, the results will merge.

Each value within a list is a Sync - an object that can be referenced, sourced or driven.

The first value is identified by index 0, the last by Count minus 1.
Index Value
0 Dragons
1 Kobolds
2 Lizards
3 Rocks
4 Moss

Array

Arrays are the lower level relative of lists. In C# that means they have a fixed number of elements defined at creation time and cannot be changed. Only the values in each index.

Resonite has a slightly different interpretation of "a more primitive list": SyncArray, which can only store DataModel value types (string, int, Chirality).

They support all operations of lists - including resizing. Internally they use an actual array which is replaced by a bigger one as needed.

The main difference is that individual values do not have an identity within the world. They cannot be referenced, sourced or driven.

Conflicts between multiple users' changes are handled as a whole. That means SyncArrays are also 'atomic', if two users write to the same array only one version of this array will propagate even if there are no conflicts.

This makes them more lightweight for storing a large amount of data which is not modified by multiple users like in RawMesh or LineGraphMesh.

Dictionary

These are represented as set of key/value pairs. While the value can be anything, even null, all the keys must be unique. They can have elements added to or removed from freely.

If you know the Key, you can get the resulting value, using GetKey. Or you can iterate over the whole table one pair at a time with nodes such as ForEach.

The key could be anything - another reference such as Slot or String or a value such as a float or even int. The implementation of SyncDictionary is limited to DataModel value keys, though.

SyncDictionaries are also subject to the same kinds of conflicts as SyncList:

  • Only additions or removals of a single user are accepted at a time - even if the keys are different. The last person to edit the dictionary will have their version take over.
  • Values handle their conflicts individually.
Key Value
Frooxius Yellow
Decoy Purple
Nexulan Green

Bag

Bags are a list of items of any generic type with no inherent order and can include duplicates. They are typically a collection of objects, such as a list of users (and related details) in ValueUserOverride, or found on any slot's component list in the inspector using the WorkerBag (which was used in the early days of Ref Hacking).

Internally Resonite's SyncBag is a Dictionary where the key is the object's RefID, allowing it to act closer to a Hash Function in other languages and ensuring that even duplicate items are unique.

Usage

To create a new collection to be stored in the data model, you can use these components:

Other components also contain accessible collections. The following pages have lists of collections that can be accessed: (Wiki login requried)

Component vs ProtoFlux

ProtoFlux Data Type Component Example
SyncArray Value ValueArray SyncArray<floatQ>
SyncFieldList Value ValueList SyncFieldList<string>
SyncFieldDictonary Reference ValueDictionary SyncFieldDictonary<int,string>
SyncRefList Reference RefrenceList SyncRefList<IAssetProvider<Material>>
SyncRefDictonary Reference RefrenceDictonary SyncRefDictonary<int,Slot>
SyncTypeList Types TypeList
SyncTypeDictionary Types TypeDictionary SyncTypeDictionary<string>

Searching For Node Types

Generic to allow overloading

This can be one of the most frustrating aspects to using Collections. For most cases finding the correct type of node(Using generics, see left) and connecting it to the source will make it Overload and change to the correct type. However in some cases you need to be able to manually search for the correct node types (also referred to as Complex Types).

(used when the "dictionary value" is a ProtoFlux value type, in this case "float" is, and "dictionary key" is a protoflux object type, in this case "string" is)

  • AddValueWithObjectKey (for example, IDictionary<string,int>) - Uses Object as a Key(string) and stores a Value(int)
  • AddObjectWithObjectKey (for example IDictionary<string,Slot>) - Uses Object as the key(string) and stores an Object(Slot)
  • AddObjectWithValueKey (for example IDictionary<int, string>) - Uses Value as a key and stores Object(string)
  • AddValueWithValueKey (for example IDictionary<float, float>) - Uses Value as a key(float) and stores a Value(float)

Example

In the example to the left, hovering the FluxTool over the desired node output gives the following string: Dictionary <SyncRefDictionary<BodyNode,Slot>

From this we can work out it's a Dictionary thus needs to use the GetKey node to access it (Instead of for example GetAt for a List ). The first name is the name of the 'Key' that is used as the Key/Value pair of the Dictionary and the second is the Value that is being stored and will be the final output from the resulting node.

BodyNode is an Enum, so is a Value. And A slot is an Object so:

Under Collections -> GetKey choose, in this case: GetObjectWithValueKey

  • In TDictionary: SyncRefDictionary<BodyNode,Slot>
    • This needs to be the full name of the desired Collection.
  • In TKey: BodyNode
  • in TValue: Slot

This gives the final Node: GetObjectWithValueKey<SyncRefDictionary<BodyNode,Slot>,BodyNode,Slot>

Other Collections nodes on this wiki describe how their input fields work.

Limitations

The current biggest limitation is the ability to create/allocate new collections in the network synced data model store directly using ProtoFlux. You can use a write to create a local/store for use within the ProtoFlux execution context however. You can also use some types of Components to 'pre-allocate' Collections: See #Usage for some workarounds until the official implementation is completed.

Editing collections directly through the inspectors are still largely unimplemented.

A number of types are not yet accessible/exposed, these include:

History

  • 2026.8.26.1047 (See: discord link for full notes)
    • Lists and Dictionary type collections are now supported!
    • ForEach, ForEachWithIndex, AsyncForEach & AsyncForEachWithIndex
    • Add, Contains (element/key), GetA (index/key), Set (index/key) IndexOf, InsertAt, Remove (element/key), RemoveAt, Count, Clear, IsReadOnly, UnpackKeyValuePair
    • SplitString/JoinString - Works with collections of strings.
    • Users/RaycastAll - New nodes that directly create collections as outputs.
    • EnumValues - to get a Read Only collection of Enum types.
  • 2026.8.27.1059 (See: discord link for full notes)
    • ValueList/ValueArray/ValueDictionary/ReferenceDictionary components for storing collections
    • ForEachWithIndex now works with ReadOnly
    • RemoveAll nodes, which will remove all occurrences of specific value in a list
  • 2026.9.8.1049 (See: discord link for full notes)
    • CharsToString will accept any collection of chars and construct a string from via IEnumerable<char>.
    • Added TypeList + TypeDictionary<K> component

See Also

Videos

Introductory Tutorial for Getting Started with Collections

Dictionary Specific Tutorial