networked-aframe / networked-aframe

A web framework for building multi-user virtual reality experiences.
https://naf-examples.glitch.me
MIT License
1.16k stars 295 forks source link

Deletion of a component in the NAF schema is not replicated #442

Open diarmidmackenzie opened 11 months ago

diarmidmackenzie commented 11 months ago

Suppose I have clients A & B, and a NAF scema that replicates component C on an entity E.

Suppose further that A has NAF ownership of entity E, and component C on entity E has value X.

If on A, component C is set to value Y on the entity, then this gets replicated to B, so component C on the entity will now have value Y. All good.

However, if on A, component C is deleted, this does not get replicated to B. After deleting component C on A, component C remains present on B, with value Y.

Discussed with @vincentfretin on Slack. This may be difficult to fix, because replication is stateless, and there is no state on the entity to indicate that component C was just deleted (and that this fact needs to be replicated).

There appear to be a couple of workarounds:

  1. Don't remove component C. Instead define a new "null" value Z that component C can take, which is equivalent to the component being removed. With this change, everything will work fine.

  2. After removing component C, explicitly call syncAll on the networked component. This will initiate a full sync of all components in the NAF schema, which will include a null value for removed component C.

If we wanted to fix this, a fix based on #2 might be possible. NAF could listen for the componentremoved event, and intiate a full sync of the entity (or just a sync of the removed component).

Is this worth fixing? There are a few components where the component is added / removed to effect a change in the appearance of an object (as opposed to a model where the component is always present, sometimes in a null state).

E.g.

However workaround 1 is typically available (e.g. set line to visible=false rather than deleting the component; set object-parent to have a parent of null etc.

Workaround 2 should also be possible in most cases.

So although fixing this would improve NAF usability, it could also be acceptable to simply document and live with this limitation.

vincentfretin commented 11 months ago

I think a fix with solution 2 based on the componentremoved event would be great, calling networked.syncAll(null, true) to do a full sync if only the removed component is in the networked schema and for the specified selector of course. Or better instead of a full sync, send the partial sync as usual with an additional entry with the removed component set to null.

vincentfretin commented 11 months ago

The logic of of setting null for a component is in gatherComponentsData so for now only if fullSync and entity from selector not found or component not set. https://github.com/networked-aframe/networked-aframe/blob/6e0819a6005c7a011fc174f4bf047603551f264a/src/components/networked.js#L382

On the receiving end, if a component is null, it calls https://github.com/networked-aframe/networked-aframe/blob/6e0819a6005c7a011fc174f4bf047603551f264a/src/components/networked.js#L527 with data being null thus removing the component https://github.com/aframevr/aframe/blob/4e53a987caa257b6703b47f89392fd2473533f49/src/core/a-entity.js#L462