So, this week is a technical blog. Iâ€™ve been flat out with work and have had no time to further our games at all. Incidentally Iâ€™ll be announcing the name of the studio Iâ€™ll be forming soon. Iâ€™ll be writing up some stuff for it first though, so until then itâ€™s still just vague â€˜our gamesâ€™ references.
So this week I have a bit of a tutorial of sorts. Iâ€™ve had to do set up version control for a project a couple of times now, and have had to re-teach myself the steps each time, so this time I wrote them down. Firstly Iâ€™ll talk a little about my reasoning for using what I use, then Iâ€™ll get to the meat of it all. Iâ€™ve included screen shots, so hopefully if youâ€™re following along there are no dramas.
There are two reasons I use GIT.
- I use a Mac, and the best version control client Iâ€™ve found is SourceTree. SourceTree doesnâ€™t support SVN, but it does handle GIT very nicely.
GIT allows you to create branches. Branches create copies of a project at a given time. You can then work on that branch, implementing a feature you arenâ€™t sure about, or you think will take a long time, without effecting the master branch. This can be good for two reasons.
- If you are working with a team they can all have their own branches where they implement specific features that are assigned them, while this is happening the master branch can be kept as an â€œalways playableâ€ build. Once the feature is complete and tested and 100% working, it can be merged back into the master branch.
Secondly, if you decide, after a lot of work and modification to the core of the code base, that the feature isnâ€™t going to work, isnâ€™t fun or is too heavy, you can simply kill the branch and go back to the game as it was before you started implementation. Nothing needs to be ripped out, no extranuous code will be left floating around in there. Itâ€™s all clean.
Ok. So why BitBucket. There are a few other options, GitHub is extremely popular, and the first that jumps to mind. I have two reasons for choosing BitBucket.
You can have an unlimited number of repositories on the free account
You can set repositories to private
SourceTree is free and an excellent visual interface to use with GIT. It shows the branches, files that were commited, comments with commits, diff comparisons. Itâ€™s just much easier than the terminal. Incidentally, itâ€™s also made by the same people that created BitBucket, so it plays nice.
So letâ€™s get to it.
First you need to set up External Version Control in your Unity project.
- Edit->Project Settings->Editor
- Version Control Mode â€“ Meta Files
- Asset Serialization â€“ Mixed. Unity made some big changes to allow you to force everything to be text files, essentially making everything serialise into something like XML. Unfortunately this doesnâ€™t particularly help much. The main issue with version control in Unity is that the Scenes themselves are usually binaries. Binaries canâ€™t be merged. This means if two developers are working on the scene at the same time someone will have to discard their changes to accept the others then make them again. Technically this is solved by making the scene a text file, except resolving conflicts when something as abstract as a scene has been stored as a massive massive XML doc is crazy. So leave it as mixed, leave the scenes as binaries so they are nice and small, and just pay attention to whoâ€™s working on which scene.
Ignore Host URL
Download Sourcetree and install it.
Create an account with BitBucket (I already had a GitHub account so I signed up using that account for ease of use)
Select â€œCreate repositoryâ€
Give your repo a name
Give it a description
You can have unlimited private and public repos on BitBucket (my favourite thing about it)
Repo type is GIT
If you would like you can have Issue Tracking and a wiki. Both could be a good idea for managing the code base (issue tracking) and game design (wiki). The wiki could even be used in a similar way to a design log as described by one of my favourite game designers Dan Cook
Choose your language (even UnityScript is in this drop down!).
Select Starting from scratch.
Now we need to set up our project as a repository (repo).
The instructions for this are handily shown by BitBucket, but Iâ€™ll go through them here as well.
Navigate to your project folder
$ cd /path/to/my/repo (for those that donâ€™t know, the $ in these situations arenâ€™t typed by you, they are a standard of some sort for showing what the user must type. It took me a little while to realise that when I began messing with the mac terminal).
$ git remote add origin ssh://email@example.com/
again, this is very nicely mentioned in the BitBucket site, it will include the username and reponame for the project youâ€™re setting up so you could even copy and paste to be sure youâ€™ve got it right.
Now we have everything that we need set up to use SourceTree instead of the terminal.
Set up repo in SourceTree
- Open SourceTree
- Select Add A Repo (Thatâ€™s the Can looking thing with a green plus in the top left).
- Select Add Working Copy (the folder and can icon)
- Navigate the Working Copy Path to your Unity project folder. If everything is set up you should see â€œThis is a GIT repositoryâ€. If not, you may be selecting the wrong folder. You want the root folder of the project, it should contain the Assets and ProjectSettings folder amongst others. If not, find that one. If you are at that one then you set up a git repo in the wrong folder. Find the one you set it up in, delete the .git folder (itâ€™s a hidden folder) from it, go to BitBucket and delete the repository and start again. It shouldnâ€™t take long to catch back up.
- Give the repo a name (itâ€™ll have the folder name by default which should be fine)
- Now the repo appears (or you may have to double click it on the list).
- This screen can look a little confusing at first, but itâ€™s pretty straight forward. There are 4 â€œpanelsâ€. On the left is a narrow one that is pretty simple at this stage because we have no branches. Here you can see any Remote repos (as this one is), any branches, tags, stashes or sub modules. These are all features of GIT that you may find useful one day. For now we are just going to use the origin (sometimes called master branch), so make sure it is highlighted.
- In the middle of the screen are two panels, one atop the other. The top is called Files staged in the index and should be empty. The bottom is called Files in the working tree and should be full.
- On the right is difference panel. This will show the changes made between a file existing on the remote repo and the one that is selected. This is especially handy for code files since it shows exactly what youâ€™ve changed since last commit.
- The files in the working tree should only show files that need to be committed (that is new or deleted ones, or ones that have been modified since the last push to the remote repository). This can be changed with the drop down above the Files staged in the index panel which is currently set to Show Pending. We want to simplify the Files in the working tree panel. We donâ€™t want to track everything in a Unity project. A lot of these things are automatically created, so if you are collaborating you want them to pull the project, open it in Unity and let their Unity set this stuff up. All you need is the Assets folder and the ProjectSettings folder. So, first of all, collapse any expanded folders (assuming you have it showing in tree mode, which I do for ease of reading, again, this is a drop down at the top, just to the left of the Show Pending drop down). Now select everything except the Assets and ProjectSettings folders. Right click and select Ignore.
- A pop up will give you some options. Select Ignore in this Repository.
- Youâ€™ll now see a very neat and tidy Files in the Working Tree panel. Notice the .gitignore file. That lists all those files and folders you just told it to ignore.
- Now we want to commit. Commit is the process of staging files, that is readying them to be pushed to the remote repository. To do that simply select all of them (including the .gitignore) and drag them up to the Files staged in the index panel.
- Youâ€™ll notice, if you expand the folders, that every file and folder has a .meta file and that every file (including .metas) have a green plus next to them. The plus, as you probably guessed, means they are new to the repo and are being added. Itâ€™s important that all meta files are included. If they go missing Unity wonâ€™t be able to set things up properly, this is especially important for prefabs since the meta files keep the prefab linked to any resources it uses.
- Now you just press commit at the top.
- A commit will ask for a comment. It is always a good idea to comment your commits well. When something breaks and you need to go back to the point you changed it, especially if itâ€™s code and you just want to pluck the class back out of the repo from before you broke it, your comments can save a lot of time. For this one, something like â€œInitial commitâ€ is fine.
- Youâ€™ll notice this also shows the files that are being commited, and any that are in the working copy that havenâ€™t been committed, in case you missed some somehow. When youâ€™re ready, press Commit.
- That is now committed locally. All we need to do is Push it to the repository on BitBucket. Itâ€™s already linked to that repo, so simply press Push and away it goes. Push beings with it another dialog, here you can select which branch to push to. We only have the master, so select it and press OK.
- Let it do itâ€™s thing, it can take a little while sometimes, depending on if you imported any packages into your project when starting up.
- Once thatâ€™s done you should see â€œmasterâ€ under â€œbranchesâ€ on the left. If you select it you get some rearanging of panels and some new panels.
- The difference panel is still there. The top panel is now a tree of commits. This will look more interesting and helpful after a few more. Selecting a commit will give you details in the other panels. It will show what files were effected, and the comment, date, author etc of the commit.
- Thatâ€™s it. You are all done. Any time you work on your project, you can come back here, it will automaticaly update and show any files that have changed and need to be committed and you just follow the same process.
You can jump back to BitBucket.org if you like and see for yourself that itâ€™s there. Select the name of the repo and it will show you Recent activity (which should have the push you just did. The SSH URL is on the right for future reference (for instance if someone else wants to pull your project and help you work on it). The number of branches, tags, forks and followers of the project. You can invite users from here. Itâ€™s all very simple and intuitive.
A couple of last minute tips.
Try to commite regularly and small changes at a time. Focus on getting a single thing working, then commit it. There is no harm in having many commits. If everything breaks it will make life much easier.
Make it a habit to save the scene and the project before each commit. Many times there wonâ€™t be any changes to them, but sometimes there are. Things like code are automatically updated just by being built. But any changes to prefabs are only saved when you save the project. If you change a prefab, double check that it shows up in the Files in the working tree panel (they have a .prefab extension). If not, you forgot to save the project first.
Thatâ€™s about it. I made that long winded, I know, but I wanted it to be as clear as possible. You now have a nice pipeline for version control. Remember that you will still get conflicts if more than one person alters a scene at the same time as you canâ€™t merge binary files. This means when you commit, one of you will have to discard your changes, accept the otherâ€™s version, pull it, redo your changes, then commit it, so communicate. I would recommend using something like a Trello board to track scene usage if you have a few scenes in the game. If thereâ€™s only one, simple communication should suffice.
Now you can focus on exploring interesting mechanics and ideas and not worry so much about breaking anything. If anyone reading this doesnâ€™t know much about GIT I recommend doing some reading, branching is a particularly useful tool for safely exploring mechanics and other ideas, especially if you are working with a team of people and you donâ€™t want to break the current master branch copy.