Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
It’s hard to find a developer who has never heard about enums. But do you use them correctly? Let’s find out.
Correct naming
The naming is one of the important things in development. Jokes aside. The best name for enum should reflect what it consists of. The good names are short and self explanatory: WindowName, EntityType, etc. It’s that simple. There is no reason to add ‘s’, or ‘enum’ or call it ListOfEntitiesType. Brevity is the soul of wit. And don’t forget to use namespace, so your Enums will be tidly separated by them.
What can be the values of the enum members?
By default it’s int and I recommend sticking with it. But sometimes there is a requirement to do something different and for the value of enum members you can use any integral numeric type you like: bytes, int’s, long’s and even shorts.
Correct indexing
Many developers use invalid indexes as default. For example -1 or int.MinValue, or -99999. These things are annoying. Let’s look at the example: imagine you have an enum DamageType and class Damage, which you send somewhere to draw some damage.
enum DamageType { None = -1, Range = 0, Magic = 1, Close = 2, } class Damage { public DamageType Type { get; private set; } public int Amount { get; private set; } ….. }
If you create this class with an empty constructor you will get these default values: Type is DamageType.Range and Amount is 0. Which is not logical, since default of DamageType will be None. Unless your goal is different.
Useful snippets
How to iterate through all elements of enum? Easy:
var allElementsOfEnum = Enum.GetValues(typeof(MyEnum));
From that point we can easily get random elements of enum. Or create one entity of each type.
And this one is a bit complicated but interesting at the same time. Imagine that you are working over a real world animal simulator. You have an urchin that lives at ground and can barely swim, you have a bass-fish that lives in water and barely can live on the surface:
public enum AnimalHabitat { None = 0, Ground = 1, Water = 2, }
...and then comes a game designer and he asks you to add a turtle that lives both on the ground and underwater. We could add another element to the enum Amphibian that equals to 3. And then we will need to check animal habitat like this:
If (animal.habitat == AnimalHabitat.Ground || animal.habitat == AnimalHabitat.Amphibian) { //do the ground stuff } ... if (animal.habitat == AnimalHabitat.Water || animal.habitat == AnimalHabitat.Amphibian) { //do the water stuff }
And then each time we will add intercrossing behaviours, we will need to modify our code again. And the problem is that it interferes with the SOLID principle. With the S button to be exact, that says that there should be only one reason to change the class. And I don’t see any reason to change the behaviour of ground or water habitat here. We just need to check if Amphibian has properties of ground behaviour or of water behaviour.
So let’s try another way!
[Flags] public enum AnimalHabitat { None = 0b_0000_0000, Ground = 0b_0000_0001, Water = 0b_0000_0010, Amphibian = Ground | Water, //that will be 0b_0000_0011 }
And then you will need to recall some magic. The magic of bitwise operations.
var habitat = AnimalHabitat.Amphibian; If (habitat & AnimalHabitat.Ground == AnimalHabitat.Ground) { //do the ground stuff } ... If (habitat & AnimalHabitat.Water == AnimalHabitat.Water) { //do the water stuff }
Keep in mind that in this situation you can have 8 flags (including zero which will stand for None as we made a deal previously). And it will give you 256 combinations.
Conclusion
As we can see the Enums can be a powerful data structure that can help build up logic of a game you are working on. And proper usage of enums will not only benefit in the process of development, but it will help support game in future.
You May Also Like