I spent a few hours this weekend fixing up a build script to drop into some prototypes that I’m working on. Much of the work originates from the lessons I’ve learned shipping multiple Unity titles to various storefronts. I started writing a post to describe it all, but it had so many various dependencies that it made a bit more sense to break it up and go a bit more in-depth when needed.
Over the next few weeks, we’ll look at how I’ve crafted this build script. If it goes well, I may continue the series with more “Best Practices” that I’ve picked up over the past few years.
Project Organization
Cooking is a pretty big hobby of mine. In the same ways that drive my infatuation with games — I’ve had some incredible experiences with some incredible meals, and I couldn’t simply leave them to hand-wavy magic. There was talent and knowledge behind the preparation of the food I was eating, so I set out to learn what it took to make a good meal or three.
One of the first cooking lessons that you should learn is a simple concept called “mise en place”. It’s French for “put in place”, and it refers to the constant organization of your kitchen. Time is incredibly valuable, especially in a professional kitchen, so efficiency must be at it’s highest point wherever possible. Keep your knives, measuring utensils, spices, and cookware in the exact same location, and preparation becomes quicker, allowing the chef to put their time and effort into the creation of their dish, not the assembly.
This applies to game development too. Spend the majority of your time on your craft. Don’t waste your time looking for the damned cinnamon.
Here’s how I currently set up my projects. Certain things get moved around and changed as I find slightly better ways to consider the organization, but after a few projects, I’ve arrived at this.
- ProjectName
- Builds
- Steam
- Linux
- Mac
- Windows
- Steam
- BuildIncludes
- Steam
- Linux
- Mac
- Windows
- Steam
- BuildTools
- 7zip
- Unity
- Assets
- Art
- Audio
- Music
- SFX
- Editor
- External
- Fonts
- Plugins
- Resources
- Scenes
- _Test
- Scripts
- ProjectSpecific
- SceneGame
- Shaders
- StreamingAssets
- ProjectSettings
- Assets
- Builds
From here, I add everything except the “Builds” folder to version control, and I’m on my way. Since the BuildTools will be included, and I can find all the included tools via relative paths, *any* computer that syncs to version control will be able to run the build on their machine.
My “Scripts” folder gets broken up a bit more, but that’s a bit dependent on the project . For instance, with Ugly Baby, level generation and PCG were very important, so there was a “Level” folder with a dozen or so scripts related to that.
The “External” folder is generally where I put all the plugins and assets I grab from the Asset Store, GitHub, and the ilk. If there is some unmanaged code that I’m compiling on my own to include as a plugin, I’ll put the source in a folder of its own at the same depth of the Unity and Build_____ folders.
“Builds” and “BuildIncludes” follow the exact same folder structure. (StoreName/BuildTarget) This is important, but I’ll get to it in a later post.
I still haven’t found a perfect solution for my “Art” folder. I’ve previously separated things into Models, Prefabs, and Textures, but that doesn’t work well when you have many assets for a 2D game. With the new 2D system from Unity in beta right now, I imagine that might change how I deal with sprites going forward.