How to add "traits" to a to a type?

By traits, I’m talking about chunks of code that would modify a type to give it some uniqueness. So let’s say I have a type called Unit, and I make a new Unit called Pyro. The Pyro, unlike a more generic Unit such as Brute, or Swordsman, has the special trait of igniting every enemy it attacks. Since the Pyro is the only Unit that can do this, it wouldn’t make any sense to put the code for igniting enemies in the base Unit type class, and I could have potentially hundreds of traits, some which might increase the Unit’s defense by five, and some much more elaborate. Each trait would also need to hold info for which other traits it interacts with or conflicts with, so maybe each trait should be a type? I’m simply asking for the best way to execute this so I don’t use my own stupid logic to do something dumb. Think of traits in a Rogue-Like game, or unit upgrades in the newer Civilization games. Thanks.

It is good that you defined your meaning for the use of the word traits, because in other languages that has a meaning quite different than your intent, expressing a paradigm not directly supported in C#, and of no importance to your question.

The subject threatens to get too deep for a post. Your asking about object design, and it can become quite a study. In your post you ask if each trait should be a type. By that I take you meaning to be a class. A class has a type, and some types are structs while others are built in.

If Pryo has a unique behavior for attacking, you could implement that from an abstract method named Attack(), but you’d have to know that all attacks would suffice from such a call. If there were magical Units that could cast spells, they may not be characterized so generally as an Attack() function, and non magical Units wouldn’t cast spells. I give this example notion to show how this can influence a design. You wouldn’t want Unit to have to account for all possible interfaces itself, many which may not be applicable and taken together comprise considerable knowledge of the derived class that Unit should not bother to have in the first place.

This may be why you’ve asked about making these concepts their own classes (traits should be a type). You’ve considered it may be smarter to consider the component design pattern as a means of building character behaviors and characteristics. That is likely best.

Consider how Unity uses components to enable the configuration of a GameObject to be a simple sphere or a complex mesh, to have children with related colliders and to attach code. I don’t suggest your character behaviors and characteristics derive from MonoBehaviour, you probably don’t want the weight or need its services, but you may require Unit to accept components of your design which define the character in modular plugin attachments, as components do, to build up the unique design of a character.