BodyaInvade MSC:Nightmare Game
BODYAINVADE | BCT#2533When we talk about the architecture of a game, we mean how the code works. A good architecture can help us avoid problems such as poor performance, long load times, or code that is difficult to maintain.
The best architecture for any game depends on the game itself. An online multiplayer game that is being worked on by a large team has very different needs than a single player offline game that is being worked on by one person.
Let's take a look at a couple of key elements of the Mutant Shiba Nightmare architecture.
We will look at how the code works and what problems it solves.
GameManager.cs is the class that manages the overall flow of the game.
GameManager uses a design pattern called Singleton . The Singleton pattern is a way to ensure that there will only be one instance of a particular class in the game. This is useful when the class has an important responsibility, such as the GameManager. It also makes it easy for any other class to access this instance with a public static reference.
The GameManager is also an example of a state machine. The state machine ensures that the game can only be in one state at any given time, and controls what happens when that state changes.
In Mutant Shiba Nightmare, hundreds of coins can appear in one game session. Instantiating and destroying large numbers of objects at runtime can have a negative impact on performance: it can involve relatively expensive code, and can lead to frequent and time-consuming garbage collection.
To reduce this overhead, Mutant Shiba Nightmare uses a technique called object merging. Object merging is a technique where objects are temporarily deactivated and then recycled as needed rather than being created and destroyed.
When the game starts, several inactive game objects are created with coins, which are placed in the "pool". When a new coin is required, it is requested from the pool and activated. When a coin is collected or leaves the screen, the coin is disabled and returned to the pool.
In any game where the player travels long distances - like space exploration games or "endless" games like my game - the developer must make a decision about how to handle the player's position. If we just move the player's GameObject, the values in the player's transform.position will get higher and higher over time. This can lead to problems due to the so-called floating point inaccuracy.
Floating point imprecision means that the larger the value of a floating point number, the less accurate it is. This is a limitation of how computers store numeric data and is not unique to Unity. In a game with a large or infinite play area, the floating point numbers used to store positions can become large enough to cause problems. If game objects have inaccurate values for their position, they may move, flicker, or appear and disappear.
There are several ways to solve this problem, and which one is better depends on the game. In Mutant Shiba Nightmare, we address this issue using a technique known as source reset. This means that once the player moves a certain distance outside the world origin (i.e. world position 0, 0, 0), we move everything in the Scene back to the origin. This ensures that the values used for positions always remain low and therefore not subject to inaccuracies. Resetting the origin is seamless and the player is unaware of it.
In this game, we create an endless path by creating sections of the path in front of the player and removing them when they are behind the player. If the player could see far ahead, we would need to create many path sections in advance. This can lead to performance issues.
On top of that, the world is full of coins, obstacles and characters. Again, if the player could see far ahead, Unity would have to draw all these objects on the screen long before they were close enough to be interacted with. It can also lead to performance issues, especially on mobile devices.
To solve this problem, the world curves away from the player with the horizon. This creates the illusion of an infinite world, hides the path parts from appearing, and means we don't have to create coins and obstacles until the player is close to them.
In development, only lessons on YouTube and a few friends from an architectural university in a blender helped me (and my 4 years at the university :D)
The project took about 21 days.
Thanks for attention <3