It has been several months since my game Gravity Voyager released in App Store. Gravity Voyager. In Gravity Voyager, you should drive your spaceship traveling the space while avoid being pulled into stars by their gravity. Today I gonna to share something about game design of Gravity Voyager at here.
So firstly, you may wondering how the idea of Gravity Voyager came from? The idea of Gravity Voyager is originated from the course design of Introduction of Game Design in my university (I majored in Digital Media Art in my university). The idea is simple but elegant: Reach the goal, avoid being pulled into stars or black holes. And as the position varies, strength and direction of gravitational force changes too. If your spaceship near a star, you can feel a strong force trying pulling your spaceship into the star and vice visa. If your spaceship lies between two stars, you may not feel there is whether a force because gravity of two stars cancel each other. Stars can rotate around other star or even form a double star system. You can see, the basic idea is simple enough, but it can generate a lot of interesting details.
No ideas comes from vacuum. The idea of this game is inspired by…. an iPhone game called Labyrinth, a game that you control a steel ball by tilting a wooden labyrinth (using iPhone built-in accelerometer to control). This game is very popular during 2008-2009. I have played this game on my iPod touch and it is very addictive. In Labyrinth, you should keep the steel ball from falling into holes. So I wondering how about add something like “gravity” to these holes? This is how the basic game idea originated.
Actually I have made a simple early prototype using Unity while finished the course design, you can clearly see the influence of Labyrinth:
The core concept of Gravity Voyager is of course “Gravity”. Recall what we learned during senior high school, the formula of Newton’s law of universal gravitation is F = GMm / r^2, i.e. the force between two object is a proportional to the product of two masses and inversely proportional to the square of the distance between them. This is really easy to implement in Unity game engine using built-in PhyX system via scripting. In formula the factor G is the gravitational constant and we can simply assign it with 1.0 for convenience. The distance between spaceship and a star can get through subtract two position vectors and get the length of it.
However if we use this physics model directly, there is a noticeable problem: If our spaceship is not not close enough to a star you hardly feel any gravity but in contrast, if your spaceship near a star you may not possible to escape from the gravity field of the star since the intensity of gravity is two strong where near a star. So I made a modification: rather than using inverse square of distance, I use inverse of the distance. So the final formula using in this game is F = M * m / r. In each physics loop of game, it calculate the sum of all gravitational force between spaceship and stars, and apply to spaceship.
(You may wonder how objects behaves if gravitational force between two objects is proportional to the inverse of the distance, rather than inverse of square of the distance. This is quite interesting. In this circumstance, the second cosmic velocity of any star is INFINITY, since the integral of gravitational potential is not converge while distance approach to infinity. That means a spaceship can not escape the gravitational accretion of a massive body, whatever how great the launch velocity of. A good explain of this problem: https://www.zhihu.com/question/26941982)
The spaceship in this game is controlled via dynamic system rather than kinematic. In another words, it controlled by forces applied to the spaceship. You controllingyour spaceship flying to the right means game engine apply a force toward to the right to the spaceship. Turning and decelerating mean apply a force which the direction differ from the velocity vector. In early game prototype, there is no limit of spaceship’s speed. You can accelerate your spaceship to infinity if scene is large enough. However, several problems occurred. It is hard to turn and decelerate while the speed is quite high. And while I did an play test, I find some player just accelerate the spaceship to a high speed to rush into the goal. So I add a drag force later. Drag is proportional of spaceship’s current speed, toward the opposite direction of current velocity. Suddenly it is much easier to control and prevent player from cheating via “rush” tactic. It becomes a huge improvement of game design.
Stars and Star Systems
Another concept is stars. There are 6 types of stars. Each type of star has different size and mass. Stars is the main obstacle in the game. You can not let your spaceship being pulled into a star. But sometimes stars can be your good friend. For example, you can use gravity of a star to accelerate your spaceship during a short time to pass another star easily.
Each level has unique formation of stars. Strength and direction of gravity varies in a scene so while a player playing the game, she/he should always keep focus on the movement of the spaceship. A star’s can cancel another’s gravity, that allow me to carefully make a “tunnel” in many stars, that simplified a level while add some complexity, kill two birds with one stone.
Naturally stars can form star system. A star can spin around another star. Of course multiple stars can rotate around one another star. Two stars can even rotate around each other (barycenter). A star system can be a parent of another star system. While a star is in motion, gravitational field changes too. That make game more interesting and challenging.
According to Kepler’s law, orbit of a star is a cone section: ellipse, parabola, hyperbola. In this game, we only consider the close form: ellipse. While a star spin around another, the orbit is ellipse and the barycentre is the focus point of this ellipse. The speed is higher while it is close to the focus point and vice visa. I modelled this behaviour using kinetic method, via parametric form of ellipse (x = a * cos(t), y = b * sin(t)). The speed spin around is the inverse of distance between two stars. It is not physically accurate but it works, and using much less CPU cycles than using dynamic model.
There is a special type of star: black holes. When I making black holes, I faced a touch decision of how it look like. Should it distort starry background or just appear nothing? Finally I decide it should have no appearance. It may boring, but add the complexity: you can not find it directly, you can only “feel” it. So I add black holes in last 10 levels.
Scene in every games should have boundary, whether it is explicitly or implicitly. In early prototype you can see above, scene has a clear solid boundary that can bounce off. But lately I changed to this, using red grid indicate there is the boundary.
Player can not across the boundary or she can be penalised restart the game. The purpose of this is make game more challenge and also natural: because there is not solid boundary in the space.
As I said before, Gravity Voyager is inspired by Labyrinth. In early prototype, player can only control spaceship by tilting their device, like Labyrinth. Later I wondering how about let player can control via virtual joystick? It proved is much better than accelerometer. Using virtual joystick, player can control spaceship more precisely and don’t look silly while playing in public places. So I made it default but player have option choosing control spaceship via accelerometer in Game Setting interface.
Once you finished a level, the game save your best record of length your take. The next time you play this level, you will see the bar above indicate your record. That let player trying beating their record and also give player a pressure, make this game more interesting.
Once after finished a play test, a player told me whether should add something else, such as let player collecting stars. I accept this advice and result is unexpected good. It add another dimension to the game, while player trying to reach the goal, she should also has an option whether collecting stars. If she collect a star, she may not finished the level. So this change made game more challenging.
Level Design in Unity Editor
In order to design level more effetely, I made some custom gizmos attach to the game objects. As you can see above, there are:
- Indicator of the level boundary.
- The orbits (purple circles)
- Intensity of gravity of stars (blue circles)
- Gravity field indicator (red lines)
You may noticed there is a white cross in the scene:
This is an indicator of ellipse orbit. The long and short lines represent major and minor axis of the ellipse orbit. In Inspector, the values named A and B are the length of major and minor axis.
That’s all, thank you for reading! If you are interested in visual design of Gravity Voyager, you can also check my previous article: http://www.zhangboning.me/blogs/2016/4/12/gravity-voyager-making-of-starry-background-and-node-based-image-compositing