Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Gamasutra: The Art & Business of Making Gamesspacer
arrowPress Releases







If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Enums in C# and how to cook them

by Tymur Koshel on 06/18/21 10:02:00 am

The following blog post, unless otherwise noted, was written by a member of Gamasutra’s community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

 

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.
 


Related Jobs

Insomniac Games
Insomniac Games — Burbank, California, United States
[07.23.21]

Technical Artist - Pipeline
Insomniac Games
Insomniac Games — Burbank, California, United States
[07.23.21]

Engine Programmer
Legends of Learning
Legends of Learning — Baltimore, Maryland, United States
[07.23.21]

Senior Gameplay Engineer - $160k - Remote OK
Bytro Labs GmbH
Bytro Labs GmbH — Hamburg, Germany
[07.23.21]

Senior Product Owner / Live-Ops Owner (f/m/x)





Loading Comments

loader image