AsteroidsVR – Game Pacing & Boss Orbital Mechanics

For a while, I’ve been working on AsteroidsVR, a 3D adaptation of Asteroids for Steam VR & Unity.  Right now, it’s mostly me learning about game dev / design for VR games – and trying to make something fun along the way.  This is the first in what will most likely be a series of posts talking about the game’s design challenges and interesting technical things along the way.  Of course, everything in here should be considered a work in progress.

In this post, I’ll talk about the game concept, plus a “boss” enemy I’m adding to the game – motivations for adding it, as well as some technical details on how it works.

AsteroidsVR’s concept is pretty straightforward.  It’s Asteroids, except:

  • It’s in 3D & VR
  • The ship is attached to your hand / Vive controller
  • Asteroids are 3D physics objects that can collide with each other and tumble around
  • Asteroids are generated procedurally and break by cutting the generated mesh – so they’re all sorts of shapes and sizes
  • Asteroids bounce off walls instead of wrapping around (helps with motion sickness – more on that in a future post)

I’m pretty happy with the look and feel – Especially since the “bloom” caused by the VR headset lenses looks a lot like scattering on the original arcade cabinet’s vector monitor.

However, there is a bit of a pacing problem I’m running into – which is most of the reason I haven’t published the game yet, even though it’s largely playable.  The problem appears to be a fundamental consequence of moving to 3D, and seems like it will require diverging a lot from the 2D inspiration to solve.

The core gameplay in the original 2D Asteroids is, in my opinion, the player trying to manage chaos.  Shooting rocks makes more fast-moving smaller rocks, so the player needs to be careful with their shots, else they’ll spend a lot of time losing.  The game is at its most exciting when the player is just at the cusp of being overwhelmed by the sheer quantity of rocks in their face – then, as they start to clear the screen, they are granted a brief reprieve before the next level.

In VR / 3D, things are a little different – and these differences are at the heart of the pacing problem.  For one, dodging obstacles is much easier in VR: instead of clumsy thrust mechanics, your ship is attached to your hand, so agile movement becomes a major part of the game.  Plus, since so many more asteroids can fit in a 3D volume compared to a 2D plane, many more asteroids are needed for the game to stay exciting.

So, just like the original game, when the player starts shooting asteroids in VR, their quantity and speed increase – until the smallest asteroids start being destroyed, and the total number in play starts to decline, along with the difficulty.

Number of asteroids in gameplay, over four levels of increasing difficulty.  Green marks rising difficulty in a level; red denotes falling difficulty.  Issues arise when the red “tail end” of a level extends too long.

This is where the problem begins in VR.  The player has gotten used to staying alive at the peak of chaos; after this, with fewer asteroids, the level gets progressively easier… and stays that way for a long time.  A reprieve isn’t a bad thing, but since we needed many more asteroids in the volume than in the 2D original, the tail end of this cleanup can get very, very long – if the rising end is about 3-4 minutes, the cleanup could take 10-15mins, even with power-ups or other mechanics to hurry the game along.

 

This is where the boss comes in.  The idea fell out of a discussion with some friends and co-workers – detect when this count of asteroids is falling, and at that point, throw in a powerful enemy to shake things up.  Instead of becoming bored once the asteroid count starts to fall, the player would instead anticipate the boss’ entrance, and the fight could be exciting by itself.  Bonus points if, by its presence, the boss also helps clean up the remaining asteroids.

My initial concept was something that would pull any remaining asteroids into orbit around itself – using them as a shield while somehow also presenting a danger to the player.  That way, the player still ends up shooting all the asteroids.  So, add some gravitational force to a placeholder boss object, throw in a bit of vector math to find velocity components with respect to each individual asteroid’s orbit, add a simple proportional controller applying thrust prograde/retrograde to push the asteroids into place, and…

…Wait.  Right.  Rings.  That’s a thing that happens.

In this case, the ring formed for the same reason real rings form in space, and why real orbits tend to share the same plane and orbit direction.  In aggregate, there is some mean angular momentum in the system with respect to the boss object’s gravity; as all the asteroids collide with each other, this angular momentum is averaged out, and we end up with everything sticking together in a nice ring.

So, while looking very cool, such a ring isn’t very useful as a shield, since it probably won’t face the player… unless the boss could actively turn the ring to lie in plane with the player, so that it stayed effective.

A bit of Kerbal Space Program-esque math later, we can define ascending and descending nodes in the orbit plane with respect to the player, and apply the necessary thrust to turn the rings.

In that video, the thrust applied to turn the ring is drawn with white lines in the debug view on the left; the magenta lines are pointing at each asteroid’s individual ascending and descending nodes.  Forces are applied so that the ring tracks between the player’s ship and the “core” of the boss at all times.  The math is applied individually, per-asteroid.

Is all this math really necessary?  Probably not – it might’ve been easier to just directly animate or interpolate the asteroids into pre-defined positions.  But I think there is some charm in forcing it to work with the overall physics simulation.  At a bare minimum, it looks more “reasonable” to me.

Next up is to write more boss logic – have it move around, for example, and perhaps attack the player somehow.  Currently thinking of having it fling asteroids in the player’s direction via changing individual asteroids’ orbits.  If nothing else, it would give me more opportunities to play with orbital dynamics.  =]

About the Author