I always had problems to organize game code in a nice and readable structure. With that, I decided to write down the guidelines that I use when developing my games.
These rules are not gold but are just simple guidelines that I use on a daily basis to write my code.
If you believe another method is better, in that case, go ahead with your system. The important thing here is to have some sort of guidelines to organize game code and give it a nice structure.
Order of items in a class:
I use the following order when I have to write something inside one of my class.
Within a class, struct or interface:
- Constant Fields
- Fields
- Constructors
- Finalizers (Destructors)
- Delegates
- Events
- Enums
- Interfaces
- Properties
- Indexers
- Methods
- Structs
- Classes
Within each of these groups order by access:
- internal
- protected internal
- protected
- private
Within each of the access groups, order by static, then non-static:
- static
- non-static
Within each of the static/non-static groups of fields, order by readonly, then non-readonly :
- readonly
- non-readonly
An unrolled list is 130 lines long, so I won’t unroll it here. The methods part unrolled is:
- public static methods
- public methods
- internal static methods
- internal methods
- protected internal static methods
- protected internal methods
- protected static methods
- protected methods
- private static methods
- private methods
How to divide and organize game code:
You can use #region if you’re coding in C# or a similar keyword in other languages. The main goal of the region keyword is to divide your code into sections in order to find faster what you’re looking for inside one of your classes and to better divide the class into sections.
Example:
public class myClass { #region FIELDS Your fields here #endregion #region PROPERTIES #endregion #region MONOBHEAVIOR #endregion ETC ETC }
If you use region you’ll also have the ability to collapse entire regions of your code.
One class for all the constants:
I used to group all the constants that can be used over my code into one single class called Constants:
public static class Constants {
public struct SceneIds { public const float GRID_PADDING = 20; } public struct Tags { public const string TILE = “Tail”; } }
Doing so will have huge advantages such as, if you have to change something, that change will automatically be reflected everywhere in your code.
Take the Tag in the example before. If you want to change it, you don’t have to find all the places in your code where the tag is used, but just change the tag in the constant class and the tag will be updated everywhere it’s used.
Use properties over field variable
Examples from StackOverflow:
1.) Immutable property (passed into the constructor, or created at construction time). In this case, I use a field variable, with a read-only property. I choose this over a private setter since a private setter does not guarantee immutability:
public class Abc { private readonly int _foo; public Abc(int fooToUse) { _foo = fooToUse; } public int Foo { get{ return _foo; } } }
- POCO variable. A simple variable that can get/set at any public/private scope. In this case, I would just use an automatic property.
public class Abc { public int Foo {get; set;} }
3. ViewModel binding properties. For classes that support INotifyPropertyChanged, I think you need a private, backing field variable.
public class Abc : INotifyPropertyChanged { private int _foo; public int Foo { get { return _foo; } set { foo = value; OnPropertyChanged("_foo"); } }
4. Private properties can be helpful in case you want to use the lazy instantiations:
private string _password; private string Password { get { if (_password == null) {_password = CallExpensiveOperation(); } return _password; } }
Or if you want to be more elegant:
private Lazy _mytype = new Lazy(/* expensive factory function */); private MyType MyType { get { return _mytype.Value; } } // In C#6, you replace the last line with: private MyType MyType => _myType.Value;
Working with field and properties in your game engine (Unity example).
Most game engines give you the possibility to expose your public variables to the game editor in order to have the possibility to quickly change their values at run time.
In Unity it’s something like this:
public class MainPlayer : MonoBehaviour { public string myName; // Use this for initialization void Start () { Debug.Log("I am alive and my name is " + myName); } }
This code creates an editable field in the Inspector labeled “My Name”.
The problem here is that public strings are accessible by every class in your code because it’s marked as public. Unless this is what you want, I tend to not use public fields if not strictly necessary, and even if I have to, I prefer to use getters and setters to expose their values.
To solve this problem, most engines give you the possibility to create private fields and expose them to the editor. Example in Unity c#:
Public class Test : Monobehavior { #region FIELDS [SerializeField] private GameObject _canvas; [SerializeField] private GameObject _gridContainer ; #endregion #region PROPERTIES public GameObject Canvas { get {return _canvas;} } #endregion }
In Unity, for example, we can expose a private field to the editor with the [SerializeField] keyword, and thanks to it we no longer have to use public fields.
Example class:
Here you can find a small class with a recap of all the things that I wrote before, or if you prefer, here the GutHub repo.
public class SpriteSheet : MonoBehaviour { #region FIELDS //Exsposing private field to the Unity editor [SerializeField] private GameObject _canvas; //Used for the lazy instantiations private string _password; #endregion #region PROPERTIES //Simple Properties creation public int Foo { get; set; } //Exsposing private field used by the editor example public GameObject Canvas { get {return _canvas;} } //Lazy instantiation example private string Password { get { if (_password == null) { _password = this.GeneratePassword(); } return _.password; } } #endregion #region MONOBHEAVIOR // Use this for initialization void Start () { } // Update is called once per frame void Update () { } #endregion #region PUBLIC METHODS //Insert here your pubblic methods #endregion #region PRIVATE METHODS private string GeneratePassword() { return Constants.Secrets.password; } #endregion }
Conclusion:
These rules are very simple, but thanks to them, I can quickly organize game code and use the same rules all over my project. Furthermore, using order in scripts allows you to be more efficient and have more readability in code.
If you have some suggestions or some best practices that you want to suggest to other readers please write them in the comments or send me a private message and I will add your content to the article.
Update: naming convention:
Was brought to our attention that the internal standard of the .NET CoreFX team insist on using the underscore-notation without giving any insights as to why. However, if we look closely to rule #3 it becomes evident that there is a system of _
, t_
, s_
prefixes that suggests why _
was chosen in the first place.
- We use
_camelCase
for internal and private fields and use readonly where possible. Prefix instance fields with_
, static fields withs_
and thread static fields witht_
. When used on static fields,readonly
should come afterstatic
(i.e.static readonly
notreadonly static
).- We avoid
this.
unless absolutely necessary.
I find interesting the way you organized your code. And it is indeed very important to use some kind of code organization.
My question is why not use something already stablished and with tools to help as StyleCop’s recommended coding styles?
http://stylecop.soyuz5.com/StyleCop%20Rules.html
Thank you for the article.
Thanks for the link, It’ll probably take a week to understand all the rules in the documents that you send. I just needed a simple and quick way to organize my code. Btw when I’ll have time I’ll take a look at that documents to see if I can find something to improve the way I organize my code.