I've been working out the design for a data driven system for a game economies using tags. This is largely inspired by Entity Component Systems (ECS) and the principle of “favor composition over inheritance”. The general idea is that for all entities in the game, they are defined by tags. Tags may have a corresponding component, but not necessarily. Tags are just descriptors which add attributes or behaviors to an object. Tags can also represent a collection of other tags (Tag sets). The tags an entity contains are all unique (stored in a dictionary, keyed by tag name), so if two tag sets are assigned to an entity and both tag sets contain a shared tag, that shared tag is included once due to how dictionaries data structures work.
I think the advantage is that by defining tag sets, you automatically get inheritance while also avoiding the diamond problem of double inheritance. It also gets around the general problem of classification / abstraction for ambiguous cases. For example, is a platypus classified as a bird or a mammal? If we have to fit it into a generalized class, it's hard. But if we just use tags to define it, we just don't know or care about what abstract class it fits into. Tags can also be added or removed from an object. If we have a lump of iron ore, and it includes the tags “Iron” and “Ore”, and then we process it in a smelter, then all the smelter needs to do is remove the “Ore” tag and it now becomes just “Iron”.
If you have a robustly defined tagging system for objects, you can also query an object to see if it contains a particular tag. Suppose you have a crafting recipe to a hammer which requires a stick and a hammer head. The recipe template might look like this: {"Stick", “Wood”} + {["Metal", “Wood”, "Stone]} => Hammer
So, the “Wood” tag is a tag assigned to all types of wood, and similarly with “Metal” and “Stone”. You could supply ash wood for the stick and copper for the hammer head, and the crafting result would be a copper hammer made of ash wood, and you could combine the properties of both ash and copper to define the final attributes of the crafted hammer. The materials used to craft an item affect the properties of the crafted item.
Someone might say, “Wait a minute, isn't this still just an entity component system? All you are doing is replacing the word ‘component’ with ‘tag’ and rebranding it as something new! It's not new and you aren't original!”
Sort of, but not quite. At the most primitive level, tags can be defined as simply a collection of strings. Some tags can just be collections of other tags. Not all tags have a 1:1 mapping between the tag and a component, though it would probably be common to pair tags with components. If all of your game objects are defined as collections of tags instead of a predefined collection of components or object inheritance hierarchy, then you can define all of your objects in a plain text file using JSON, CSV, XML, or some other data warehousing format. If you want to change the properties of an object, or create a new object, all you have to do is change the data file instead of changing classes or components. This would mean you can update your game economies, crafting systems, and add new items without necessarily recompiling, repackaging, and redistributing binaries to customers.
I'm sure I'm not the first person to come up with this, so I'm curious to know how common something like this is and how other people have designed similar systems. If I look at “Age of Wonders 4”, it appears that they have a tagging system of some sort on the backend, but I am not sure if its used for crafting economies. What are your thoughts? Are there any oversights on my part?