Mobile 3D game on Unity3D in less than 90 hours
- From the sandbox
- Tutorial
Greetings! Today I will tell you about my experience in developing a game on Unity for the Android platform, in less than 90 hours, by the example of creating a simple “runner”. In the process of narration, I will touch on some details and key stages, with a description of all possible pitfalls and methods for solving them. This story describes the process of creating a game for mobile platforms, from the concept to the finished product. I hope it inspires you to create your own project, or helps shed light on some of the features of the Unity engine. Without further ado, let's get down to business!
As a rule, novice developers step on their first and most significant rake already at this stage, because before you start creating something, it would be nice to evaluate your own capabilities. Just ask yourself: will you have the strength, time and skills to create an AAA class project? The answer is no! Drop this idea in the long box, and do not return to it until you have implemented a damn dozen successful projects. By the way, by luck we mean the number of installations from 500 thousand, a rating of over 3.5 on a 5-point scale and commercial success. For starters, consider simpler, I would even say mundane projects, like arcades in the style of addictive games, combining all the criteria we need for a “successful” project.
Advantages of addictive games style:
The last point stands apart, since the lion's share of the time is spent not on writing the code, but on polishing the visual component of the game, which in our case does not play a special role. Given the above, I decided to stay on the 3D-runner, namely on an article in the form of the famous ZIGZAG game , only better.
So we have come to the most important stage of development, and while a disappointing smile has not left your face, let me remind you that the sketch is a vision of the product. Having created it, you actually approve the technical task of the future game, thanks to which all further shamanism and dances will come from this task. The degree of elaboration of the sketch is up to you and only you. In the end, you create this sketch for yourself, not for the art gallery. At this stage, I just take a pen and notebook, after which I start drawing, occasionally leaving brief comments and explanations:
It can be seen from the sketch that the game is designed for mobile platforms, and it will be launched in portrait mode. The gameplay is also unsophisticated: the player’s task is to overcome the dangerous route on the car provided by the game, collecting crystals along the way. For each crystal collected and a successful turn, the player receives a reward in the form of bonus points. Touching the screen forces you to change the direction of the car along the X and Z axes.
Having at hand a detailed plan of action, you can safely proceed to the creation of a “mocap” or prototype of a future game. In fact, this stage is the beginning of work with Unity, and it should begin with setting up the environment. Here's how I set it up:
On the left side of the screen are the Scene and Game editor. The latter displays exactly how the game looks on devices. On the right side: the Hierarchy and Inspector panels, and just below the Project and Console panels.
Attention! Below we will describe the simplest game implementation code, designed for beginners, and demonstrating how quickly and easily you can achieve results in Unity. The final code of the game is implemented on a deeper knowledge of the language, including problems of data storage, optimization and monetization of the project, however, for obvious reasons, this article will not talk about them. We will write all the scripts in C #, but for those who are not interested, I propose to safely proceed to Stage 4: visual design
My prototyping always starts with discs, that is, as actors I always use primitive elements, like cubes and spheres. This approach greatly simplifies the development process, allowing you to abstract from everything that is not related to the mechanics of the game. At the first step, we form a basic understanding of the look of the future game, and since, as planned, our game is created in an isometric style, the first thing we need to do is set up the camera. Here we come to one of the key features of Unity. The fact is that you can experiment with the camera settings for a long time, choosing the necessary values ... But it's easier to simply set the view you like using the View panel, and then activate GameObject -> Align With View, after which your camera will immediately take the necessary values. Here is such a shortcut from the creators of Unity.
So, the scene is ready, but how to give the character movement? To begin, we’ll do some manipulation of the Sphere object by adding components such as the Rigidbody and the newly created sphereBehavior script to it. Do not forget to turn off the Use Gravity checkbox, since at this stage we will not need it.
In short, the Rigidbody component allows the object to feel all the charms of the physical world, such as mass, gravity, gravity, acceleration, etc. That is why it is so important to us! And now, to make the body move in the direction we need, we just need to slightly change the velocity parameter, but we will do this with the code. Let's make the sphere move along the X axis, for this we will make changes to the sphereBehavior script:
In Unity, bodies describe their position and direction through special vectors that store values along the x, y, and z axes. By changing these values, we achieve the direction or position of a specific body that we need. The line rb.velocity = new Vector3 (speed, 0f, 0f) sets the new direction to the body along the X axis, thereby giving our sphere the direction we need.
If you did everything exactly like me, then your sphere will go on an endless journey along the X axis, with speed speed.
Now let's make our sphere change its direction, with each click of the left mouse button, as it is implemented in the ZIGZAG game. To do this, we will return to the sphereBehavior code and change it as follows:
Let us agree that when the sphere moves along the X axis, then this movement is called the "right" movement, and along the Z axis - "left". Thus, we can easily describe the direction of our body with the special boolean variable isMovingRight.
This piece of code monitors the left mouse button, and if this button is still pressed, it runs the changeDirection () function , with simple logic: if the variable isMovingRight was true at the time the left mouse button was pressed, now it has become false and vice versa. Let me remind you that the Boolean variable allows us to answer one simple question: is the statement that the body moves along the X axis true or not? In other words, pressing the left mouse button constantly changes the value of isMovingRight, then to true (the body moves to the right), then to false (the body moves to the left).
Alternatively, the changeDirection () function can be written on one line:
And the last thing that needs to be done is to rewrite the direction of movement method taking into account the variable isMovingRight:
If isMovingRight is true (if the sphere really moves to the right), then velocity takes a new direction vector rb.velocity = new Vector3 (speed, 0f, 0f); If isMovingRight is false, then the body is no longer moving to the right, which means it's time to change the direction vector to rb.velocity = new Vector3 (0f, 0f, speed);
Launch the game, do a few clicks of the mouse, and if you did everything exactly like me, you will see how the sphere begins to describe zigzags.
Cool? Of course not! After all, the sphere is moving, and we are standing still. Let's modify the game so that we can move along with the sphere and not lose sight of it. To do this, we need to create a cameraFollow script and attach it to the Main Camera object:
And here is the cameraFollow script code:
How to track an object? First, we need to calculate the offset difference between the Camera and Sphere objects. To do this, it is enough to subtract the coordinates of the sphere from the camera position, and save the resulting difference in the offset variable. But first, you need to access the coordinates of the sphere. To do this, we need the player variable, which is a simple GameObject. Since our sphere is in constant motion, we must synchronize the camera coordinates with the coordinates of the sphere, plus the previously obtained offset. It remains only to indicate our tracking object in the player field, and you can safely admire the result. Just drag the Sphere object into the Player field of the cameraFollow script, as shown in the picture (the Main Camera should remain selected at the same time):
Now, let's think about the generation of a road along which our sphere could move, because now it is literally floating in the air. Let's start by setting up a Cube object, which, in our opinion, represents a section of the path.
If there is no Ground tag in your list, then you need to create it in the Add Tag tab ...
The next thing we have to do is create a special folder in the project root called Prefabs and drag our Cube into it, right from the inspector. If after that, the name of the Cube object turns blue, then you did everything right.
Prefabs are a special type of object that allows you to store GameObject, as well as all its values and properties in one place. Prefabs allow you to create an infinite number of objects, and any change in it immediately affects all its copies. In other words, now we can call the Cube path, right from the Prefabs folder, as many times as necessary.
Now let's create an empty GameObject, (right-click on the Hierarchy) rename it to RoadContainer and attach the just created roadBehavior script to it:
And here is the roadBehavior code itself:
What is really going on here? As you can see, we have a variable that will later be manually bound to our Cube prefab, and there is a Vector3 object that stores the coordinates of the last prefab set (now the values are zero).
This code section does the following: as long as i <10, we will take the prefab, set its position taking into account the last position lastpos + position taking into account the offset along X, keep the last position. That is, as a result, we get 10 Cube prefabs installed exactly one after another. Before checking, do not forget to assign our Cube object from the Prefabs folder to the road variable:
Ok, but what to do next? And then we need to continue installing blocks in random order. For this we need a random pseudo-random number generator. We’ll fix the roadBehavior script, taking into account the innovations:
The line InvokeRepeating ("SpawnPlatform", 1f, 0.2f) is intended to activate the SpawnPlatform () function 1 second after the start of the game, and call it again every 0.2 seconds. As for the function itself, then, as they say, everything is simpler than a steamed turnip! Every 0.2 seconds, the system makes a random number between the numbers from 0 to 1. If the system guesses 0, we set a new prefab on the X axis, and if 1 - then on the Z axis. That's all magic!
And finally, let's make the sphere fall every time it goes off course. To do this, create a new playerFalls script and attach it to our Sphere object:
And here is the playerFalls script code itself:
Raycast - a special beam similar to a laser, which is emitted towards the scene. In case the beam is reflected from the object, it returns information about the object that it collided with. And this is very cool, because that's the way, by means of such a beam directed from the center of the sphere down, we will check whether we are on the Cube platform or not (we check whether the object has the tag “Ground”). And as soon as we leave the regions of the roadway, we automatically activate the Gravity parameter of our sphere (remember how we deliberately turned it off at the very beginning?), After which the sphere will collapse under the influence of gravity, haha!
When all the work on game mechanics is completed, it is time to move on to the visual part of the project. All the same, the gameplay is good, and the pleasant gameplay is even better. And despite the fact that at the very beginning we designated the schedule as far from the most important thing, I still want to add some zest by adding color to the game being created. After some deliberation, the following idea came to my mind:
By design, you are driving a car rushing through the vast expanses of the sea, escaping from an impending cataclysm. Procrastination is akin to death, since platforms continually strive to tip over into the deep sea, dragging the player into the abyss of shame and disappointment. Plus, from time to time, platforms begin to change color, and the car spontaneously increase speed. All this is designed to bring to the game a kind of "challenge". As it was said, for each successfully completed turn or collected crystal, the player is rewarded with an “Incam” - a local similarity to a salary. Subsequently, the salary can be exchanged in a shop for a car with a higher “Incam”. The concept gave the sonorous name "Income Racer".
All assets were modeled in Blender, a free 3D editor. In it, the necessary textures were created, subsequently brought to an acceptable form in Photoshop. The pleasant moment was that Unity easily imports 3D models from Blender, without any headache, making the creation process pleasant and painless.
The development of the project is still a rake, because there is always a place for something that can be improved or redone. Often, it happens that it is at the stage of polishing and debugging that the development process significantly loses in time, or even comes to a standstill. The reason is that you are already noticeably tired: the game seems to you monotonous and not interesting enough. Sometimes, at the end of development, a revelation comes of the fact that you are capable of remaking the game from scratch, improving it at least twice! Drop these thoughts and think of the plan, of how it all began. It’s better to supplement the game after release, by rolling out updates, than to delay development indefinitely. Otherwise, you risk ruining the project by putting a bold cross on it. For example, at the time of writing these lines, the game did not even have an opening screen. The reason for this is the fact that according to the plan I could not go beyond the 90 hours allocated to the development process. Of course, it would be possible to spend a few more hours creating an introductory screen, but he had a plan to follow. And it’s normal that some moments are added to the game after its release.
Lastly, it remains to create presentation documents: a brief description, video, as well as a game icon. This stage should be given as much attention as possible, because it is precisely by the icon that users begin to judge your project.
In the end, it turned out what happened. A little more than 90 hours was spent on everything about everything, which by the standards of the modern game dev is not so much. After this time, the game was uploaded to the Play Market and put up for universal trial, such a story! If you liked the article, or just have something to talk about, then welcome to comment. I will be glad to answer your questions.
Stage 1: concept
As a rule, novice developers step on their first and most significant rake already at this stage, because before you start creating something, it would be nice to evaluate your own capabilities. Just ask yourself: will you have the strength, time and skills to create an AAA class project? The answer is no! Drop this idea in the long box, and do not return to it until you have implemented a damn dozen successful projects. By the way, by luck we mean the number of installations from 500 thousand, a rating of over 3.5 on a 5-point scale and commercial success. For starters, consider simpler, I would even say mundane projects, like arcades in the style of addictive games, combining all the criteria we need for a “successful” project.
Advantages of addictive games style:
- Addictive, "sticky" gameplay;
- Lack of plot;
- Simple and intuitive controls that require a minimum of player action;
- Minimum graphics requirements.
The last point stands apart, since the lion's share of the time is spent not on writing the code, but on polishing the visual component of the game, which in our case does not play a special role. Given the above, I decided to stay on the 3D-runner, namely on an article in the form of the famous ZIGZAG game , only better.
Stage 2: sketching
So we have come to the most important stage of development, and while a disappointing smile has not left your face, let me remind you that the sketch is a vision of the product. Having created it, you actually approve the technical task of the future game, thanks to which all further shamanism and dances will come from this task. The degree of elaboration of the sketch is up to you and only you. In the end, you create this sketch for yourself, not for the art gallery. At this stage, I just take a pen and notebook, after which I start drawing, occasionally leaving brief comments and explanations:
It can be seen from the sketch that the game is designed for mobile platforms, and it will be launched in portrait mode. The gameplay is also unsophisticated: the player’s task is to overcome the dangerous route on the car provided by the game, collecting crystals along the way. For each crystal collected and a successful turn, the player receives a reward in the form of bonus points. Touching the screen forces you to change the direction of the car along the X and Z axes.
Stage 3: prototype creation
Having at hand a detailed plan of action, you can safely proceed to the creation of a “mocap” or prototype of a future game. In fact, this stage is the beginning of work with Unity, and it should begin with setting up the environment. Here's how I set it up:
On the left side of the screen are the Scene and Game editor. The latter displays exactly how the game looks on devices. On the right side: the Hierarchy and Inspector panels, and just below the Project and Console panels.
Stage 3.1: under the hood
Attention! Below we will describe the simplest game implementation code, designed for beginners, and demonstrating how quickly and easily you can achieve results in Unity. The final code of the game is implemented on a deeper knowledge of the language, including problems of data storage, optimization and monetization of the project, however, for obvious reasons, this article will not talk about them. We will write all the scripts in C #, but for those who are not interested, I propose to safely proceed to Stage 4: visual design
My prototyping always starts with discs, that is, as actors I always use primitive elements, like cubes and spheres. This approach greatly simplifies the development process, allowing you to abstract from everything that is not related to the mechanics of the game. At the first step, we form a basic understanding of the look of the future game, and since, as planned, our game is created in an isometric style, the first thing we need to do is set up the camera. Here we come to one of the key features of Unity. The fact is that you can experiment with the camera settings for a long time, choosing the necessary values ... But it's easier to simply set the view you like using the View panel, and then activate GameObject -> Align With View, after which your camera will immediately take the necessary values. Here is such a shortcut from the creators of Unity.
So, the scene is ready, but how to give the character movement? To begin, we’ll do some manipulation of the Sphere object by adding components such as the Rigidbody and the newly created sphereBehavior script to it. Do not forget to turn off the Use Gravity checkbox, since at this stage we will not need it.
In short, the Rigidbody component allows the object to feel all the charms of the physical world, such as mass, gravity, gravity, acceleration, etc. That is why it is so important to us! And now, to make the body move in the direction we need, we just need to slightly change the velocity parameter, but we will do this with the code. Let's make the sphere move along the X axis, for this we will make changes to the sphereBehavior script:
using UnityEngine;
using System.Collections;
public class sphereBehavior : MonoBehaviour {
private Rigidbody rb; // Объявление новой переменной Rigidbody
private float speed = 5f; // Скорость движения объекта
void Start() {
rb = GetComponent (); // Получение доступа к Rigidbody
}
void Update() {
rb.velocity = new Vector3 (speed, 0f,0f);
}
}
In Unity, bodies describe their position and direction through special vectors that store values along the x, y, and z axes. By changing these values, we achieve the direction or position of a specific body that we need. The line rb.velocity = new Vector3 (speed, 0f, 0f) sets the new direction to the body along the X axis, thereby giving our sphere the direction we need.
If you did everything exactly like me, then your sphere will go on an endless journey along the X axis, with speed speed.
Now let's make our sphere change its direction, with each click of the left mouse button, as it is implemented in the ZIGZAG game. To do this, we will return to the sphereBehavior code and change it as follows:
using UnityEngine;
using System.Collections;
public class sphereBehavior : MonoBehaviour {
private Rigidbody rb; // Объявление новой переменной Rigidbody
private bool isMovingRight = true; // переменная, отражающая условное направление объекта
private float speed = 5f; // Скорость движения объекта
void Start() {
rb = GetComponent (); // Получение доступа к Rigidbody
}
void changeDirection() {
if (isMovingRight) {
isMovingRight = false;
} else {
isMovingRight = true;
}
}
void Update() {
if(Input.GetMouseButtonDown(0)) {
changeDirection();
}
if (isMovingRight) {
rb.velocity = new Vector3 (speed, 0f, 0f);
} else {
rb.velocity = new Vector3 (0f, 0f, speed);
}
}
}
Let us agree that when the sphere moves along the X axis, then this movement is called the "right" movement, and along the Z axis - "left". Thus, we can easily describe the direction of our body with the special boolean variable isMovingRight.
if(Input.GetMouseButtonDown(0)) {
changeDirection();
}
This piece of code monitors the left mouse button, and if this button is still pressed, it runs the changeDirection () function , with simple logic: if the variable isMovingRight was true at the time the left mouse button was pressed, now it has become false and vice versa. Let me remind you that the Boolean variable allows us to answer one simple question: is the statement that the body moves along the X axis true or not? In other words, pressing the left mouse button constantly changes the value of isMovingRight, then to true (the body moves to the right), then to false (the body moves to the left).
Alternatively, the changeDirection () function can be written on one line:
void changeDirection() {
isMovingRight = !isMovingRight;
}
And the last thing that needs to be done is to rewrite the direction of movement method taking into account the variable isMovingRight:
if (isMovingRight) {
rb.velocity = new Vector3 (speed, 0f, 0f);
} else {
rb.velocity = new Vector3 (0f, 0f, speed);
}
If isMovingRight is true (if the sphere really moves to the right), then velocity takes a new direction vector rb.velocity = new Vector3 (speed, 0f, 0f); If isMovingRight is false, then the body is no longer moving to the right, which means it's time to change the direction vector to rb.velocity = new Vector3 (0f, 0f, speed);
Launch the game, do a few clicks of the mouse, and if you did everything exactly like me, you will see how the sphere begins to describe zigzags.
Cool? Of course not! After all, the sphere is moving, and we are standing still. Let's modify the game so that we can move along with the sphere and not lose sight of it. To do this, we need to create a cameraFollow script and attach it to the Main Camera object:
And here is the cameraFollow script code:
using UnityEngine;
using System.Collections;
public class cameraFollow : MonoBehaviour {
public GameObject player;
public Vector3 offset;
void Start () {
offset = transform.position - player.transform.position;
}
void Update () {
transform.position = player.transform.position + offset;
}
}
How to track an object? First, we need to calculate the offset difference between the Camera and Sphere objects. To do this, it is enough to subtract the coordinates of the sphere from the camera position, and save the resulting difference in the offset variable. But first, you need to access the coordinates of the sphere. To do this, we need the player variable, which is a simple GameObject. Since our sphere is in constant motion, we must synchronize the camera coordinates with the coordinates of the sphere, plus the previously obtained offset. It remains only to indicate our tracking object in the player field, and you can safely admire the result. Just drag the Sphere object into the Player field of the cameraFollow script, as shown in the picture (the Main Camera should remain selected at the same time):
Now, let's think about the generation of a road along which our sphere could move, because now it is literally floating in the air. Let's start by setting up a Cube object, which, in our opinion, represents a section of the path.
If there is no Ground tag in your list, then you need to create it in the Add Tag tab ...
The next thing we have to do is create a special folder in the project root called Prefabs and drag our Cube into it, right from the inspector. If after that, the name of the Cube object turns blue, then you did everything right.
Prefabs are a special type of object that allows you to store GameObject, as well as all its values and properties in one place. Prefabs allow you to create an infinite number of objects, and any change in it immediately affects all its copies. In other words, now we can call the Cube path, right from the Prefabs folder, as many times as necessary.
Now let's create an empty GameObject, (right-click on the Hierarchy) rename it to RoadContainer and attach the just created roadBehavior script to it:
And here is the roadBehavior code itself:
using UnityEngine;
using System.Collections;
public class roadBehavior : MonoBehaviour {
public GameObject road; // Префаб участка пути
private Vector3 lastpos = new Vector3 (0f,0f,0f); // Координаты установленного префаба
void Start() {
for(int i=0; i<10; i++) {
GameObject _platform = Instantiate (road) as GameObject;
_platform.transform.position = lastpos + new Vector3 (1f,0f,0f);
lastpos = _platform.transform.position;
}
}
}
What is really going on here? As you can see, we have a variable that will later be manually bound to our Cube prefab, and there is a Vector3 object that stores the coordinates of the last prefab set (now the values are zero).
for(int i=0; i<10; i++) {
GameObject _platform = Instantiate (road) as GameObject;
_platform.transform.position = lastpos + new Vector3 (1f,0f,0f);
lastpos = _platform.transform.position;
}
This code section does the following: as long as i <10, we will take the prefab, set its position taking into account the last position lastpos + position taking into account the offset along X, keep the last position. That is, as a result, we get 10 Cube prefabs installed exactly one after another. Before checking, do not forget to assign our Cube object from the Prefabs folder to the road variable:
Ok, but what to do next? And then we need to continue installing blocks in random order. For this we need a random pseudo-random number generator. We’ll fix the roadBehavior script, taking into account the innovations:
using UnityEngine;
using System.Collections;
public class roadBehavior : MonoBehaviour {
public GameObject road; // Префаб участка пути
private Vector3 lastpos = new Vector3 (0f,0f,0f); // Координаты установленного префаба
void Start() {
for(int i=0; i<10; i++) {
GameObject _platform = Instantiate (road) as GameObject;
_platform.transform.position = lastpos + new Vector3 (1f,0f,0f);
lastpos = _platform.transform.position;
}
InvokeRepeating ("SpawnPlatform", 1f, 0.2f);
}
void SpawnPlatform() {
int random = Random.Range (0, 2);
if (random == 0) { // Установить префаб по оси X
GameObject _platform = Instantiate (road) as GameObject;
_platform.transform.position = lastpos + new Vector3 (1f,0f,0f);
lastpos = _platform.transform.position;
} else { // Установить префаб по оси Z
GameObject _platform = Instantiate (road) as GameObject;
_platform.transform.position = lastpos + new Vector3 (0f,0f,1f);
lastpos = _platform.transform.position;
}
}
}
The line InvokeRepeating ("SpawnPlatform", 1f, 0.2f) is intended to activate the SpawnPlatform () function 1 second after the start of the game, and call it again every 0.2 seconds. As for the function itself, then, as they say, everything is simpler than a steamed turnip! Every 0.2 seconds, the system makes a random number between the numbers from 0 to 1. If the system guesses 0, we set a new prefab on the X axis, and if 1 - then on the Z axis. That's all magic!
And finally, let's make the sphere fall every time it goes off course. To do this, create a new playerFalls script and attach it to our Sphere object:
And here is the playerFalls script code itself:
using UnityEngine;
using System.Collections;
public class playerFalls : MonoBehaviour {
private Rigidbody rb;
void Start() {
rb = GetComponent ();
}
void Update() {
RaycastHit hit;
if(Physics.Raycast (transform.position, Vector3.down, out hit, 5f) && hit.transform.gameObject.tag == "Ground") {
rb.useGravity = false;
} else {
rb.useGravity = true;
}
}
}
Raycast - a special beam similar to a laser, which is emitted towards the scene. In case the beam is reflected from the object, it returns information about the object that it collided with. And this is very cool, because that's the way, by means of such a beam directed from the center of the sphere down, we will check whether we are on the Cube platform or not (we check whether the object has the tag “Ground”). And as soon as we leave the regions of the roadway, we automatically activate the Gravity parameter of our sphere (remember how we deliberately turned it off at the very beginning?), After which the sphere will collapse under the influence of gravity, haha!
Stage 4: visual design
When all the work on game mechanics is completed, it is time to move on to the visual part of the project. All the same, the gameplay is good, and the pleasant gameplay is even better. And despite the fact that at the very beginning we designated the schedule as far from the most important thing, I still want to add some zest by adding color to the game being created. After some deliberation, the following idea came to my mind:
By design, you are driving a car rushing through the vast expanses of the sea, escaping from an impending cataclysm. Procrastination is akin to death, since platforms continually strive to tip over into the deep sea, dragging the player into the abyss of shame and disappointment. Plus, from time to time, platforms begin to change color, and the car spontaneously increase speed. All this is designed to bring to the game a kind of "challenge". As it was said, for each successfully completed turn or collected crystal, the player is rewarded with an “Incam” - a local similarity to a salary. Subsequently, the salary can be exchanged in a shop for a car with a higher “Incam”. The concept gave the sonorous name "Income Racer".
All assets were modeled in Blender, a free 3D editor. In it, the necessary textures were created, subsequently brought to an acceptable form in Photoshop. The pleasant moment was that Unity easily imports 3D models from Blender, without any headache, making the creation process pleasant and painless.
Stage 5: Polishing
The development of the project is still a rake, because there is always a place for something that can be improved or redone. Often, it happens that it is at the stage of polishing and debugging that the development process significantly loses in time, or even comes to a standstill. The reason is that you are already noticeably tired: the game seems to you monotonous and not interesting enough. Sometimes, at the end of development, a revelation comes of the fact that you are capable of remaking the game from scratch, improving it at least twice! Drop these thoughts and think of the plan, of how it all began. It’s better to supplement the game after release, by rolling out updates, than to delay development indefinitely. Otherwise, you risk ruining the project by putting a bold cross on it. For example, at the time of writing these lines, the game did not even have an opening screen. The reason for this is the fact that according to the plan I could not go beyond the 90 hours allocated to the development process. Of course, it would be possible to spend a few more hours creating an introductory screen, but he had a plan to follow. And it’s normal that some moments are added to the game after its release.
Lastly, it remains to create presentation documents: a brief description, video, as well as a game icon. This stage should be given as much attention as possible, because it is precisely by the icon that users begin to judge your project.
In the end, it turned out what happened. A little more than 90 hours was spent on everything about everything, which by the standards of the modern game dev is not so much. After this time, the game was uploaded to the Play Market and put up for universal trial, such a story! If you liked the article, or just have something to talk about, then welcome to comment. I will be glad to answer your questions.