Open BaxterOttoman opened 8 months ago
This is such a cool idea and would be extremely useful for world customization. The only issue with this would probably be in determining datatypes from a string as mentioned.
I like this idea a lot.
For a while I've had the idea to make a world that has different "entrances" to it, and based on which one you pick, it will appear differently for you (for example you spawn at a different point). This proposal would be a very generic solution that could also potentially fulfill that use-case. The thing is, those entrances wouldn't always be world links, they could also be session links.
So I would additionally suggest to use the same logic for users that join via session link, just that those values are stored under the individual user roots. So for world links, they are bound to the world variable space, for session links, they are bound to the individual user dynamic variable space. I'd also suggest ensuring all dynamic variable component created are marked as non-persistent, since this wouldn't make sense to store persistently with the world.
For a lot of the cases I can think of for this being most useful, having them be persistent makes more sense to me. After all, if you create a persistent value on a world you don't save, that's as good as creating it so it's non-persistent. That said, I think a few reserved query strings for affecting how this system would behave makes sense and allow even more flexibility.
For a lot of the cases I can think of for this being most useful, having them be persistent makes more sense to me. After all, if you create a persistent value on a world you don't save, that's as good as creating it so it's non-persistent. That said, I think a few reserved query strings for affecting how this system would behave makes sense and allow even more flexibility.
I'd say that depends on how the values are used in the different implementations. For your cinema for example, it would make sense to remember the last URL in the video player - but that doesn't have to be the dynamic variable itself. You'd kind of create those based on the "context" in which the world was opened, i.e. what link was used to open the world / join the session. Conceptually, that context is over once the world is closed. In your world, you could still read the value when the world is opened, and then write that to a persistent field. But that should be up to the world creator how to interpret / use the variables. As a default behavior, I think it makes more sense to have them non-persistent. Because it's easy to just copy the value to a persistent field, but it's more effort to do the clean-up yourself, and sometimes not even possible since this would allow for arbitrary arguments that someone could add to the world URL. You also wouldn't want those to "collect up" over time as you start and save the world many times, and perhaps do some changes to the systems in between.
I don't think we would do this specifically this way. The problem I have with this is that it ties the world query parameters specifically with dynamic variables - meaning you now can't use them for something else.
A better approach here is to expose the query parameters more generally, so you can then do with them what you want.
However there is an approach with that - we could introduce a component that specifically takes the query parameters and generates the dynamic variables - that way you only get this behavior if you place the component in.
However the other problem here is - how to actually determine the type? I don't think we would go with the example you proposed, because there's too much ambiguity and "trying to be clever", which ends up in convoluted rules that end up confusing the users.
E.g. what if I want "WorldColor" which is a string? What if it's a hex code? What if I want to provide it numerically?
If we were to do this, we would probably require either:
?worldColor(colorX)=<VALUE>
I think another acceptable option could be to have all variables created from query parameters be of type string, and leave the parsing up to the world creator, if that would simplify the implementation. It would also have the benefit of keeping the query string itself shorter and more readable.
That said, if types are implemented, I'd like explicit type mapping in a component much more. That way you could also define which query parameters are supported in the first place, and any others are just discarded and don't end up creating components.
Prepopulating the world with components to handle receiving the dynamic values if query strings are present sounds like a good idea for solving the typing issue to me. Makes it so the behavior is explicitly being called to happen. Then, if the case calls for entirely handling parsing through code, you can do that by just making the type a string. A complimentary flux node that can separate out a string value based on a key input would probably be called for too, if this is functionality that's added.
That said, if types are implemented, I'd like explicit type mapping in a component much more. That way you could also define which query parameters are supported in the first place, and any others are just discarded and don't end up creating components.
I think this is a very good idea - if the "interface" of a world can be defined like that and queried before launching the world, the world browser could perhaps list those values or even provide a way to set them when launching a session. That would take a lot of the guesswork out of it and make it clear what a world supports.
There's also an argument to be made for a sort of implicit declaration: any (lets call them) QueryParameterInput
For both options, a way to let users of the world know which paramters are "required" and which ones are "optional" would also seem like a good addition. It could be a simple checkbox, or providing a default value through a Nullable*
at the end of the name. For the implicit option, the checkbox or default value would have to be synchronized across instances, to prevent conflicting values.
Either way, there should still be an option to access the full query string or some kind of "params" option, so that worlds can feasibly make use of unspecified key/value combinations, e.g. to generate a elements in the world based on those inputs without specifying them (as there can be any number of them). Supporting HTTP query parameter like array data would also be convenient, once collections are supported.
I also like the idea of components defining the interface of a world. They should have an option to define if they are part of the world or session interface.
It may be useful to augment the VerifyJoinRequest
node with a way to get the parameters of the used link.
One could use that for "single-use visit-tickets" that are not bound to a user until use.
For both options, a way to let users of the world know which paramters are "required" and which ones are "optional" would also seem like a good addition. It could be a simple checkbox, or providing a default value through a Nullable - or even something like having an * at the end of the name. For the implicit option, the checkbox or default value would have to be synchronized across instances, to prevent conflicting values.
I'm not sure how well "required" query parameters would translate to worlds / sessions. If they aren't provided you can't start the world / join the session? That would be kind of bad imo. I'd say instead of marking them as "required" you could be able to set a default value, but leave all parameters optional, so that you can still open the world without providing anything, and the world can implement specific behavior then. (In the case of sessions, using Autopilot's idea the VerifyJoinRequest could enforce certain parameters to be specified, and deny the join if they aren't).
I'm not sure how well "required" query parameters would translate to worlds / sessions. If they aren't provided you can't start the world / join the session?
The quotes around it were very intentional - I more meant it as "should be defined for the intended experience" and "not necessary, but can be added for certain / extra features". The world browser or such could provide a warning though, that some "required" parameters haven't been set (but still allow opening the world anyways).
Since first commenting, I also thought of an example: Think of a party world - it might "require" a parameter to be set that determines the kind of party, or at least one message to put on the decoration banners. Extra messages, or perhaps a guest list, or the age for a birthday party would be "optional".
Is your feature request related to a problem? Please describe.
Many worlds have features that include media players and other customizable options that have values stored in the world. These currently must be set after the world has been opened and the host user has loaded into it. Allowing world level dynamic variables based on query strings entered into the URL would allow for an entirely new way to interact with worlds when starting them that may allow for very interesting and unique items and interactions. Examples will be in additional context.
Describe the solution you'd like
When a world URL is used to start a session, if that URL has query strings, an attempt should be made to determine a type, and if one is a likely match, a world level dynamic variable is written or created with the name of the dynamic variable equal to the key provided with the same value or a cast if it's not entirely compatable (IE, a colorX value if it's a web color name). In cases where the information can't be meaningfully parsed, the fallback of string would let the user try and handle values themselves.
The key should be used to weight the likelihood of a value being of one data type or another. As an example, a key of "WorldColor" would suggest if the value is "purple", that it should be cast from a web color name to a colorX, while "WorldColorName" may suggest it's supposed to be a string. I could speculate more on the specifics of implementation, but I believe this would be better informed through experimentation and iteration than my speculation.
Describe alternatives you've considered
Cloud variables are currently the go-to way to set values between worlds and it works well, however it has the limitation of that value being shared to all worlds that use that value. The desired functionality would allow values to be passed to specific instances of worlds.
Additional Context
Examples of feature utility.
A theater lobby world is created. In this world, users are able to interact and socialize. A URL supplied to a ticket booth which will be placed in a query string added to a theater world URL. When opened, the world will have a dynamic variable written that includes the URL provided and that value will be passed to a video texture provider. Users can join the world in the background through some interaction in the world and continue to socialize in the lobby world while the video is loaded and users are able to join at their leisure.
A world can be set up to act as a visualizer for a template, with flux and drivers in place to change values on the fly to allow users to customize a world. When they are happy with their choices, the values are passed along to a template world where the values will simply set values, but will otherwise be static and not require calculations further.
Requesters
Baxter