Godot Version
4.7.stable.official
Question
I’m designing a game where creatures will need to inherit a variety of tags from their parent class. I don’t want to use _init() to modify the tags because it will create a lot of unnecessary lines. I tried writing it like this:
class mammal:
var name := "None"
var tags = ["animal", "mammal"]
func _init( newName ):
name = newName
class dog extends mammal:
var tags = ["animal", "mammal", "dog"]
This returns the error “The member “tags” already exists in parent class mammal.” If I remove the word “var” on the last line, I instead get “Unexpected identifier “tags” in class body.” So how can I accomplish this?
I know this seems like a simple question, but I want to solve it programmatically, because this system needs to be extremely scalable. Basically, I want “tags” in “dog” to overwrite “tags” in “mammal.”
If you don’t need to edit these tags at run time then you can return them as a function.
class mammal:
var name := "None"
func tags() -> Array[String]:
return ["animal", "mammal" ]
func _init( newName ):
name = newName
class dog extends mammal:
func tags() -> Array[String]:
return ["animal", "mammal", "dog"]
Though there may be a better solution, this question has some XY Problem potential, could you explain more big picture about what you are actually trying to do?
Well, the point is to check whether a creature has certain traits. For example, a creature with the “fire” tag would take extra damage from weapons with the “water” tag. These traits do need to be modified at runtime, as some individual creatures may have traits different from their class. For example, there might be a dog named Fred which has the “fire” and “armor” tags because of unique characteristics.
Should you make these resources? Generally a split between data and code is good, and currently by using only the RefCounted (aka class within a script) you are relying on code for data.
# in a new `tagable.gd` file
extends Resource
class_name Tagable
@export var name: String
@export_flags("Animal", "Fire", "Armor") var tags: int = 3 # starts with animal and fire
You can create new resources in the filesystem panel and add this resource type as a variable of any other script needed to be loaded later. You can still extends Tagable to add new functionality where needed, your examples thus far do not need to extend from the base type though.
Okay, this looks really cool, thanks!