Tuesday, 21 October 2014

Enable MvcBuildViews using TeamCity if a view is changed

At work we recently switched from using SVN to Git and GitHub. There are many advantages but there's one in particular I want to talk about. 

Using TeamCity you can automatically build all pull requests. This is incredibly useful as it ensures only code that compiles successfully and passes all unit tests gets back into master. If the build fails you are notified in GitHub.

But, there's a problem. View errors are not reported because MvcBuildViews is off. One solution is to enable MvcBuildViews for all web projects but in our case this is best avoided as it roughly quadruples compile time. The ideal solution is to enable MvcBuildViews only if a view has been changed in the current build. Unfortunately I struggled to work out how to do this. So I asked a question on Stack Overflow and the first answer I received pointed me the right direction.

I've managed to improve on my Stack Overflow answer. It simply enables MvcBuildViews for all .csproj files if a view has changed, but this is still quite slow. It's much faster to only enable the setting for projects in which views have changed. This may be overkill for many solutions but for ours it's not.

A few things to bear in mind:
  • I'm no PowerShell expert, the code is probably quite poor
  • You'll probably what to change the Get-ChildItem command in step one to point directly at your web project .csproj files rather than all .csproj files
  • The Write-Host commands must be formatted in this way so they appear in the TeamCity build log
  • By default TeamCity does not do a clean checkout of the source code (although this can be enabled). Instead changes are applied incrementally meaning that alterations to .csproj files are not undone on each build. So MvcBuildViews should be reset on every build
  • %system.teamcity.build.changedFiles.file% - This file lists all the changes in the current build in the format [fileName]:[status]:[commitHash]. E.g. Home/Index.cshtml:CHANGED:1400ea14c3196abbfd8de3ab6fe0a902be2ccad8
  • %teamcity.build.workingDir% - This is the directory that contains all the files to be built

Monday, 1 September 2014

I've made a game - what did I learn?

I've made a game for iPhone, it's called Rebounder. This is a series of blog posts about it.
  1. I've made a game
  2. Why?
  3. How?
  4. Some of the challenges
  5. What did I learn?

It works in my head

Before starting Rebounder I came up with a few other game ideas and made a few prototypes. Each one was great when I imagined it in my head but sucked when I made a prototype. It really underlined the importance of getting software into people's hands as soon as possible.


There's no such thing as simple

Okay so Flappy Bird was pretty damn simple, but generally speaking there's no such thing as a simple game. When the idea popped into my head for Rebounder it was something like "draw lines on screen to bounce balls to a target, simple!". Unfortunately when you give it more thought and started building something, it's rarely simple.



Programmers can't make games by themselves

I have zero graphic design skills yet I still tried to create some graphics. It was a total waste of time, you need someone with graphic design skills. In fact I'm going to go as far to say that making a game by yourself is a bad idea. I think sharing work, sharing ideas, sharing enthusiasm, sharing testing and everything else would help a great deal.


Don't throw away your prototype

My prototype was terrible. Once it had served it's purpose, to prove that Rebounder would work, I had to start from scratch because the code was so bad. In doing so I reintroduced bugs I'd fixed and introduced new bugs, plus it took ages. In hindsight I feel that had I spent maybe 30-40% more time on the prototype I could have reused much more code and saved quite a lot of time.


Time management

Games take time and time is often in short supply. I realised during the course of development that I need to make better use of my time.
  • Prioritise - Only do what really needs to be done. Aggressively slim down your task list. For example split tasks into essential and nice to have
  • Discipline - When there's a lot of work to do I find it's important to find regular time, however short, to complete a few tasks so you feel like you're making progress
  • Focus - I spent a lot of time working in front of the TV, only half concentrating on the task at hand. Big mistake. It resulted in poor code and poor solutions. I really should have worked somewhere quiet with no distractions


Unity specific stuff

  • Don't use Vector2D to position your sprites - As far as I'm aware Unity has no mechanism for controlling sprite order so you have to set their Z co-ordinate so one is in front of another in the scene. This means you need Vector3D
  • Be careful when updating plugins - Make sure everything is committed to whatever source control system you're using before updating. In particular NGUI cause me some difficulties
  • Use Force Text asset serialization - The alternative, Force Binary, leaves you clueless as you what you've changed when committing to source control
  • Don't fight MonoBehaviour - By default all script components attached to GameObjects inherit from MonoBehaviour. When I started development I wanted to write POCOs so my classes were easier to unit test but I found many tasks were hard work because of the missing inherited functionality. In the end I gave in and wrote all my components that way. It was much easier
  • Keep your script components as small as possible - I found it's better to attach several small scripts to a GameObject rather than one massive script. In hindsight this is fairly obvious, it's just the single responsibility principle. The only downside to this a bit of extra code so the components can communicate
  • Events are invaluable - When I started writing Rebounder I had a lot of initialisation code that looked like this someObject = (SomeObject)FindObjectOfType(typeof(SomeObject)); This is really bad news because many of my classes ended up with unnecessary references to one another. Then, since I had a reference I would start calling the referenced classes methods and I moved closer to spagettiville. Using events these problems disappear. You simply fire off an event and any classes that need to know about it implement event handlers. The class firing the event and the class handling the event have no knowledge of one another. For event handling I used the Messenger Extended code on Unity3D wiki. I highly recommend it if you want a simple, easy to understand code that is up and running within minutes
  • Playmaker isn't particularly useful if you're a programmer - Playmaker is a popular plugin described as "visual scripting for Unity". What that means is you can make games without any programming knowledge. I attempting to learn it hoping it would speed up development time but ended up being frustrated because I could achieve things much quicker using code. Perhaps if I'd persisted with it Playmaker it would have been very useful, but then I would have probably had less Unity API knowledge. It's not black and white. Anyway, I gave up on Playmaker


Get lots of people to test

When I was ready to send Rebounder out for wider testing I asked on facebook and received what I thought was plenty of replies. I distributed copies of the game to less people than offered because I had enough testers. In hindsight this was a bad idea. Some testers didn't install the game and quite a few testers didn't offer any feedback at all. Perhaps they were busy or perhaps they didn't like it and were embarrassed to say. Don't get me wrong I appreciate everyone who gave up their time to test, but testing without feedback is totally pointless. So my point is, if you make a game or app, send it out to every single person who offers to test it.