Aggregating Extended Class Properties Only

Godot Version

4.2.1

Question

So I’m planning to make a function that changes the class (e.g. PlayerScoreCard) into a builtin type like an array or dictionary. Essentially to pass around a light weight state of the class that isn’t directly referencing the main class.

I know I can do this by making a manual list of properties into the container variable, but I’m hoping this could be done programmatically. I know I can get a list of properties, but I want to filter that into a list of properties that exist on this new class only. I think I can do this by appending the property name with a prefix or suffix to filter against, but I’m wondering if there is a better way?

Thanks!

This is the closest I got:

const prop_exclude_list : Array[String] = ["score_events"]
func as_dictionary():
	var script = get_script()
	var props:Array = script.get_script_property_list()
	props.pop_front() # removes hidden script property refernce
	props = props.filter(func(dic:Dictionary): return not prop_exclude_list.has(dic.name) )
	print(props)
        ...

You can get the properties introduced by the script, but the first prop seems to reference the script itself. so pop that off
Then I may have some properties that I dont care about so I can filter those out.

This has eveything I need, now I’m worried about whenever I make changes to the class the clients that reference this dictionary may interact with it in the wrong mannor.

I think I can define enums and make sure I use them so when I change the class it throws an error on the clients…

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.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.