Skip to content

Implement sending custom structs as RPC parameters #6216

@TheYellowArchitect

Description

@TheYellowArchitect

Describe the project you are working on

Literally any serious game, which will need custom structs (Resources) made of primitive types

Describe the problem or limitation you are having in your project

Basically, I have custom resources which exist on both server and client, yet the network cannot parse them. Cannot convert from Object to Object even though the type and its variables is obvious on both sides. Look at this code sample from the MRP (slightly tweaked):

class_name DeckData
extends Resource

@export var mainDeck: PackedInt32Array
@export var dungeonDeck: PackedInt32Array
@export var equipmentDeck: PackedInt32Array
func _process(delta: float) -> void:
	if (multiplayer.is_server() == false):
		return	
	
	if (Input.is_action_just_pressed("ui_accept")):
		var new_card_data = DeckData.new()
		new_card_data.dungeonDeck = PackedInt32Array([0,2,6,8])
		new_card_data.equipmentDeck = PackedInt32Array([2,3,6,10])
		new_card_data.mainDeck = PackedInt32Array([0,1,1,5])
		rpc("receive_deck", new_card_data)

@rpc func receive_deck(received_deck: DeckData) -> void:
	print(received_deck.mainDeck)

Since both server and client have the same resources, encoding/decoding should happen automatically.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Basically makes netcoding structs easier. No manual encoding/decoding. No boilerplate.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

See MRP and code sample above. It should work as it is.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Example for the above sample code

func _process(delta: float) -> void:
	if (multiplayer.is_server() == false):
		return	
	
	if (Input.is_action_just_pressed("ui_accept")):
		var new_card_data = DeckData.new()
		new_card_data.dungeonDeck = PackedInt32Array([0,2,6,8])
		new_card_data.equipmentDeck = PackedInt32Array([2,3,6,10])
		new_card_data.mainDeck = PackedInt32Array([0,1,1,5])
		rpc("receive_deck", new_card_data.dungeonDeck, new_card_data.equipmentDeck, new_card_data.mainDeck)

@rpc func receive_deck(received_deck1: PackedInt32Array, received_deck2: PackedInt32Array, received_deck3: PackedInt32Array) -> void:
	print(received_deck1)
        print(received_deck2)
        print(received_deck3)

The problem is on nested structs/resources. Nested == using structs/resources inside, instead of purely primitive types (PackedInt32Array on above example).

Is there a reason why this should be core and not an add-on in the asset library?

Convenience, since much of netcoding is automated thus far anyway (e.g. MultiplayerSpawner)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions