godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.14k stars 21.19k forks source link

Unable to do an `rpc` with a function that uses arguments annotated with an typed Array #69215

Closed Nusiq closed 7 months ago

Nusiq commented 1 year ago

Godot version

Godot_v4.0-beta6_win64

System information

Windows 11

Issue description

Godot gives me an error when I try to execute an rpc function that has an argument annotated as Array[int], but it works fine when I remove the type annotation or change it to just Array. The data I'm sending is an Array[int].

This is the code of the function (it doesn't work when it has the argument type annotation):

@rpc
func client_print_array(host_array: Array[int]):
    print("Host array: ", host_array)
    print("My array: ", self.array)

When I try to trigger the rpc from the host it gives me this error:

E 0:00:04:0771   _process_rpc: RPC - 'Node(Main.gd)::client_print_array': Cannot convert argument 1 from Array to Array
  <C++ Source>   modules/multiplayer/scene_rpc_interface.cpp:294 @ _process_rpc()

Removing the annotation fixes the problem.

Steps to reproduce

  1. Open the Minimal reproduction project
  2. Run the projects as 2 instances
  3. In the first instance press "Host"
  4. In the second instance press "Join"
  5. In the first (host) instance press "Send message"
  6. Observe errors in the debugger.
    E 0:00:04:0771   _process_rpc: RPC - 'Node(Main.gd)::client_print_array': Cannot convert argument 1 from Array to Array
    <C++ Source>   modules/multiplayer/scene_rpc_interface.cpp:294 @ _process_rpc()
  7. Modify the Main.gd script by removing type annotation on line 28
  8. Repeat steps 1-5
  9. Observe expected messages in the log output
    Host array: [1, 2, 3, 4]
    My array: [4, 3, 2, 1]

Minimal reproduction project

RpcIntArrayIssueExample.zip

ShlomiRex commented 1 year ago

Can confirm this is still hapening on 4.1, windows

akien-mga commented 1 year ago

4.1 hasn't been released, can you be more explicit?

ShlomiRex commented 1 year ago

4.1 hasn't been released, can you be more explicit?

Sorry, the commit is 8d501a2dc31f3bef6d5a7f6b0d060c8915082011

dalexeev commented 1 year ago

I think the reason is the same as #76841: binary serialization does not currently support typed arrays, so type information is lost in multiplayer.

Text serialization:

https://github.com/godotengine/godot/blob/eb86dabee07e8dfce3b06cbd557b50b74afd3d6c/core/variant/variant_parser.cpp#L1927-L1958

Binary serialization:

https://github.com/godotengine/godot/blob/eb86dabee07e8dfce3b06cbd557b50b74afd3d6c/core/io/marshalls.cpp#L1590-L1609

jonathaneeckhout commented 11 months ago

@dalexeev , @akien-mga , I can still reproduce this one on v4.2.

This is causing an error:

@rpc("call_remote", "any_peer", "reliable")
func characterclasscomponent_sync_class_change(n: String, c: Array[String]):
E 0:00:29:0132   _process_rpc: RPC - 'Node(sync.gd)::characterclasscomponent_sync_class_change': Cannot convert argument 2 from Array to Array
  <C++ Source>   modules/multiplayer/scene_rpc_interface.cpp:290 @ _process_rpc()