Room Persistence

In case it wasn’t obvious, it’s super important to me that it’s easy, natural, and “low-stakes” for people to share personal content like photos, videos, and documents in Hubs. I think this use-case in particular is one that the low friction of the web will enable in a way other platforms cannot, and also could be a killer use of social VR.

Of course, this is tough to balance with the fact that we also want to make it possible to share, archive, or re-use bits of room state. So hence this thread :slight_smile:

I guess I could imagine something like:

  • We implement CCK first, which can be distilled down to “auto-save”, so that if your client disconnects you don’t lose what you’ve created. Anything beyond that boils down to just increasing TTL on the data. Culturally, people will probably create “persistent rooms” by just keeping a client connected at all times. (People did this in Rec Room.) Could be a mix of local storage (for entities) and hosted storage (for uploads) or entirely hosted. Whatever we do for uploads would be easy to re-purpose to include entity data, and seems like it wouldn’t require accounts since the data is effectively useless blobs sitting on disk, and will get nuked on some TTL.

  • Once that works, we add the ability to “pin” objects as a v2. (This could align nicely with the Phoenix Channels support for durable room state in ~Q4.) This is the first time we have state on our servers that doesn’t require a specific user be connected for anyone to access it. Once pinned we’d end up decrypting any hosted content and removing the TTL, since we’d need to serve it even if the person isn’t in the room. Pinning might need to be tied to an account so we can have a method for people to expunge the data we store for pinned objects, since we don’t expire it anymore. Can’t get around this even if we punt on uploaded files, because people could be drawing stuff they want us to remove too.

  • Once that works, we add the ability to export/snapshot all the pinned objects in a room for re-use. By this point we probably will have a clearer picture of how to do this in a way that is privacy preserving, etc.

I suspect you’ve all talked about this internally in the group, but I still have a hard time seeing why we want to save anything right now.

Even with the ability to author content in the hub, it seems like the “things” people author could still be sent out of the system, as gltf’s or similar.

I get the “friction” thing: for people who don’t have “web accounts somewhere” needing to store on the web is hard. But, there are so many options for web storage (e.g., all the “big 5” offer free services, as do dropbox/etc, plus temporary services like uploadcare and so on) that it feels like that would be a good “first step”. We could conceive of hosting content later, possibly as a paid service to make it sustainable, if/when we see the friction become real.

The reasons I’m so keen on keeping it external are

  • Simplicity
  • Sidestepping all the issues with hosting (privacy, liability, performance, etc)
  • When people have the files, they can do with them as they will. Opens up the door to interesting external tools and mashups
  • If we can save authored content as things like gltf’s, perhaps people will be able to leverage tools like Blender (on a hypothetical online gltf editor) to clean up or improve their assets. This reduces the pressure for us to make the editor full featured
  • User expectation: hubs is still “ephemeral”. We have the ability to create state that you can re-activate when you go back, but the state is up to you, not us.

I guess I’m struggling to see any real win in having us save content.

I don’t think this risk is related to the Room Snapshot Model. I can already capture everything in the room (including voice data) using OBS. As in any multi-user app, the people on the other end can create copies of anything you send them without telling you. E.g. Snapchat informs you if someone used his phone’s screenshot tool to save a copy of your snap, but nothing informs you if he took a photo of his screen with a separate camera.

Consider the use case of uploading a photo from your phone. Relatively few (edit: rephrased :)) are going to intuit that they have to upload the photo to a hosting provider and get the URL in order to share it in the space. They will expect to be in the app, hit a “+” button, and pick the photo from a photo picker. The underlying incidental nature of where and how that file is hosted is secondary to the mental model of “I want to bring stuff into the space, give me the tools I need to get it in easily.”

I don’t think a 2d projection of a VR space has the same mental weight as being able to re-create a real snapshot. For example, if I create an art gallery and impart my creative energy into it, I may not care about someone posting photos of the time they spent there in VR, but may care a lot about how the app encourges and enables the “export” of the entire gallery, as-is, for reproduction in VR.

But I can grab copies of everything; it’s a web browser and it’s downloading stuff from the internet. Right?

I agree.

I agree.

Right, so we should be careful about encouraging people to share information they don’t want others to be able to copy. We can design hubs such that information you share is encrypted and only decipherable by the person you want to share that information with, but each user still has to trust the people they’re sharing the information with.

When you say “low stakes” I’m reminded of these articles.


Are the “practice spaces” in these articles what you have in mind? Preventing copies is not the only way to encourage “low stakes” exchange.
(As an aside while there are interesting thoughts in these articles, I don’t believe/agree with the conclusions/recommendations.)

I like this. It’s the same as the snapshot model except that Mozilla doesn’t store the snapshots for you and you can edit/store/author however you want.

Yes we’ll want some story around keeping artifacts compatible with future versions of hubs (or hoping there exists mirrors of older versions). A formal schema seems like a good way to tackle this, although an informal schema and manual upgrade process may be tractable for some small number of simple changes. (We add a field to a component, then upgrade the text-based snapshots by running them thru sed to add a default value for that field.)

I admit this gets my spidey-sense tingling, but perhaps just because of context. Is this important for … what long term trajectory/use-case?

One read on this says we absolutely MUST store content because most people don’t have web-accessible storage, so requiring a URL is too high a barrier. But this feels wrong to me; we’re creating yet-another closed system the minute content is put in it and saved in our servers. Sure, it’s built on the web, and sure it’s open and has nice properties. But, the content is now hidden and saved and “OMG I have no idea where it lives and how to get rid of it”

Another read on this say we absolutely MUST NOT store content and must insist that anyone who wants to share personal stuff must first upload it somewhere. Perhaps we give them links; perhaps we build on services like Firefox snapshots to provide storage. BUT, that storage is outside of hubs and controllable and manageable independently.

Me, I would likely create directories in dropbox for certain uses: drop copies of things there so I can find them, use dropbox finder integration on my mac to get a copy of the url, paste it. If I decide I regret sharing a picture or video, I delete it from dropbox. And that link breaks. Easy-peasy.

The web is full of places and services for storing and sharing content; it seems like we’re being more webby if all the content that you can share and view and create in hubs ends up in those, and we reference it by URL.

I would like to suggest a hybrid of:

Room Snapshot Model (RS)
and
“Opt-in Pinned Objects” (ORO) model

Essentially, functions like RS but only for opted-in objects.
Let’s call it:

“Opt-in Snapshot Model” (ORS) model

The reason for this is that as I want to be able to save state of a room at will, but trust that I have control over who sees it and when. I also expect that other users in that room have a say in what content they share can be saved or not. At the same time, I understand that anyone can save the state of the room. This would be like several people taking a photo of a whiteboard after a meeting, but then being able to restore that whiteboard in any other meeting in the future (with the caveat that anyone can erase their contribution to that whiteboard before the photo is taken, if desired).

I believe that we also want ORO in addition to this, but as far as order of operations go, ORS should come first. This also potentially avoids the concerns about us storing data, at least for now.

I’ll add that if we’re only saving links to external content, it also means that I can pull access to my contributions at any time afterwards, as well. (or change it, by updating the files … which is a whole other interesting “feature”).

I can empathize with this – the CCK model kind of blurs the lines a bit though. The CCK model is kind of “local storage security semantics, but we push things to our servers to help reduce loading times.” If you’re not logged in, the data is effectively deleted. We will TTL it away as well, even though the bits are useless. Also, the mental model for the creator is “hit the delete button on the object in 3D” to delete the data, if they want to do it “manually.”

Perhaps the answer for v1 is CCK but use remotestorage.io as the underlying storage medium, with a “happy path” to use our provider. Helps with the privacy and centralization concerns, but could be a real nightmare UX-wise though. (typing in VR = awful, etc)

Yeah I think a “pinning” model (where, in the abstract sense, objects have a 0/1 state on them) and snapshotting may go hand in hand. If the object has a 0, it is ephemeral, exists only when the owner is connected, and can’t be easily exported. If it’s a 1, it will exist no matter who is in there (unless someone deletes it) and will be included in exports.

It makes sense to me that a single logical bit drives both, since its kind of a bit on “readability” of the internal bits of the object. It isn’t a system-enforced readability constraint (since its the web) but an application-enforced (or at least, encouraged) one.

The fact that it enables persistence decoupled from the creator is just inductive from the fact that the object’s guts are “readable” by other participants – eg if the creator left, everyone can see its state anyway and so could just replicate it, so having it be “automatically” kept in the room regardless of who is in there is just a convenience to prevent the need to “hand it off” between people. (the “room is empty” case is also inductive since theoretically you could build a bot to just do this work for you :))

Yes the “low-stakes” term is stolen from there :slight_smile:

I wonder if “low” vs “high” stakes in communications tools is something like “colored functions” (http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/) – as soon as you have one “high stakes” element (like, for example, the expectation that personal photos you share will appear in another person’s “stash” for their own use however they please) then suddenly the whole medium inherits it and becomes “high stakes.”

Ok so here’s a concrete proposal of a plan. I think based on the feedback in the thread we can pitch the CCK concept, and implement a 2-phased build out of ORO which then leads naturally to an RS model that dovetails with the editor tooling. (Doing it in the opposite order seems hard to wrap my head around.) The net effect on the other side is we have most of the use-cases covered, privacy seems good, and there’s minimal UX complexity.

First, we should just ensure that content created by a user (drawings, etc) does not get lost due to a reconnect. This is basically unrelated to persistence but I think is worth mentioning as something worth verifying and enabling if it doesn’t work.

Milestone 1:

I think the main mechanic we should introduce first is the “pin” concept. Every object in the room is by-default “un-pinned” and will be erased when the owner leaves. However, the creator (and only the creator) has the ability to pin the object. The UX probably looks something like “hit pause, and pinned objects look more ‘permanent’ in the scene, and you have a one-click to pin action you can perform.” A v2 could introduce a “pin lock” concept so all objects created are pinned by default for that session.

Under the hood, pinning will store the state of the object in a durable way (mechanism TBD) and also move uploaded content into permanent storage.

In order to pin something, the person must create an account. This is necessary because we need a way for that person to audit and delete the objects they have stored on our servers. The pin action can be visible at all times but clicking it will pop a sign in/sign up gate.

On the other side of this, users have a mental model that they must opt in to any long term persistence. This model is very privacy preserving since only the creator can pin, and it’s always clear to the creator when their objects are being made permanent. The downside is there may be unintentional loss of work if you forget to pin something important, but if we introduce the “auto-pin” functionality in a nice way, that could close the gap.

Milestone 2

Once pinning is implemented, the next phase will be to allow users to take a room with pinned objects and remix it in various ways. At this point, we can probably align this with our UX and model for scene creators using the Spoke editor. At this point it seems likely that scene creators will have two options for managing their scenes:

  • Full export to GLTF, do what you wish and host where you want. Does not require an account.
  • Hosted solution, scenes are stored on our servers, with various pages to support their use and discovery. Requires an account.

These two methods would then become available to users in-room as well but the context would be the set of pinned objects in the room.

At any time, users would have the option to export the current scene as a GLTF – that GLTF will include a reference to the scene GLTF and have internal nodes for each of the pinned objects. When that GLTF is used as the scene for a new Hubs room, it should effectively behave as a snapshot: the pinned objects will be in the room, but are dynamic and can be deleted, etc, as they are at export time. This export option will be available without an account, but will only export pinned objects, so those objects will have had to be created by people who have an account.

In addition to that, there will be an option to “Create a Scene” from the current room, which will tie into the same flow that is used in the Spoke editor. This will require an account, and will export and host the scene (which includes the pinned objects) in an identical fashion to the flow in the editor, but would be in game. This new scene would then be available on hubs.mozilla.com for sharing, feedback, etc.


One big downside to this model is that there’s an account gate to enable any form of persistence, since someone needs to pin an object for it to become persistent and exportable. It seems difficult to resolve this without adding at bunch of conceptual complexity: users should control what data can be exported, which implies they should have an opt-in mechanism to allow export/persistence of that data.

If we wanted to avoid the account creation step, we could have two attributes object creators can set (“pin this object” which would require an account, and “allow this object to be exported” which wouldn’t) but that seems super confusing and weird. The model outlined above is pretty natural: an object can be in two states – the initial state is the object is ephemeral and hard to export by others, and once it goes into the “pinned” state, it is permanent and conceptually exposes its data to everyone in the room, both in the form of being exportable but also because the object will always be in that room for them to see even if the creator leaves.

Overall, this seems worth the tradeoff, but if there’s a way to introduce the use case of “a bunch of people can create a room, intentionally create exportable objects, and export it as a GLTF without anyone signing in” I’d support it if it doesn’t result in a bunch of UX complexity or change the “my object are private and temporary by default” mental model users will have if we implement the above.

Also worth mentioning: what is covered here is largely about UX and not fundamental security when it comes to others in the room – since others in the room download your data to see it, of course they have everything they need to copy all of your objects, regardless of if you have pinned them.

Regardless of technical capabilities, encouraging certain behaviors and models for how people should interact with one another in the space is our job as social system designers, and the UX we design is our best way to communicate this. The model above encourages opt-in-to-expose content as the model, but leaves open the possibility for alternatives to be created by 3rd parties. For example, one could imagine a browser plugin that enables “export to GLTF” for all scenes you are in while in Hubs.

With this in mind, we shouldn’t be too fearful around our built-in UX being too restricting if the restrictions are there to foster certain cultural norms and increase user trust. If these are too limiting for certain users the possibility will exist for 3rd parties to help get around them. Much better for us to be adding these kinds of features with care, than potentially making things too open in a way that is hard to reverse – particularly because in most contexts where this is problematic for people, the web makes it possible for them to find a non-sanctioned mechanism to get past any model we’ve burned in. And of course, we’ll learn and potentially can refine these models over time as we determine if any of our decisions were overly cautious.

Also worth mentioning that the term “pin” here is probably a placeholder – it’s not a great metaphor, since it might imply that you can’t move the object around anymore when it’s pinned. I’m having trouble coming up with a better one though. (Stick, save, lock come to mind too but seem worse than pin.)

A question I have when reading this:

How are these exported GLTF’s used as scenes for a new hubs room?

The reason I am asking is this implies (to me) that you will support the use case I’ve been pushing for: creating GLTF’s externally. If I can point hubs at a GLTF, I should be able to create those GLTF’s any way I want.

Am I reading it too much? I really want to be able to create rooms externally, and automatically. A room with images on the walls for all my recent blog posts and projects; a room with the slides from a lecture; a room with the most recent video for a class.

Hey thanks Blair, we already support the case you are asking for. If you go to hubs.mozilla.com and click “options” in the top corner of the room creation box, you can enter a custom GLTF URL. So anyone who has the chops to get a GLTF scene on the web (probably with the help of our Spoke editor to add behaviors and test it) will be able to use it without storing anything on our servers. We’ll always support people bringing their own assets and hosting, and our initial roll-out of Spoke is not coupled with hosting but will be directing users to use their own hosting.

The hosting proposal is separated into two separate features: hosted scenes and stored room objects. Both of these will deliver a lot of user value beyond what we have already:

If you upload and let us host your scene:

  • You obviously don’t need to worry about where to save it
  • We will offer some UX around sharing and using it for room creation. (like a landing page to see it and create new rooms with it, or a profile page for you to show people all of your uploaded scenes.)
  • It will allow other users to remix your scene easily, right in the browser ,if you’ve CC licensed it (this could be critically important to growing the ecosystem)
  • We’ll be able to promote your scene in our newsletters, the home page carousel, etc.
  • Probably more stuff down the line

So hosting scenes is pretty huge if we expect there to be creators out there who want to create scenes for others to see, remix, or use. If we don’t build this stuff ourselves, its unlikely to get built anytime soon by the community, if ever, for a whole variety of reasons, not the least of which that there currently is no community and these tools may actually help create the community!

The other part of hosted state is persistent room objects. This need has just become really obvious now that the media tools work has come together. I want to be able to go into Hubs, create a room, spawn some photos, save them in the room, and then leave so I can come back later and look at them, for example, with the same link. I don’t want to have to worry about hosting, GLTF files, or any of that incidental complexity, I just want to spawn my photos and not have them disappear when I disconnect by clicking a save button or something. This seems like a pretty obvious thing for us to build, and is something I selfishly want for myself :slight_smile: