Make Exported Array Immutable

Godot Version

4.6.1

Question

I have been using @tool scripts recently to make development easier, and it has been going great but there is one thing I am trying to do that I am unable to figure out.

My resource’s purpose is to store a list of integers (PackedInt32Array) which correspond to UID’s of other resources (These are custom UID’s opposed to the ones for files that Godot does itself.)

Now to make checking the arrays values easier I wanted to have a separate array visible in the inspector instead of the real one that instead of just showing the numbers shows the name of each corresponding resource, which I have done like so;

@export var card_names : PackedStringArray:
	get:
		var list : PackedStringArray
		var temporary : CardData
		for card : String in ResourceLoader.list_directory("res://Resources/Cards"):
			temporary = ResourceLoader.load("res://Resources/Cards/" + card)
			# 'cards' is the real array with the uids used at runtime 
			if temporary.uid in cards:
				for i : int in range(0, cards.count(temporary.uid)):
					# the 'cards' list can have
					# duplicates so add a name for each 
					list.append(temporary.name)
		return list

Which does work, but it makes the property have the reset icon, ability to add / delete elements, resize it and re-order them.

When looking at Property Usage Flags I see it describes being able to make arrays static and constant which would seemingly achieve what I want, as even though the name array doesn’t change when you try in the inspector I would still rather the buttons not be there.

But I am confused as to how to implement this, at first I tried _validate_property() but that didn’t seem to work as it instead makes it not show up in the inspector…

func _validate_property(property: Dictionary) -> void:
	if property.name == &"card_names":
		property.usage |= PROPERTY_USAGE_ARRAY
		property.class_name += ",static,const,numbered"
	return

…and as it described using _get_property_list() I tried that also…

func _get_property_list() -> Array[Dictionary]:
	var properties : Array[Dictionary]
	properties.append({
		&"name": &"card_names", 
		&"class_name": &"static,const,numbered", 
		&"type": TYPE_PACKED_STRING_ARRAY, 
		&"usage": PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE | PROPERTY_USAGE_ARRAY, 
		})
	return properties

…but I couldn’t get that to actually change how it was exported either, it remained the same.

So how do you properly set the usage flags so the array counts as ‘static’ and ‘const’ as described in the usage flags description?

Thanks.

Try or-ingPROPERTY_USAGE_READ_ONLY in _validate_property()

1 Like

I thought I had tried that… I guess not, feel a bit daft now lol, Thanks!

1 Like