Posted by Abban on 29/01/2017
An Overview of How we Plan and Structure our Projects. TLDR; MVC
I'm Abban, the lead (only) developer in Big Bad Studios and in this series of posts I'm going to outline some of the technical challenges we faced and the reasoning behind some of the decisions we made (and are still making) in our journey to become a game development studio.
Some posts will be long form tutorials, some will be smaller tips and some will be more of an overview of our planning and decision process. I'm far from a technical expert in Unity, but in my experience so far decent information on many aspects of game development can be hard to find. So my hope is that writing down some of this as I go will help some of you to get to at least where we are at now. Never stop learning!
As this is the first post I'm going to start at the beginning, because the beginning is usually the best place to start unless of course you like going backwards and in that case you should probably skip to the end. This might not necessarily be the most perfect way of doing things, but through trial and error this is where got to and its whats worked best for us so far.
The foundation of any project is its structure, or System Design. The system design is where you define how the different parts of your project will work together in order to satisfy your project's requirements. How the data is stored and manipulated, how it should be used, how your interface works, all these are part of your System Design.
You might be wondering why you need to think about good structure at the very beginning of a project?
Well for starters its good discipline, the more you do it the more natural it becomes and it will eventually save you time.
Building multiple projects on a similar well designed foundation also makes it easier to swap between projects. I have 10-20 prototypes I like to fiddle with and swapping between them is easy enough.
But the most compelling reason this lazy programmer has to design early is that if the prototype is already built with a good system design its super easy to just roll that on into a production project. No restarting and copying code from a prototype into a separate production project!
In the longer term the benefits of doing that early design on your system really start to stack up the longer your project goes on.
If your project is well structured it will help you to remember where stuff is. Especially when you want to make some changes to say a GUI component you last looked at 6 months ago.
If you need to add another developer to your project it will help them get up to speed really quickly. Everyone on your team should use the same design for the modules they build, meaning anyone can work on any part of your project without having to learn the style of any one developer.
Scalability & Maintainability
As your codebase gets bigger it will get harder to manage and early design mistakes could compound into a nightmare. Designing good structure right from the beginning will make sure that this is kept to a minimum as your project grows.
Beware of god classes/fat controllers.
What I mean with this is that its very easy to give your manager/controller too much responsibility. You don't want your Controllers to care about what happens in the view or model layers. I've fallen into this trap myself a couple of times without realising.
The solution to this is to use fat models and skinny controllers. It makes a lot of sense to do this, make your model responsible for modifying and validating all of its own data before sending it to the controller. Similarly the view elements don't care about modifying any data, they're responsible purely for display. That way your data handling is completely separated from your GUI.
If you ask 100 different developers how they structure their project you'll get 100 different answers. Here's how I've been doing things.
I cut my programming teeth in web development and from early on I learned to use the MVC design pattern. MVC stands for Model-View-Controller and is a design pattern that separates various parts of the application into one of 3 roles that work individually from each other but communicate in defined ways. Each part is responsible for their own layer and this is called Separation of Concern. I'm not going to go too deep into it in this post so if you're not familiar with it I recommend you do some reading. Apple have a good overview here.
In Unity projects I find that this design pattern works pretty well, albeit in a bit more of an abstract way.
Web frameworks take the MVC pattern very literally, a lot of them define their folder structure in one of 2 ways:
- Models - Module1 - Module2 - Controllers - Module1 - Module2 - Views - Module1 - Module2
- Module1 - Models - Controllers - Views - Module2 - Models - Controllers - Views - Module3 - Models - Controllers - Views
Its important to remember that the MVC pattern is an abstract pattern and you don't need to make sure all files are explicitly saved in a folder structure that corresponds to that. In Unity I use a folder pattern that groups code by component type but the code logic is still MVC orientated. I treat GUI and display objects as views, Managers as controllers and use Models for loading player preferences, save data and JSON configurations.
Example Component Folder Structure
- Camera - Characters - GUI - Helpers - Levels - Managers - Models
This makes it a little harder to tell whats in each layer when looking at your file structure but when you think about it most game objects in Unity already belong to one. GUI elements and things like the player, enemies, lights projectiles are all naturally in the view layer. In the same way Managers are Controllers, and Player Prefs and Save Data are in Model layer.
So by keeping the functionality of a component within its allocated layer when you look at it you'll know where it belongs.
Note: A bonus from component structuring it that these folders also correspond to namespaces. Classes in the managers folder can use the namespace MyProject.Managers in the GUI folder MyProject.GUI etc.
I mostly focused on the code structure of a project because in my mind everything else is just an asset, Scripts is where the bulk of the design goes. But keeping these other assets organised is also an important part of maintaining the sturdiness of a project. I handle assets by just using a folder structure that works for me:
- Animations - Editor - Fonts - Plugins - Prefabs - Resources - Scenes - Scripts - Sounds - Sprites - StreamingAssets
I also use subfolders as needed, for example enemy prefabs might be in an Enemies folder in Prefabs. All the premium assets I'm using from the Unity Assets Store go into the Plugins folder. I've heard it said that you should leave them where they want to be installed because paths might break, but if an asset requires a hardcoded path its probably not well made enough to use in a production project anyway.
So this is the end of the beginning. I've just given a brief overview of how I handle structure. What works for us might not work for you so don't be afraid to adapt things to suit your own preferences. The approach I used to get to here is to try something, tweak what doesn't work, then try again.
I know this post was heavy on overview and light on detail, but like a good system I needed a foundation to build this series on. There's a whole bunch of things I want to talk about in more detail which I'll start posting here over the next few months.