godot: MultiplayerSynchronizer doesn't update Texture property

Godot version

4.0 official

System information

SolusOS

Issue description

When setting up the MultiplayerSynchronizer to update TextureRect:Texture or Sprite2D:Texture it fails and may even cause issues.

When testing with two MultiplayerSynchronizers, one for a Label:text and one for a TextureRect:Texture it overwrote the settings IN THE EDITOR that was veeeery weird, I’m going to report this in another issue. You can see the tests in the video below:

https://youtu.be/JOtoQWPdjRU

Steps to reproduce

  1. Setup a server/client using ENetMultiplayerPeer
  2. Create a scene that is dynamically spawned across peers using the MultiplayerSpawner
  3. When spawning the above scene, change its texture
  4. Make sure the above scene has a MultiplayerSynchronizer trying to sync the “Texture” property

It’s complex, but that’s the gist of it.

Minimal reproduction project

  1. Toggle at least 2 Debug Instances in the Debug Menu
  2. Open the 03.making-lobby-to-gather-players/MainMenu.tscn scene
  3. On one instance, press the “Server” button
  4. On another instance, press the “Client” button
  5. Look at the Server instance as it has a scene with a different texture than the Client instance
  6. Look at the Client instance and notice it has none or the default texture

multiplayer-synchronizer-bug.zip

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 21 (14 by maintainers)

Most upvoted comments

Part of the solution would be to restrict the types in the property selector in the editor, but yeah keeping the silent failure doesn’t seem like too big a problem.

Also Variant::RID should probably be excluded as well at least in the editor.

Will look at some ideas for editor-only checks, but maybe I’ll just start by adding a basic editor-only solution restricting the types that can be selected and adding to documentation? Got some basic things working already.

Synchronizing “object type properties” (like resources and node references) is indeed not supported, we should add an error or warning in the debugger (and possibly the editor) to clarify that.

A texture is also pretty big in the context of network packet size, so you should not use a synchronizer anyway (even if it was supported, the “sync” would have thrown an error about the packet size and dropped the state).

Using an RPC to send the texture data (get_image().get_data()) might work assuming the avatar is small enough (e.g. 64x64) but keep in mind the Multiplayer API is not suited to transfer assets, which should be done using dedicated protocols like HTTP instead.

My working approach for the moment:

  • Restrict properties in the editor picker, preventing accidentally picking the wrong types
  • Add to documentation

To investigate:

  • Checking properties in the editor and warning on unsupported types
  • Warn on types that are not guaranteed to work (like arrays and dictionaries), not sure about this one

This is a different issue than the OP. The problem is that CollisionShape2D is a “fake” node, that doesn’t exists at runtime, which is why it doesn’t work. I expect the same to happen when trying to modify it with an animation player.

You probably want to use a custom property, which uses setter/getter to operate on the shape, and sync those, e.g.:

extends PhysicsBody2D

var shape_size : Vector2 :
  set(value):
    var shape := shape_owner_get_shape(0, 0)
    shape.size = value

  get:
    var shape := shape_owner_get_shape(0, 0)
    return shape.size

Yes digging through the code I noticed the error and was confused at first why it didn’t show up but I assume it’s because the property is just encoded as an object id and not as actual data

It seems to fail silently when decoding objects, there is an option in the API to encode objects fully but not used, which makes sense, but there should be checks there for data that obviously can’t be managed correctly as objects aren’t going to have matching IDs