In Sliding in the Deep, the core development task is to procedurally generate the tunnel. In our design, the tunnel has two varying parameters, the longitudinal direction and latitudinal curvature. We want to make our tunnel turn left/right/up/down randomly. And its shape can also vary between a complete circle and a plane. Player will move inside the tunnel if its curvature is positive and outside the tunnel if its curvature goes negative. We want the tunnel direction and curvature change smoothly.
The basic idea is to derive a section of tunnel from a procedurally generated cubic Bezier curve, namely, the guide curve. This guide curve will determine the general shape of this section of tunnel. Its start point coincides with the end point of last guide curve. Its end point is randomly picked. We want our tunnel to always develop along the +z axis, so we keep our tangent of two endpoints be (0, 0, 1) * constant.
The basic idea is easy and straightforward. But we did meet challenging problems when implementing this idea:
1. How to describe the tunnel’s curvature?
Most of the time, the tunnel is an arc of a circle (or a complete circle). But things goes messier if current curvature is 0, which means the tunnel degenerated to a plane. We can no longer treat it as arc since its radius will be infinity.
2. How to ensure uniform speed?
The speed of player moving along the curve is an essential element in our game. It will only be affected by the interaction between player and obstacles or accelerators. We actually want our player move a contestant length of curve in each step (If it doesn’t get accelerated or hit an obstacle). If using Bezier curve, the naive method to deal with player movement is to use the Bezier parameter t. But for Bezier curve, uniform change in t doesn’t mean uniform speed.
3. The workload of tunnel generator is not uniform. Next section only needs to be generated if player get near to the end of current section. But the generating process needs heavy computation. Simply call the generating function when player move towards the end will make the game get stuck for a very short time. This is annoying and will make our user experience quite bad.
The method we used to solve those problems and more implementation details will be given in the following blog.