Endless Globe

Programming and World Design · 5 minutes Read

Capturing the feeling of an infinite globe through visual trickery and camera manipulation.

Being able to be adapted to any game dimension, an endless globe allows completely new mechanics to surface.

Games contain a variety of worlds that, to this day, get throttled from the technical and scope related applications of the hardware. Even games like Red Dead Redemption II that push the very concept of a realistic world to preposterous ends still contain elements that leave the player tumbling out of their pre-defined magic circle back to reality. This idea initially started as a project to create a realistic world that replicated reality, one that, if a player walked too far north they wouldn't just fall from the map, but end up at the bottom of the map seamlessly, and so on. At its core, its quite literally just smoke and mirrors, but when joined with mechanics such as Pathfinding, whereupon clicking on an area the algorithm utilises the world edge to calculate the shortest path, to a player that knows they never have to turn back, it allows this simple system to create bundles of new core mechanics and experiences. In this post, I'll cover how to implement this mechanic yourself, as well as ways to adapt it to 3D.

Part 1: Implementation

The first step to projecting an image of a Camera onto a texture or plane is by utilising shaders in Unity. I won't go into detail for what the shader contains except these six variables, each of which allowing the texture to be written to the correct depth buffer. Upon creating this shader, simply attach it to a texture, and attach that texture to the Plane, making sure each Camera contains the correct gameobject in its Target Texture.

	"Queue" = "Transparent" 
	"IgnoreProjector" = "True" 
	"RenderType" = "Transparent"
Lighting Off
Cull Back 
ZWrite On 
ZTest Less
Fog { Mode Off }

Due to the planes acting as a mirror, it's impossible to align both planes directly next to each other. This can be solved by simply adding a gameobject in each corner of the world. Later you can replace these objects with mountains or other landmarks, and upon the player reaching it, would be able to tell they've reached one of the edges. Unfortunately, this is the last remaining element that I have not been able to work around as pointing two mirrors against each other simply returns a paradox.

Next, we align each camera to face the direction of the plane, and attach this script to each of them, updating their positions based on the main Cameras and portals positions as it moves around. Make sure to make the main camera teleport upon reaching one of the edges of the portal, this can be based on the grid size subtracted by the size of the planes. Likewise, once you create units and AI, you can implement the same seamless teleportation once they reach an edge.

public void Update ()
	// Updates the position to be offset from the other camera
	Vector3 offsetFromPortal = Camera.position - portalB.position;
	transform.position = portal.position + offsetFromPortal;

	// Updates the rotation based on player camera 
	float angleDiff = Quaternion.Angle(portal.rotation, portalB.rotation);
	Quaternion rotationDiff = Quaternion.AngleAxis(angleDiff, Vector3.up);
	Vector3 cameraDir = angleDiff * playerCamera.forward;

	//Updates the rotation to be offset from the player 
	transform.rotation = Quaternion.LookRotation(cameraDir, Vector3.up);

Once again, it's as simple as that. Upon scrolling the camera to the edge of the world, it will teleport without any visual indications. Since this texture is also rendering real-time, it allows units that are moving to simply walk over it and be rendered to the other side, creating the feeling of an infinite globe through the use of smoke and mirrors.

This experiment was immensely fun to make and allowed me to take an old RTS genre and add a mechanic that allows for a new variety of gameplay. To transform this to 3D simply re-assign the planes to be upright rather than face down, making sure they're facing directly where the camera is pointing.