I am a computer science student who is in their third year at Hull University. I started out teaching myself about various web technologies, and then I managed to get a place at University, where I am now. I've done a year in industry too, which I found to be particuarly helpful in learning about the workplace and the world.

I currently know C# + Monogame / XNA (+ WPF), HTML5, CSS3, Javascript (ES6 + Node.js), PHP, C++, and a bit of Python. Oh yeah, and I can use XSLT too.

I love to experiment and learn about new things on a regular basis. You can find some of the things that I've done in the labs and code sections of this website, or on GitHub. My current projects are Pepperminty Wiki, an entire wiki engine in a single file (the source code is spread across multiple files - don't worry!), and a Prolog Visualisation Tool, although the latter is in its very early stages.

I can also be found in a number of other different places around the web. I've compiled a list of the places that I can remember below.

I can be contacted at the email address webmaster at starbeamrainbowlabs dot com. Suggestions, bug reports and constructive criticism are always welcome.


Blog Roll | Article Atom Feed | Mailing List

Latest Post

Untangling MSBuild: MSBuild for normal people

I don't know about you, but I find the documentation on MSBuild is be rather confusing. Even their definition of what MSBuild is is a bit misleading:

MSBuild is the build system for Visual Studio.

Whilst having to pull apart the .csproj file of a project of mine and put it back together again to get it to do what I wanted, I spent a considerable amount of time reading Microsoft's (bad) documentation and various web tutorials on what MSBuild is and what it does. I'm bound to forget what I've learnt, so I'm detailing it here both to save myself the bother of looking everything up again and to make sense of everything I've read and experimented with myself.

Before continuing, you might find my previous post, Understanding your compiler: C# an interesting read if you aren't already aware of some of the basics of Visual Studio solutions, project files, msbuild, and the C♯ compiler.

Let's start with a real definition. MSBuild is Microsoft's build framework that ties into Visual Studio, Mono, and basically anything in the .NET world. It has an XML-based syntax that allows one to describe what MSBuild has to do to build a project - optionally depending on other projects elsewhere in the file system. It's most commonly used to build C♯ projects - but it can be used to build other things, too.

The structure of your typical Visual Studio solution might look a bit like this:

The basic structure of a Visual Studio solution. Explained below.

As you can see, the .sln file references one or more .csproj files, each of which may reference other .csproj files - not all of which have to be tied to the same .sln file, although they usually are (this can be handy if you're using Git Submodules). The .sln file will also specify a default project to build, too.

The file extension .csproj isn't the only one recognised by MSBuild, either - others such as .pssproj (PowerShell project), .vcxproj (Visual C++ Project), .targets (Shared tasks + targets - we'll get to these later), and others - though the generic extension is simply .proj.

So far, I've observed that MSBuild is pretty intelligent about automatically detecting project / solution files in it's working directory - you can call it with msbuild in a directory and most of the time it'll find and build the right project - even if it finds a .sln file that it has to parse first.

Let's get to the real meat of the subject: targets. Consider the following:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="" DefaultTargets="Build" ToolsVersion="4.0">
    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

    <Target Name="BeforeBuild">
        <Message Importance="high" Text="Before build executing" />

I've simplified it a bit to make it a bit clearer, but in essence the above imports the predefined C♯ set of targets, which includes (amongst others) BeforeBuild, Build itself, and After Build - the former of which is overridden by the local MSBuild project file. Sound complicated? It is a bit!

MSBuild uses a system of targets. When you ask it to do something, you're actually asking it to reach a particular target. By default, this is the Build target. Targets can have dependencies, too - in the case of the above, the Build target depends on the (blank) BeforeBuild target in the default C♯ target set, which is then overridden by the MSBuild project file above.

The second key component of MSBuild project files are tasks. I've used one in the example above - the Message task which, obviously enough, outputs a message to the build output. There are lots of other types of task, too:

  • Reference - reference another assembly or core namespace
  • Compile - specify a C♯ file to compile
  • EmbeddedResource - specify a file to include as an embedded resource
  • MakeDir - create a directory
  • MSBuild - recursively build another MSBuild project
  • Exec - Execute a shell command (on Windows this is with cmd.exe)
  • Copy - Copy file(s) and/or director(y/ies) from one place to another

This is just a small sample of what's available - check out the MSBuild task reference for a full list and more information about how each is used. It's worth noting that MSBuild targets can include multiple tasks one after another - and they'll all be executed in sequence.

Unfortunately, if you try to specify a wildcard in an EmbeddedResource directive, both Visual Studio and Monodevelop 'helpfully' try to auto-expand these wildcards to reference the actual files themselves. To avoid this, a clever hack can be instituted that uses the CreateItem task:

<CreateItem Include="$(ProjectDir)/obj/client_dist/**">
    <Output ItemName="EmbeddedResource" TaskParameter="Include" />

The above loops above all the files that are in $(ProjectDir)/obj/client_dist, and dynamically creates an EmbeddedResource directive for each - thereby preventing annoying auto-expansion.

The $(ProjectDir) bit is a variable - the final key component of MSBuild project files. There are a number of built-in variables for different things, but you can also define your own.

  • $(ProjectDir) - The current project's root directory
  • $(SolutionDir) - The root directory of the current solution. Undefined if a project is being built directly.
  • $(TargetDir) - The output directory that the result of the build will be written to.
  • $(Configuration) - The selected configuration to build. Most commonly Debug or Release.

As with the tasks, there's a full list available that you can check out for more information.

That's the basics of how MSBuild works, as far as I'm aware at the moment. If I discover anything else of note, I'll post again in the future about what I've learnt. If this has helped, please comment below! If you're still confused, let me know in the comments too, and I'll try my best to help you out :-)

Want a tutorial on Git Submodules? Let me know by posting a comment below!

By on


An implementation of an algorithm to find the distance from a point to a line, adapted for multi-segmented lines.
githubjsLine Distance Calculator
An implementation of Valvalingam's line simplification algorithm.
githubjsLine Simplifier
Share files and images on your computer with your friends!
A night sky full of pretty twinkling stars.
sbrljsStarry Sky
A small gem I found in my archives. From 2013.
sbrljsArchives: Colour Picker
A bicycle riding through some procedural scrolling parallax hills.
sbrljsParallax Bicycle
A procedural castle generator I wrote for /r/proceduralgeneration's 2nd Monthly challenge.
githubjsProcedural Castles
A pen I created as a demo whilst writing a class to draw regular shapes.
codepenjsRotating Shapes
A pen I created as a demo whilst writing a class to draw smooth lines.
codepenjsSmooth Lines
A small experiment to get my head around how fractals work.
sbrljsFractal Shapes
An example of context.ellipse in action, written for a blog post.
Get all the fun of the fair without the noise and the cold.
sbrljsBig Wheel
Some treasure is hidden on your screen. Can you find it using only your ears?
sbrljsAudio Treasure Hunter
A Voronoi Diagram Generator
sbrljsVoronoi Diagrams
A random snowflake generator
sbrljsSnowflake Generator
A fully functional wiki in a box.
sbrlphpPepperminty Wiki
Some clouds drifting across the screen, drawn via the HTML5 Canvas.
sbrljsHTML5 Canvas Clouds
A turtle based drawing program for your first forays into simple programming.
A client side online tool for stitching strings of still images into an animated gif.
sbrljsGif Renderer
A set of parallax scrolling stars using the HTML5 Canvas
sbrljsParallax Scrolling Stars
An (almost) pure CSS spotlight demo.
jsbincss(Almost) Pure CSS Spotlight
A Javascript Bookmarklet to fade the unimportant parts of a page. Also features HTML5 fullscreen API integration.
A small script to trianglify (draw triangles on) an image.
sbrlhtmlImage Trianglifier


An implementation of HTTP and Websockets in pure C&sharp; as a library. Does not use System.Net.HttpServer.
githubcsharpGliding Squirrel HTTP
A program that detects and decodes morse code embedded inside an audio file.
sbrlcsharpAudio Morse Decoder
The one and only C&sharp; class generator. Tired of typing the same old scaffolding out all the time? Give this tool a try.
A class modelled on StreamWriter that makes it easy to generate CSV files.
A web based tool that generates diagrams based on Prolog traces.
githubjsProlog Visualisation Tool
A command line tool to generate random noise, written in C#
A (hopefully) better traceroute utility written in C#
An easier way to generate XML.
sbrlphpSimple XML Writer
A PHP based Atom feed generator.
sbrlphpPHP Atom Generator
A simple CodeMirror based javascript bookmarklet editor.
sbrlhtmlBookmarklet Playground


I find useful tools on the internet occasionally. I will list them here.

I'm Only Resting
Art by Mythdael