• Orkney Chair

  • V&A Sliced

  • Map of Scotland

  • Dresser Teapot

  • Jaguar - FType

  • Gallery

The Game

Spinnacle is a vertical 3D puzzle game where the player can rotate and reorder the slices of a famous Scottish design in the V&A collection.

Using intuitive touch screen controls, they manipulate each slices rotation and vertical order to recreate the Scottish design. They will be rewarded for completing the object in as few moves as possible, we use a par system to allow the player to keep playing without punishment. The player can unlock more information by collecting the light bulbs in each level. These light bulbs unlock more information in the gallery but make the puzzle harder to complete.


As the programmer I implemented the gameplay mechanics and backend systems. I also setup and managed our VCS, Doxygen and Technical Wiki through using GitLab’s CI/CD and Hugo the latter two were easy to manage. Our setup on GitLab also utilizes Git-LFS to handle any large files we had, I also carried out Unity upgrades at several points for specific fixes required for the project.


The fundamental core game didn’t change but whilst liaising with the V&A Dundee there was a lot of iteration on the design, but the team really brought the game together. This did require rewriting, tweaking and abandoning various parts of the project but it was still a lot of fun and the V&A were very happy with the final product.

Unity Cloud Build

One of our greatest investments was the use of Unity Cloud Build. It built the develop branch for all available platforms and provided links to the builds. This allowed us to get the game in people’s hands much faster making it easier to test.

Unity Cloud Build would automatically log crashes, null references and various other issues straight away, all matched to specific versions. This helped us spot bugs early on, whilst also helping in iterating the design as everyone was able to play the game easily.

Designer Tools

To make creating and adding new design objects with connected levels, gallery entries, descriptions and difficulties easier, the process was automated from Scriptable Objects. The designers could modify the details in one place and it would propagate through the various levels and gallery entries. This same idea was extended to generate the map screen. This reduced the number of errors and made the game much easier to manage.

The goal with the design tools was to eventually create an editor window that would take the design objects models; create all the required scriptable objects, levels and object slices and allow it all to be edited easily from one window, sadly this final goal was not reached as other issues took priority, but the individual components were, making it much easier for the designer to iterate on the level difficulties and descriptions.

iPad Air Shader issues before play test

The V&A kindly gave us access to their iPad Airs for a playtest at the Douglas Community Centre. We had been building for iOS for several weeks and our test devices, everything I could get my hands on at the University, tested fine and ran smoothly without problem.

One week before the playtest we finally got our hands on the physical devices, I booted up Spinnacle, there was a massive delay on first load, our game normally took only a few seconds to load, the game would finally load and play fine but the lag at the beginning was odd and a possible sign of future problems. There was something obviously wrong with our game, we had no idea what it could be there was to many variables to consider.

Profile, profile and profile some more, slight issue I couldn’t reproduce the lag spike any more on the device, everything seemed fine, which was odd. I booted it onto another device and the bug reappeared. This was evidently a one-time on initial boot bug, so I wiped Spinnacle from the device, hooked in Unity’s profiler and started profiling again.

Shader dot Shader Create GPU Program

Unity’s Profiler was really helpful it instantly showed us we had an issue in `Shader.CreateGPUProgram`.

Shader.CreateGPUProgram is only called when the application is first loaded on the device. It builds the shaders into their platform specific binaries and stores them in a shader cache on the device. After some general debugging techniques; I stripped out the shaders into a separate project, used shader variants to force them to be compiled at start and started tracking down which specific shader was causing the error. After further investigation, it came down to one declaration that was not handled properly on older iOS version float4(0,0,0,0) did not expand out properly on older iOS devices.

void surf(Input IN, inout SurfaceOutput o) {
    // o.Albedo = float4(0, 0, 0, 0); << Odd error only on iPad Air/iPhone 4
    // o.Alpha = 0;
    o.Albedo = _InternalColor;
    o.Alpha = _InternalColor.a;

Products Used


Stewart L. McCready
Code Monkey

Game programmer and code monkey, living in Inverkeithing, Scotland.