Shield Runner
Project Description
Shield Runner is a virtual reality auto-runner game. Use your dual-wielded shields to block incoming
projectiles, and try to run as far as you can before the turrets shoot you down.
Shield Runner is built using PlayCanvas, a browser-based game engine. A VR headset is required to play.
On your headset's native web browser, navigate to this page, scroll to the bottom, and click "PLAY NOW IN VR"
to play the game!
Project Goals
I worked on this project with 3 goals in mind:
- To experiment with PlayCanvas to see what the engine is capable of.
- To challenge myself to create a game using less than 1GB of assets.
- To create my first solo VR game project.
Challenges faced
As computers are really powerful these days, I typically do not struggle to get my game projects running smoothly.
However, it is a completely different matter when I'm targetting VR headsets instead of laptops or PCs. These days,
commercially-available headsets such as the Meta Quest 2 and the Pico 4 run off integrated graphics, making it
difficult to render high-quality 3D graphics while maintaining a smooth and consistent frame rate.
Another challenge I faced was how tedious debugging a VR project was. For 2D and 3D projects, logging debug messages
is simple and easily readable. However, with a VR headset on, I couldn't test the game and read debug messages simultaneously.
What I learnt
After trying my hand at PlayCanvas, I found that it brings certain advantages over other game engines like Unity.
First of all, PlayCanvas comes with native WebGL support. Anything I build can instantly be hosted on PlayCanvas and
accessible on any browser.
Secondly, being a browser-based engine, all projects assets are stored on the cloud, allowing me to free up local storage.
Although, this comes with its own drawback, which is that I have to pay for a subscription if I want to store more than 1GB
of assets on the cloud. This was also why I wanted to keep my asset files under 1GB.
Thirdly, PlayCanvas features live development, which is a really useful tool. It allows changes on my script to be reflected
in real time while the game is running.
Finally, PlayCanvas does not need to compile scripts. I can launch the game right after editing scripts and the game launches
immediately, allowing for really quick iterations.
Creating a game with limited assets means that I have to capitalise on game mechanics instead of graphical fidelity. I chose
shield-wielding to be the main mechanic as I had a lot of fun with shields in Blade & Sorcery and I felt that it could well
leverage the 3D nature of VR games. I also resorted to using primitive shapes instead of 3D models as they take up much less space.
To optimise the game, enough for it to run off a VR headset's built-in hardware, was quite the challenge. However, through this
struggle, I learnt a lot about computer graphics. I used batching to merge many models into a few mesh instances to reduce draw
calls, which improves performance. I also reduce the number of light sources and disabled shadow casting as it is expensive. To render
shadows, the engine has to create a shadow map, which involves rendering the scene from the light source's perspective. When there are
multiple light sources, each of them will need to create a shadow map, which further increases computational workload. In addition,
I also avoided using mesh colliders, and opted for colliders with primitive shapes instead, as the game does not require extremely
accurate collision detection.
Aside from tweaking graphics and physics, I also adjusted the game mechanics to improve performance. I controlled the number of active
turrets in the game. Initially, I spawned turrets really far ahead of the player, which resulted in a huge number of turrets being
rendered on screen. After halving the spawn distance from the player, the number of turrets was reduced. This did not affect gameplay
much, as the turrets that were far away were really small and hard to see anyway. One other way I improved performance by tweaking
mechanics was when I was trying to increase difficulty over time. My initial idea was to spawn turrets at shorter intervals, which
increases the number of projectiles, making it harder for the player to block them. However, this eventually results in a tsunami of
turrets and projectiles, causing the game to lag severely. To fix this, I opted to increase the speed of projectiles instead. This way,
the game becomes more difficult while keeping the same number of turrets and projectiles.
Finally, to aid in debugging this VR project, I used the WebXR plugin on Mozilla Firefox. It allowed me to simulate movement of a
VR headset and its controllers, which was ample for this project. This way, I could easily read console logs while running the game.
All in all, I am happy with this project as I have completed all the goals I set out to achieve. However, I am not done with Shield
Runner, and I will be continuing to improve it over time.
Play now in VR!