Eliminating Magic Numbers

With the Dream Build Play competition nearing a close, I’m sure everyone is busy with tweaking their game to make it as fun as possible. Of course, this can be quite the monumental task if you’ve got a large code base with “magic numbers” all over the place.

What’s a magic number, you ask? A magic number is any number in your code that doesn’t have a concrete reason for being that number, and could be changed without changing the meaning of that number. For example, your character’s velocity equation might have something like this:

Velocity += 9.81f * Vector3.Down * elapsedSeconds;

That’s obviously an equation to add gravity to your velocity. Who’s to say that gravity is 9.81 though? Your world will most likely have different units, you might change these units over time, or, worst-case, you might want to change your world’s gravity late in production and have to track down all of the places where 9.81 is used. Now, you could search through your entire project for this number and change each instance…but then what happens when you need to change your overall fade speeds? How about the delay after enemy attacks?

One solution I’ve found (and enforced on my team’s DBP entry) was to have a static constants class. This class is very simple - it just contains a bunch of constants. You can even organize them by placing more static classes within that class (or by using namespaces). For example, I ight have something like this:

Then, whenever I need to make use of gravity, I can just reference the Constants.World.Gravity variable. That way, if I need to make changes, I can do it very easily.

This is especially helpful when playtesting. If you have a good tester (and especially if you have another screen/machine to test on), you can sit them down to play and have them comment on anything that doesn’t feel right. Maybe the attack isn’t firing fast enough, perhaps the enemies are getting too strong too fast. You can stop their game, change the AttackDelay and DifficultyRampFactor variables, recompile and have them playing again in just a couple minutes.

As an extension of this, you can have all of your constants stored in a file, and load them all upon starting your game. Then you don’t even have to recompile between tests!

Leave a Reply