How I made a VR game in three days at Ludum Dare 39
Articles
Automatic translation of the archived Russian text. Recordings and text within images remain in their original language. Read the Russian original
About this material
A postmortem of an HTC Vive game made in three days for Ludum Dare 39, covering arm-swing locomotion, the sense of scale, production constraints and playtests that require equipment and participants to be arranged in advance.
Almost a year has passed since my last Ludum Dare, when my team and I prototyped and began developing SMASH BASH: Date with the Desert. Since then there had not really been a reason to enter again. Recently, though, I got the chance to develop for HTC Vive, and I could not pass it up. In the end, I made my own VR game in three days and enjoyed playing it myself. If you have an HTC Vive handy, I recommend playing the game before reading on.
To me, it is fairly obvious that VR, AR, and MR will become firmly established in everyday life in the next few years. Today the technology is at the same stage as every other technology that changed our lives: geeky, expensive, inconvenient, slow, but working and producing results. What clinches it for me is the ARKit Telegram channel from Luden.io, showing what can be done using the latest iPhones—devices already in millions of users’ pockets. Rumours are already circulating that Apple, Facebook, and Google are working on their own versions of Microsoft’s HoloLens: similarly standalone devices, but affordable and available at the nearest mobile phone shop. This stuff is going to burst into our lives at breakneck speed, while some VR/AR games still have game design at the level of “a normal 3D game you can look at from different angles.” So I wanted to improve my VR game-making skills a little, rather than be left behind. That desire first arose while I was teaching my students on the Unity game development course at Scream School. I devoted one class to introducing them to VR. In three hours they went from “putting on a VR headset for the first time” to walking around a world they had just made themselves. During the class I had the idea of attaching a light source to one controller and turning off all the other lights in the scene. Less than a minute of adjustments, and suddenly I had an excellent horror game. A shot from the Ludum Dare game. The desired effect achieved.
Before Ludum Dare began, I already knew I wanted to repeat that experiment. As a test, I put together a small scene from free assets and became even more convinced by the idea. For gameplay, I tried this: you have to find the exit from an area containing a monster that slowly but relentlessly follows you. A sort of labyrinth with a Minotaur. I implemented movement through teleport points to slow the player down a little, since you have to aim at the right point. Pressing the teleport button made every teleport point visible, even behind obstacles. With several dozen of them, the level started looking like a Christmas tree. I had to dig into the code to hide points beyond a certain radius around the player. On Saturday morning, 29 July, I learned the jam’s theme: Running out of Power (running out of energy or strength). Since I already had a concept prepared, I had to force the theme to fit. It was supposed to be dark, so the power must already have run out. Why? Because a dangerous enemy did it. What enemy? Well, I cannot really model, so I assembled an abstract enemy from flying cubes. I called it “Project 424,” thinking of creepypasta and SCP. Since my goal this time was to learn to work with VR, I decided to skip creating basic assets and use the Asset Store. First I browsed environment-building asset packs and settled on this pack, which was fairly cheap, varied, low-poly, and straightforward. The last thing I wanted was to get stuck with poor performance. The chosen modular kit later turned out to have several significant drawbacks: — The materials used obsolete shaders and had to be set up again. — Most objects share one material, which can greatly improve performance if you remember to enable instancing. But when stone and metal share a material, either the stone is not really stone or the metal is not really metal. — Every object has a default scale other than 1, and the objects are upside down by default. Clearly there were problems setting the correct dimensions in the 3D editor and exporting properly. — Although the whole point of a modular kit is for the pieces to snap together on a grid, several pieces of one building simply did not fit and left obvious gaps. I had to avoid them or move and scale them manually, which is bad practice. — Typos in filenames were a real facepalm, and caused practical problems because quick search could not find those files. — The pack has no light-source models at all.
A small part of the environment made with this kit.
Still, for $5 those problems were tolerable. I paid another $2 for a flashlight model. No complaints there at all: an excellent flashlight. Then I spent another $25 on a script pack for different VR character movement methods—locomotion. I found the remaining assets among the free ones: — The night sky from this pack. — A lava material to use on enemies. I needed a material with an attractive emissive glow. — A modular kit, from which I took lamp models to provide light sources. — A very high-quality pistol model. Its moving parts let me make a firing animation. I fiddled with it for a while before realizing that such a short animation did not need blending with the idle state. I also had to tinker with both the pistol and the flashlight to add emission, so you could see your hands even in total darkness. — A car model. I wanted to connect the starting location to the beginning of the game. — An effects pack, from which I took the impact effect. I had to tweak it a little to get the size right and make gravity affect the particles. — Gunshot sounds and ambience, mostly from https://freesound.org/
The pistol’s materials are really gorgeous, but you only notice them in the right light.
I quickly lost enthusiasm for teleport-based movement. It would mean placing hundreds of points throughout the level, testing them, and then watching artificial gameplay markers appear in the world every time I teleported. But immersion is the beauty of VR, and I wanted to preserve it wherever possible. I liked the movement in GORN, where you move by swinging your arms. Fortunately, the Asset Store had an arm-swing solution, though only one, and it had problems. Problems I was surprised to encounter included: — Some functionality was labelled Coming Soon. Fortunately, these were movement methods I was not interested in. — The code explicitly referenced Unity 5.6, causing errors in 2017.1. — Arm-swing movement worked only for the left hand. I had to add the right hand myself. — Although the description says the pack is based on SteamVR, it is not actually compatible with Valve’s solutions. Interface interaction, for example, does not work with it. I wasted a lot of time trying to make Valve’s interface code cooperate with these controllers. It did not work, so I resorted to a workaround: a trigger around each button that responds when the controller enters it. — The unclear manual lives in Google Docs, linked from the package files; I could easily have missed it. I still had to rack my brains to find where movement parameters were configured, because they are not on the character but on a camera buried deep inside it. — Arc teleportation is broken: it can teleport only about a metre, and looks ugly too. Fortunately, I wanted to abandon teleportation anyway. Still, the pack saved me by allowing reasonably comfortable, free movement over any surface covered by a NavMesh, which I needed to calculate for the enemies anyway. Narrow stairs were a problem: there was a high chance of slipping past them rather than climbing them. So I avoided making stairs central to the gameplay. Movement was only in the direction you looked, but that turned out even better than GORN, where sideways movement made me a little nauseous. The red cubes are enemies. If even one touches the player, that is it: game over.
I made enemies like this. Each enemy spawns a cluster of cubes within a small radius. Each cube can rotate and change scale randomly. When a bullet hits a cube, it enables physics and flies off accordingly. Once the enemy has no cubes left, it is dead. I added a sound and a light so you could react to its approach and recognize its death. It turned out pretty creepy. Initially enemies are very slow, making them creepier still, but their speed increases with every cube shot off. Further into the level, enemies have more cubes, so they move extremely fast when only the last few remain. By adjusting the balance, I could create situations I could not survive myself, but I decided not to overdo it for Ludum Dare. I spent a long time thinking about the player’s main objective. I kept thinking of Slender and its task of finding eight notes, but I wanted something of my own. By the middle of the third day, nothing good had occurred to me, so I simply covered power-line pylons in the same pieces the enemies were made from. Shoot every piece off a pylon and the lights come on in part of the level. Clear all three towers and you win. Not a brilliant solution, since it leaves a huge portion of the level unused, but it works and is intuitive for the player. Brightness is increased in this screenshot and you still cannot see a damn thing; in the headset, at the original brightness, everything looks fine.
Speaking of enemies and shooting them: at first I liked the idea of one unbeatable enemy you could only run away from. The film It Follows handles that idea brilliantly, along with its sexually transmitted curse. But once I began making the game, I realized such an enemy is frightening only at first, then becomes predictable and boring. Besides, to avoid motion sickness the player should occasionally stop moving. That meant giving them something to do. Shooting is a mechanic that reveals the distinctive qualities of VR controls. So I decided: why not shoot things? I needed something for the hand not holding the flashlight anyway. I chose not to complicate life for myself or the players with cooldowns or reloading. At least here we could fire away to our hearts’ content. Usually I put so much into Ludum Dare that it takes me a week to recover. This time, though, I was already exhausted before the jam and had a busy week ahead, so I jammed the way musicians do: unhurriedly, enjoying the process. On day one I thought through the idea, considered assets, planned the overall level, and in the evening even went to the DevsGo game developers’ meetup, where I unexpectedly ended up among the speakers.
Left to right: me, Alexander Pashin, Ilya Tumenko
The second day was the most enjoyable: I spent most of it doing level design, assembling the environment. A very calming activity, like building with Lego.
An overall view of the main level in daylight.
Day three, however, was painful, because it was time to implement functionality. I had to iterate a great deal: change something in the code, put the headset on to check, adjust settings, then put it on again. Switching realities so often throws you off a little. When I went to the shop that evening, I kept catching myself thinking I was moving too fast and might crash into a wall in the other reality. Overall, everything went smoothly. There were only two problems. I mentioned the broken interface interaction above. The second was light baking. I am no expert in Unity lighting, but I thought setting Directional Light to Baked would improve performance. Instead, after lengthy shadow calculations even in a small scene, the shadows vanished. I had to switch the lights back to Mixed. For some reason the built game also launched at Very Low settings, even though I had set Very High as the default. I had to bring back Unity’s startup launcher so graphics quality could be selected manually. All that remained was to record a gameplay video for people without an HTC Vive, take a batch of screenshots, and put together the game page. That is exactly what I did, bringing my Ludum Dare participation to an end.
Yes, VR is the technology of the future. It is not 3D cinema, where the effect served marketing and caused irritation rather than immersion. This creates a sense of immersion that cannot be achieved any other way.
VR games involve physical movement. That is healthier than sedentary gaming.
Arm-swing movement works, causes no nausea, and is better than teleporting on every count. Though perhaps I am judging by myself, since my body is already somewhat used to VR.
The image looks brighter in the headset than on the screen. This needs to be accounted for by brightening the monitor image somehow; otherwise watching these games from outside is uninteresting: nothing but blackness.
Making VR games is not difficult at all. All the basics work out of the box.
I need a wheeled desk that can be rolled into the VR area, so I can test features without running back and forth.
VR testing intensity needs to be controlled. Constantly putting the headset on and taking it off is no fun. Test some functionality, then switch to content work.
Fine detail is not what VR is about. The resolution is mediocre, so detailed assets turn to mush while low-poly assets look fine.
And in general, what matters is not detail but the sense of space.
I need to write my own locomotion system that works with SteamVR and its features.
I did not hit a performance bottleneck, which is good. Thanks, Unity.
You cannot playtest a VR game just by sending friends a link. Plan ahead so testers can be at the development location, where the equipment is available.