Go to Top

How you write code can make it legible and easy to share or impenetrable and a great alternative to cross word puzzles if you like a challenge and need to debug your code 3 months after writing it. Nothing's perfect, here's one interpretation of best practices...

Motivation

You should read this article if you are new to programming or new to the C#, Unity Script and Unity environments and want to know about coding structure and variable naming conventions.  You will learn (/hear me rant about)

  • Why we have variable naming conventions and why they matter
  • How and where to declare variables
  • Keeping your code DRY
There's really just one lesson here - write code that does what it says so that you and everyone else can just understand it by reading it.

Warning: this is like discussing religion or politics

There are very different opinions on naming conventions.  This article represents the .NET standard (with Unity modifications and a few personal opinions).  About the only wrong thing in naming conventions is not to have one, to have one that's half baked, or to have one that is opposite to a commonly practiced convention.

NamingConventions

It is very tempting when you start to program to just call your classes, your variables, your properties and your methods by whatever name you like and using any combination of capital letters, underscores and other paraphernalia that comes to mind.  However naming conventions exist for a reason - and it isn't us pedants just wanting to dictate how things are done.  Naming conventions do this for you:

  • Reduce the number of coding errors you make
  • Make your code more readable to someone else who looks at it
  • Make your code make more sense to you when you come back to it after a month or two
  • Reduce the need to create masses of documentation by self documenting your code

Identifier Names

Make your identifier names meaningful, even if it makes them long.  If you use a decent editor like Visual Studio or MonoDevelop you will hardly ever type them all anyway - so do yourself a favour and don't write code like this:

var p = transform.position;
for(var i = 0; i < ar.Length; i++)
{
    p += ar[i];
}

Does this make more sense to you?

var endPosition = transform.position;
for(var step = 0; step < pathStepVectors.Length; step++)
{
       endPosition += pathStepVectors[step];
}

When you declare a boolean variable give it an auxilliary verb so that it has more meaning.  For example alive is less useful than isAlive which clearly shows that your are sampling something that has a present value relevant now; activated could imply that something was ever active or that it was active right now while that question would not arise if you called your variable isActivated or hasActivated.

Capitals & Why They Matter

Ok so first here's the rules:

  • Class names always start with a Capital letter
  • Therefore, because classes and scripts are closely related in Unity, script names start with a Capital letter
  • Public and protected fields of a class start with a lower case letter*
  • Public and protected properties of a class start with a Capital letter, but Unity regularly uses lower case itself, so you can just adopt the rule:Properties and fields start with a lower case letter
  • Methods or functions always start with a capital letter
  • Private properties and fields of a class start with an _
  • Parameter names start with a lower case letter
  • All identifiers are written in camelCase - where the first letter of every new word after the first one is a Capital letter.

* .NET conventions say that any publicly accessible member of a class should start with a Capital letter - be it member, property or field.  Therefore you will often encounter strange things in Unity when integrating with .NET libraries as the convention is different.  I've finally opted for using Unity conventions in my code, but there will sadly be some inconsistency no matter which approach you take.

Camel case is great as itReallyMakesReadingIdentifiersFarMoreEasy - thanifyouwrotethemlikethis - and it is far_less_cumbersome_than_using_underscores.

Right so straight away I know that:

  • thisVariable = 5 // does not call any code that has any effect, because it starts with a lower case letter.
  • ThisIdentifier.thisValue // is probably a static variable (though it could be the value of something returned by a property - heh nothing's perfect) - I should be able to recognise ThisIdentifier as one of my classes

When I write a function that takes parameters I often want to store them in variables in my class - it's good to be able to have private variables start with a _ because then there isn't a naming conflict (and of course, I know that they're private!)

function SetTarget(targetPosition : Vector3)
{
     _targetPosition = targetPosition;
}

Is clearer and more obvious than prefixing the variable targetPosition with this. every time we need to make a distinction - likely to lead to problems that.  In fact it's also usually a good idea to make parameter names more obvious too:

function SetTargetPosition(newTargetPosition : Vector3)
{
     _targetPosition = newTargetPosition;
}

Hungarian Notation

The standard way to name variables in C++ was always to use Hungarian notation so you can work out what type the variable actually refers to - it's kind of more important in C++, but not much and it lpszMakes szYour m_lpstrCode somewhat hard to read as you have to skip past a whole usBunch of characters to get to the meaning, and in any case do you know if a lpszVariable is actually compatible with an lpstrVariable?  It's not obvious that it is.  That and half the time you can't remember whether bByte is the right notation or is that bBoolean - hang on that's sFloatingPoint for a single isn't it and fBoolean for flag? Don't even get me started on arrays and other higher level collection structures.

It is not recommended to use hungarian notation, nor is the distracting m_inFrontOfAllMembers very clear is it?  Don't use it.  A variable is a variable - plain and simple, a private variable is far more legible as _variable and readability is actually more important than variable types to the meaning of your code.

Where and How To Define Variables?

Best practices currently dictate that variables in a function should be defined as close as possible to their usage, being defined as they are initialised is the best choice if that is possible.

Also remember that variables in a function have been allocated on the stack and are not initialized with their default value so you should always ensure that they are initialised before they are used or allocate the default value yourself.

In C# there is a lot of debate around the use of var to define a variable in a function.  var imputes the type of object from the thing that it is set = to.  So

  • var x = 0; //x is an int
  • var x = 0f; //x is a float
  • var x = new Dictionary<string, float>(); // x is a dictionary of string to float
It's this last example that is so compelling to me.  I would of course never call a dictionary x but I think this is far more legible:
var lookupWeight = new Dictionary<string, float>();

Than this alternative:

Dictionary<string, float> lookupWeight = new Dictionary<string, float>();

It takes me a moment to even find the variable name in there, especially if it's buried in a bunch of other code and definitions.

One school of thought is that var should only be used for prototyping and that you aren't a proper programmer if you use it otherwise.

The other school, of which I am an evangelist (did you guess?), says that actually being able to read your code quickly is the most important part of the creative process and debugging process.  Any accidental errors, like initialising something you wanted to be a float with an integer, are immediately caught in the compiler anyhow.

In fact when I'm calling a function to return a variable value then I really don't need to remember what the actual type is that's coming back from it is - so long as I (and intellisense) know what properties, methods or fields it has and whether I can access it with array semantics!

var newEnemy = CreateEnemy("Bob", EnemyType.pedanticProgrammer);
newEnemy.EvolveNow();  //Intellisense knew what newEnemy was
                          //I don't need to

This becomes even more important when using Linq or anonymous classes because it can actually be very hard to work out what the return value is, even though you (and again, intellisense) know exactly how to use it.

Where do you put variables in a class?  Well I put the public ones at the top and the private ones close to where they are first defined and used.  I don't do scrolling when I'm concentrating and I like to see the public variable interface of the class closely tied together.  I will also put properties first, just after fields.

Subclasses and Enums

So you can define helper classes inside other classes or in global scope - if this class is ONLY going to be use in reference to another class or its functions then define it inside - Unity 3.x doesn't support namespaces so anything else will just end up with clutter.  If you define subclasses then they should come at the bottom of your outer class definition.  Remember to use #regions to simplify your file structure.

#region Is your friend for logical groups of code

//Logical block of code

#endregion

The argument for Enums is slightly less clear - simply because you will probably end up typing the name of them when you pass them as function parameters or set field or property values.

var easedPosition = Easing.EaseInOut(currentTime, Easing.EasingFunction.LinearEasing);
Because of our captial letter naming convention it is obvious that Easing is a class and EaseInOut must therefore be a static function defined by that class

The answer in my case is to define enums in global space if they are used outside of a class often and if they are defined in the class, I think about how the final code will read and try to do something like this:

//Either:

var easedPosition = Easing.EaseInOut(currentTime, EasingFunction.Linear);

//Or:

var easedPosition = Easing.EaseInOut(currentTime, Easing.Function.Linear);

In the latter, Function makes sense because externally it will be preceded by Easing and internally it's fairly obvious that this is an easing class.

Don't Be Wet Be DRY

DRY stands for Don't Repeat Yourself and it is a mantra that should be playing in your head all the time you are writing code.  Cut & Paste can be the enemy of productivity.  You write some code,  you cut and paste is half a dozen times and everything is dandy - right up to the point where you decide to refactor or fix a bug and then you have to find all of the places you pasted that code - in the end you will forget one and the bug will go unnoticed for ages.

Bite the bullet and write a function if you are going to do exactly the same thing in multiple places.  Try to organise where these functions live - create a global static class and put general utility functions in there.  The effort of thinking about a function can be useful too:

  • Pretty much all coding involves holding only a part of the whole structure in your head at a time. When you are writing code and just type in the name of a function in line and move on,  then fill out that function afterwards.

    Black box in other words - don't even worry yourself about how it will work until you fill it in. Sure you may have to add some parameters, but pretty quickly you will find you are building useful function prototypes as you code. Some refactoring tools will actually just build these functions out for you - working out all of the parameter types and names by inferring them from the variables you passed to the non-existent function.

  • Thinking about functions and the parameters helps you spot the theoretical mistakes in your architecture - you will write better code.  

    Always try to write a function that is efficient but has the maximum flexibility - the whole of your code is effectively the software equivalent of Frankenstein's monster - these functions are going to be the beautiful elegant bits!

Conclusion

The most important thing to do is be consistent, concise but readable in your identifier definitions and always indent your code.  If you've indented more than 4 times, consider refactoring to multiple functions.  Your code should be as DRY as possible.

The conventions presented here represent my view on the current recommendations from .NET and Unity - feel free to argue, rant, rave and call me names in the comments section.

,

18 Responses to "Coding Conventions"

  • ffyhlkain
    November 14, 2012 - 11:58 pm Reply

    An excellent article! I’ll use it to show our fresh and new student developer why coding conventions aren’t bad (or as he may think just for that I could argue about his code).

    Thx!

  • EvansGreen
    November 19, 2012 - 9:09 pm Reply

    Great article, thanks for taking the time to write it down, it kind of rewrote the programming() methods in my brain in a more consistent, concise, and readable way :P

    Cheers!

    E.

  • Tim
    November 20, 2012 - 3:17 pm Reply

    Great article, I’ve seen way to much code that has no standard at all…

    A few thoughts:
    I don’t think it’s necessary to use “_” in front of private variables, for a lot of people, reaching for the underscore key, takes away from a good typing flow. Just start use Camel case on all private variables and Pascal case on all public.

    I actually think it’s cleaner to use the “this” keyword, than an underscore:
    Public void SetTarget(Vector3 targetPosition)
    {
    this.targetPosition = targetPosition;
    }

    Code order:
    I think it’s easier to see all the variables/fields at the top in an order something like this:
    Static variables
    Public Fields
    Private variables
    Properties
    Methods

    You mentioned that for class private variables you put them “close to where they are first defined and used”. That could be a cause of scrolling around trying to find it, if they are all at the top, you know right where to go. There is also a school of thought that says a private variable should be touched by most methods in the class, otherwise that is a sign your class is doing too much and another class may need to be created.

    One thing you didn’t mention is booleans. A good convention is to always start them with an action. A variable called “isDead” makes more sense than “dead”. You instantly know it’s a bool by reading it and reading your code will flow better. Just don’t use negative bools like “notDead” that can start to get confusing.

    These are just a few things I prefer and have found work well. Keep up the great articles!

    • whydoidoit
      November 20, 2012 - 3:24 pm Reply

      Good points – I know a bunch of people who like using “this” rather than an underscore, but I prefer the clarity, especially given you can forget to use “this” the code compiles and when you are reading it you aren’t sure what is private and what isn’t. Each to there own I say :)

      Great point on the booleans – yes no action is a bad idea – will add that to the main article.

      On the location of private variables – I’m not sure I agree with you on that – I tend to have private variables that are related to a series of functions and define them near that, if there get to be a lot, and they are truly used abundantly, I would refactor like you suggest. I find that CMD D/CMD SHFT D is my friend on all variables though – never really go looking for them :)

  • whydoidoit
    November 21, 2012 - 7:26 pm Reply

    I’ve spammed a comment due to an expletive in the (fake) email address which is visible on this site:

    The comment read:

    This is terrible
    In one sentence you speak of .net and c# then show us a bunch of javascript in the next

    My response:

    The naming conventions for C# and Unity Script (JavaScript) are the same. In Unity the version of JavaScript is a .NET derivation (more like Action Script than real JavaScript) and so the style should be maintained between both.

    This tutorial deliberately mixes Unity Script and C# to show examples, as the code in this article is not designed to be used I considered that to be a reasonable way of showing the methods being used in both languages.

  • CodeAssembler
    April 1, 2013 - 7:22 pm Reply

    Thanks for the good read. I too prefer not to use this.x syntax if I don’t have to.

    Although I still consider is very important to know or be aware of its existence and functionality in order to better understand OOP concepts for those new to coding.

    Also another drawback of Hungarian notation my mentor told me about is the case where you do find yourself needing to change the type of a variable after being used in a lot of code by any chance during code maintenance later on after such code has grown large enough.

  • PTTC
    April 13, 2013 - 2:40 pm Reply

    Excellent summary of this type of conventions.
    I tend to use Capital letters for all Public variables, same for u guys?

  • Sl
    April 29, 2013 - 2:37 pm Reply

    Pretty good tutorial.
    One thing struck me as false though, “The standard way to name variables in C++ was always to use Hungarian notation so you can work out what type the variable actually refers to”.
    No it wasn’t. Most of the popular coding standards followed by a great deal of C++ programmers (including myself) explicitly say to not use Hungarian notation. It’s not just avoided, it’s widely hated by quite a few.

    • whydoidoit
      April 29, 2013 - 3:13 pm Reply

      Well in my day every C++ programming book had hungarian notation in it. As you can probably tell – I hated it too. I guess it depends how old you are…

  • Mikael Gyth
    September 17, 2013 - 7:03 am Reply

    Hello, Came here trough google, trying to find out if Unitys uses lowercase public fields for a reason, like crossplatform compatability etc. Or if it’s just a convention. I’v been using uppercase for all my projects without any problems, but I can’t really be sure I’v encountered those potential edgecases where it might have mattered.

    Also, you mention that Unity 3.x doesn’t support namespaces. Do you know if unity 4.x supports namespaces on all plattforms? I just have a blurry memory about reading somewhere that there might be some issues with IOS and Android.

    Thanks for a great article.

  • Dilip
    September 20, 2013 - 1:36 pm Reply

    Excellent tutorial.

  • Shailendra
    November 9, 2013 - 9:07 am Reply

    Great Article,
    Great for the novice programmer.
    Great Job…keep it up..:)

  • Jeremiah Nunn
    November 16, 2013 - 3:09 am Reply

    Wanted to point out that there are other reasons to use the var keyword, an important one being when the type is anonymous, as you might have after a linq projection that creates a new type.

  • Adrian Toma
    January 21, 2014 - 5:35 pm Reply

    I’m finally leaving flash for unity.. Interesting articles!
    Coding conventions was very good reading for a start

  • Benproductions1
    January 24, 2014 - 8:09 am Reply

    Although you mention a lot of stuff (And I really do like this article), this article is clearly not meant for people just starting out with programming and it misses the obvious things such as spacing, indentation, placement of parenthesise, double or single quotes, scopes, comments, null checking, “using” instead of try/catch and multiple parameters. I was actually thinking of writing my own article specific to UnityScript addressing most of these, basically in order to link people to some style guide when they post questions on Unity Answers. Would you mind if I wrote another article on this, or should the information rather be all in one article.
    IMO C# and UnityScript require different styles and follow different conventions, but otherwise good job at incorporating both into the same style guide!

  • Jeff Evans
    March 16, 2014 - 8:08 pm Reply

    Great article for a novice programmer like myself that had some ideas from code examples but not enough knowledge to categorize appropriately.

    The only thing I found slightly confusing was the use of var, when in c# it needs to begin with the type, unless I’m mistaken. Maybe a line clarifying that would help a fellow noobie coder :)

    Great work and please keep it up!

    • whydoidoit
      March 16, 2014 - 8:37 pm Reply

      For local variables you can use var in c#. I always do this because I can read the code better afterwards, others would string me up for such heresy and claim it was for prototyping only. There’s no performance impact and it creates exactly the same IL so I’ll be continuing to use that style and evangelizing it to anyone who will listen!!

Leave a Reply