I found a solution:
extends MultiplayerSynchronizer
class_name ScoreCard
static var res:String = "res://src/match-manager/score_card.tscn"
static func new_scorecard(id:int)->ScoreCard:
var score_card: ScoreCard = load(res).instantiate()
score_card.card.player_id=id
return score_card
class Card extends Resource:
var active : bool = true
var player_id : int = -1
var score : float = 0.0
var rank : int = 0
var card : Card = Card.new()
signal updated(card:Resource)
func _ready():
setup_replication_config()
delta_synchronized.connect(_on_delta_synchronized)
func setup_replication_config():
var props =get_local_filtered_properties()
for prop in props:
# use relative path
var prop_path : String = ".:card:" + prop.name
replication_config.add_property(prop_path)
replication_config.property_set_spawn(prop_path,true)
replication_config.property_set_replication_mode(prop_path,SceneReplicationConfig.REPLICATION_MODE_ON_CHANGE)
func get_local_filtered_properties() -> Array:
var script = card.get_script()
var props:Array = script.get_script_property_list()
props.pop_front() # removes hidden script property refernce
return props
func get_card() -> Card:
return card
func _on_delta_synchronized():
updated.emit(card)
...
So instead of using an array or dictionary i used an inner class.
This allows me to encapsulate the things I wish to transport in a class that will update everywhere I use it and avoid access incorrect properties at runtime. I can also use the same get script properties on the inner class just as before.