Dan Taylor is a gaming industry veteran who has worked on some of the most celebrated franchises in gaming history: Medal of Honor, Hitman, Max Payne and Tomb Raider. He now leads Thunderbox Entertainment, a VR and mobile dev studio located in the UK.

His latest release is Tsuro: The Game of The Path. Today he provides his lessons learned for what you should and should not do when developing a mobile VR application, and we hope these help you to elevate your next experience (or potentially save a few dev hours).

The start of 2016 was an exciting time: we’d just shipped our first mobile app, a tactile recreation of the board game Tsuro, and were getting ready to start on the next one. We didn’t really have any plans to get into VR… it just kind of, you know… happened.

A friend of ours had been raving about his shiny new Gear VR and insisted we try it out. We weren’t convinced about the potential of mobile VR - it was hard enough to do a decent looking game on a phone, let alone one rendering at 60fps – but we thought we might as well take a look.

As soon as we tried it, we were suitably impressed, quickly realising that mobile hardware was entirely capable of delivering a VR experience almost every bit as spellbinding as much of the software on desktop… and at a way friendlier price point.

Two weeks later we’d got our hands on some hardware, and Tsuro was up and running in VR… but it wasn’t particularly fun. Playing a virtual board game around a virtual table somehow made it clear that we were a pale imitation of a real-life experience that was already way more engaging. If we were to disrupt on mobile VR, the same way we did on phone and tablet, we needed a hook…

Fast-forward to 2018, and I had a similar epiphany in the form of Superhot on Oculus Quest.

The OC5 demo team literally had to pry the headset from my head to stop me playing. As I stumbled out of the play area, it suddenly hit me: why couldn’t we make board games a room-scale VR experience too?

So, to reimagine Tsuro for the Oculus Go, we supersized everything by a factor of 70. You can feel the pieces whoosh past you as you survey the action from the center of the board, and climbing the surrounding scenery gives you a tactical awareness that wouldn’t be possible in any other format.

But even once we had a clear vision, it wasn’t all smooth sailing. In retrospect, it does seem that the project went more right than wrong, so let’s get the bad stuff out of the way first…

What went wrong?

1. A Legacy of Pain

In order to make porting Tsuro as efficient as possible, we needed to re-use as much as we could from the mobile version. Unfortunately, the base project was over 6 years old, so there were some weird legacy issues that slowed us down and hampered performance.

Our tweening system, HOTween, didn’t work when compiled with IL2CPP. We could have updated to DOTween but, as we only switched from Mono late in the project, this was deemed too risky.

As we started Tsuro before Unity had its own UI system, we were using nGUI. It’s great for very performant UI, but has a few quirks. Because we had to use custom shaders to light our diegetic UI, it all fell apart when we tested the dynamic system fonts required for Asian localisation. Once again, this was late in the project, so we had to hack in a fake lighting system a week before launch.

We were also using Playmaker for visual scripting. We didn’t really know how to use it when we started Tsuro, so our scripting is a horrible mess. If you are going to use Playmaker, use globals for your key game data, keep your state-machines small, color-code everything, and make sure any hand-overs between state-machines are robust and properly synched: when we updated our version of Unity, a slight speed increase meant that a few Playmaker elements were suddenly firing in a different order, causing major bugs!

2. Taking the Mobile Framework for Granted

In porting Tsuro, we underestimated the amount of basic mobile functionality that we would need to be considered for VR, this included:

Push Messaging – we use OneSignal for multiplayer push notifications, to update room lists and notify users outside of the app when it’s their turn. Oculus has a notification system which might work as an alternative, but we didn’t have time to research and implement it for Tsuro.

– we use OneSignal for multiplayer push notifications, to update room lists and notify users outside of the app when it’s their turn. Oculus has a notification system which might work as an alternative, but we didn’t have time to research and implement it for Tsuro. Game Center – Tsuro has over 50 achievements that are designed to help users discover the various secondary game mechanics. Oculus has a robust achievements system… but no systemic notification pop-up when you unlock one, and no UI to check your progress. The achievement UX had to be designed from scratch and bolted on.

– Tsuro has over 50 achievements that are designed to help users discover the various secondary game mechanics. Oculus has a robust achievements system… but no systemic notification pop-up when you unlock one, and no UI to check your progress. The achievement UX had to be designed from scratch and bolted on. Social Integration – believe it or not, there is no easy way to integrate Facebook into a Unity game for Oculus. On mobile, you can use the Facebook Unity SDK. On Oculus… not so much.

– believe it or not, there is no easy way to integrate Facebook into a Unity game for Oculus. On mobile, you can use the Facebook Unity SDK. On Oculus… not so much. A Keyboard ?!?!?! – There is one instance in Tsuro where the user needs to enter text. This tiny-but-crucial feature meant that we had to implement a VR keyboard. Fortunately, we found a solution on the Unity Asset Store and were able to quickly modify it to suit our needs.

Systemic Mobile Achievment UI vs Custom VR Achievement UI Systemic Mobile Achievment UI vs Custom VR Achievement UI

3. Testing on Gear VR: Too little and too late

For some foolish reason we assumed that Gear VR had similar performance to the Go… this was a big mistake. Moving from Go to a Galaxy S7, we found a noticeable drop in frame rate. This required a deep optimization pass, and the creation of a few tiers of device-specific graphical quality which drop resolution, swap shaders, halve textures, tweak shadows and throttle the CPU/GPU accordingly.

A few key gotchas for graphics performance:

DO combine your environment into one mesh and disable dynamic occlusion culling.

combine your environment into one mesh and disable dynamic occlusion culling. DO use ASTC compression for your textures – experiment with the block size to get the best trade off between performance and detail (while most of our textures were best at 5x5, we dropped our fairly hefty light-maps to 6x6 for a considerable speed boost).

use ASTC compression for your textures – experiment with the block size to get the best trade off between performance and detail (while most of our textures were best at 5x5, we dropped our fairly hefty light-maps to 6x6 for a considerable speed boost). DO use the Oculus Lint tool (sooner rather than later!)

use the Oculus Lint tool (sooner rather than later!) DON’T use the standard shaders. Use the simplest shaders you can (in Unity these are usually the mobile shaders).

use the standard shaders. Use the simplest shaders you can (in Unity these are usually the mobile shaders). DON’T use Unity’s default skybox – use the mobile version instead, and bake the fancy colourisation settings into the texture.

use Unity’s default skybox – use the mobile version instead, and bake the fancy colourisation settings into the texture. DON’T use environmental lighting – it has no noticeable FPS impact on Go, but it killed the framerate on our S7.

...And finally, don’t forget that it’s crucial to watch your reviews during launch week! Have your team ready to deliver awesome customer service and rapid fixes to anyone who reports a problem!

What went right?

1. Low-poly Art Style

We initially wanted to match the environment style to the existing art from the mobile version. Experiments with hi-def environments revealed that we would have had to invest way too much time, and still have to compromise on quality. Fortunately, the Unity Asset Store came to the rescue…

We’d been researching low-poly art, and were already familiar with Synty, a great studio in New Zealand, who had a fantastic Feudal Japanese environment kit which was perfect for Tsuro.

This retro look has a number of benefits: first and foremost, it’s beautiful! Secondly, it’s highly performant - after a bit of tweaking, we were able to get Tsuro running at 1.5x standard resolution at 72fps on Oculus Go. Finally, we were able to find other high-quality, low-poly assets to add stylized skyboxes, distant scenery, particle effects, and even a little wildlife.

2. Focus on User Interface

The original UI for Tsuro had been specifically designed to hide unobtrusively at the corners of the screen, and there isn’t a screen in VR, let alone corners. We assigned a few early sprints to developing solid UI, which involved rapidly building, testing and iterating multiple UI permutations in a dedicated “gym”. This helped us identify and address a number of key issues…

Chose your font wisely - using an overly stylised font is a bad idea if you want legibility. We went with something that was clean, but with a playful, hand-painted feel.

- using an overly stylised font is a bad idea if you want legibility. We went with something that was clean, but with a playful, hand-painted feel. Keep your text short but clear - players can view UI from anywhere in the environment, which can make text legibility an issue. We experimented with a number of technical solutions to help with this, but the best technique was to keep wording concise, so the font could be as big as possible.

- players can view UI from anywhere in the environment, which can make text legibility an issue. We experimented with a number of technical solutions to help with this, but the best technique was to keep wording concise, so the font could be as big as possible. Fake the lighting - If your UI needs to move with the player, it will probably need to be lit. We ended up manually faking the lighting for static UI elements, and used a scripted approximation to dynamically recolour UI that moved about.

- If your UI needs to move with the player, it will probably need to be lit. We ended up manually faking the lighting for static UI elements, and used a scripted approximation to dynamically recolour UI that moved about. Use UI to focus, not distract the player - locking UI to the player is uncomfortable, but our main UI needed to be visible at all times, from any position. To get around this, we locked it to the player’s position, but always made it face the point of interaction on the board; this had the extra benefit of focusing the player’s attention. It also re-orients itself horizontally based on player elevation, so the game area is always unobscured.

3. Cross-platform Multiplayer

Tsuro players on Oculus Go can battle it out with their friends on phones and tablets! We’ve had great feedback from VR gamers who use this feature to play against the non-VR people in their house. It also means that we already had thousands of players ready to auto-match at launch.

To achieve this, we use two bits of off-the-shelf tech: Photon Networking and PlayFab. Both systems have been specifically designed to work well together, and are cheap as chips.

Photon handles the actual online gameplay (setting up rooms, transmitting data, etc.) and PlayFab manages authentication, friends, match-making, and persistent game states; it can also get info from players’ accounts (Facebook, Steam, Game Center, etc.) with a generic option that integrates nicely with Oculus.

4. Working with the GOmmunity

We were very lucky that one of our early testers pointed us in the direction of the GOmmunity on Discord, which turned out to be absolutely invaluable.

These lovely people have played pretty much all of the games available on Go. They were able to inform us on key features we were missing, and show us which games implemented them the best.

Thanks to their recommendations, we were able to refine the locomotion system, create a rock-solid on-boarding experience, and implement Coordinated App Launch via Oculus Rooms (this was super easy to implement, as it meshes really nicely with Photon).

To Conclude

We believe that the VR version of Tsuro is the best way to enjoy the Game of The Path… digitally at least! We’ve had a lot of fun bringing this great little strategy game to VR, and we hope to give similarly immersive treatments to more board games in the not too distant future. As our first foray into VR, Tsuro was designed to be an experiment: a relatively short project that would get us the necessary experience to approach more complicated VR games; all the expertise and new tech that has gone into Tsuro (Art style, UI, locomotion, testing, optimisation, framework, etc.) will definitely be reused in our next VR game. Which is already coming along nicely…

- Dan Taylor

Design Director

Thunderbox Entertainment