Recently I’ve been developing a small piece of tech for a secret game concept we’re workng on over here at Hyper Luminal, and I think I’d like to take some time today to talk about it somewhat. Let’s get started.
The concept of infinitely scrolling worlds should be something very familiar to anyone who’s ever played the classic game Asteroids. In Asteroids, the player flies a spaceship around a screen, and when the ship flies out of one side of the screen, it appears on the other, with the same velocity and orientation, as though the two sides of the screen were continuously connected.
At its core, this is essentially the behaviour I needed. However, our game required a full 3d environment and a camera the follows the player, rather than being fixed. This presents a few problems. Asteroids achieves its scrolling by simply teleporting the player to the opposite side of the screen once it has left the viewport. This works well, as the player is completely hidden by the window bounds when the move occurs.
For us however, our 3-dimensional camera means that the player will be able to see “off-screen,” into the void when nearing the edges of the map, as well as being able to clearly observe any edge to edge teleports that may occur. Obviously a big problem with this approach.
The Edge of the world
To address the first issue, lets imagine what the little spaceship would actually see when looking off the edge of the world. Since the world loops back on itself, he would see a copy of the world behind him projected in front of him, hell, if he could see far enough he would even see the back of his own spaceship!
So, we need a way to allow the player to see what is behind him as though it is in front of him. Unless we want to completely replicate the game-world in front of the player, the best approach here is to fake it with camera trickery.
To do this, one places a camera behind the player, exactly one world-width away. Imagine the player was the repeated version of himself we mentioned earlier, and the offset camera is the viewport of the actual player. Confusing I know. This camera follows the player, maintaining relative distance and orientation, so it’s view will always line up to what should be in the edge of the world void out in front.
Now, by overlaying this new camera on top of the already existing image from the camera following the player, and transporting the player to the opposite side of the world when it crosses the boundary, we get the illusion of a scrolling world. Neat!
Some of you might have seen a problem with this though. Sure, it works fine when moving forward, but what if the player is moving backwards, or sideways, or diagonally? With this 2-cam setup, you’ll still end up catching glimpses of “void space,” especially at the corners of the world.
The solution to this, as with most things in life, is more cameras, 7 more to be precise. That amounts to 1 for the player, 4 for forwards, backwards, left and right, and then 4 for the corners. True, it’s a little fiddly to setup, but it works in the end.
After all that, you end up with something like this : LINK