Multiple rooms per y-websocket connection?

Is it possible to connect to multiple rooms via a single y-websocket WebsocketProvider?

I see a similar question asked previously, but I didn’t see the original question addressed.

Hi @canadaduane,

The current design of y-websocket only allows for a single room per connection. This approach makes sharding and optimized routing easier (e.g. through a load balancer). Unless you are connecting to hundreds of rooms this won’t make a difference for you.

Ok, that helps for the immediate use case. We will probably have 3 rooms per relm for now:

  • One to control the “version” of the current relm and point to a corresponding yjs room. This will allow us to “clear history” when needed for optimization (We are already seeing signficant delays as a result of uncompressed history–during “world editing” a single game object can have its position updated 60 times per second as it is “dragged” from point A to point B. Combine all of these edits for hundreds of in-game objects, and we get a world history that is very long.)
  • One to contain the historical positions of players within the relm. This will allow us to keep player position history separate from world construction history.
  • One to contain the world state (and history, as much as we care to keep).

In the future, we are considering a grid-like structure where one relm may have hundreds of “cells”, and each cell would correspond to a yjs “room”. Using this system, we can have a player connect to the closest cell, and the 8 surrounding cells, to get spacially-relevant updates. In other words, “things that are far away” won’t affect the player’s bandwidth (and, importantly, will not be within the rendering view).

Nice idea to separate these data structures.

Some useful insights that you may use to tweak the dragging functionality: Updating the same value several times will result in only a single update message.

ymap.set('val', 1)
ymap.set('val', 2)
ymap.set('val', 3)
ymap.set('val', 4)
ymap.set('val', 5)
ymap.set('val', 6)
...

Consecutive changes to the same key-value are internally managed as two objects and also encoded. The changes 1-5 can be merged into a single change operation. In contrast to:

ymap.set('val1', 1)
ymap.set('val2', 2)
ymap.set('val1', 3)
ymap.set('val2', 4)
ymap.set('val1', 5)
ymap.set('val2', 6)
...

… which will create a separate object for each change. The time between each change doesn’t matter. But as long as consecutive changes happen to the same property, the changes can be merged.

I think the ideal use-case for this would be the Awareness instance because this kind of data is non-permanent.

Yes, this is why I was trying to unify the Awareness and Yjs types, because then my game objects’ attributes could easily switch between “off the record” (when being dragged) and “on the record” (once arrived at final destination).

Do you need to keep player positions around? If not, you could only store them in the Awareness instance. I would imagine that you can forget player positions once they leave.

Switching between Awareness and Yjs Types is probably not necessary if you optimize the drag-algorithm. As I said, setting the same value does not incur any cost.

More specifically. ymap.set('pos', 1);ymap.set('pos', 2) is as expensive (in terms of document size and performance when reading the encoded document) as setting the same value a million times. for (let i = 0; i < 1000000; i++) { ymap.set('pos', 1) }

We’re kind of split on this at the moment. We have some potential customers who want to be able to “time travel” to see context around team decisions. For example, if a team in Europe made a decision and moved some TODO cards around on a board, then a team in America wakes up and wonders “Why did they do it that way?” they might be able to rewind and see what the European team was doing/thinking/talking about at the time.

So I think the answer is “yes, we want to keep player position around” but with the caveat, “but not if it slows everything down so much that the relm is unusable.”

Right now, we are reducing player position updates by making sure to only record changes in direction every “50 pixels”. We’re also using Awareness for this at the moment, but would like to switch to Y.Doc if feasible.

Good to know, thank you!