My girlfriend and the first video game. Unity development. Part 1

Well, as the first ... Except for releases only for Android and a dozen abandoned projects at the finish line, then yes, this is our first game with a swing for more than one platform. How did it all begin? And it's simple, we worked on another project, let's call it “Project A”, worked for a long time and decided if we could make a game in a couple of months and train our marketing skills on it, and we will release “Project A” right after with extensive experience in promoting games. But the stars did not agree, the cock did not whistle and "Project A" lay down for exactly one year. But this story is not about him, but about a logical game called "Cubicity: Slide puzzle."



According to the first plan, the following was planned: a minimum of graphics, a minimum of UI and everything that was possible to minimize, the game should have been in the style of today's casual games, which are as many on the market as Match-3. As a result, our goal was as follows, round chips are connected in a given shape, moving with a swipe in 4 directions. Those who have already played Cubicity know that we have not gone far from this task, but have made a rather big leap over the rest, as for a team consisting of only two people.



If one of the readers expects to find the secret of successful and quick game development here, then you should know that there is no secret. Here we do not share great experience or knowledge, only the history of one project of a small company is described here. Successful or not, we still do not know. But for many of you, our readers are a message from the past from the developers themselves.

Returning to the history of the creation of Cubicity, we mainly work only on Unity and the standard set of any self-respecting Unity developer is here: Newtonsoft.json, Zenject, Cinemachine, Dotween, etc. ... As you saw above, the first prototype of the game looked just like that, cubes and pancakes. After a week of thinking how to diversify the game and lure the players, a brilliant idea came ... Look at the Asset store of cubic or round characters. Well, it started, a few packs of characters were bought without hesitation. The same situation happened with the blocks on which the characters are now moving. They also made a list of new gameplay elements, from a list of about 30 new goodies, neutral things were selected for a start, such as redirecting blocks / arrows, an elevator and a teleport. They decided to leave the rest to new levels and introduce them one at a time into 30-35 levels.



Honestly, we can’t remember what prompted us to do so many levels at first, but as is, 95 levels went into the first release. In fact, a lot, and we have regretted this more than once. Why are you sorry? But because the game was raw and a lot of things changed along the way. I had to quite often get a dose of "Groundhog Day" by going into each of the 95 levels and making changes. All levels took 2 months of continuous operation. These were not already 100% finished levels, but very close. On productive days, 10 levels were not difficult to move from head to paper, and then to the scene. But there were those days when you feel like Henk Moody from Lascivious California, experiencing a creative crisis, you think everything is dry, but a new day and new ideas come.

If we talk about the visual component, then everything is somewhat more complicated. Rendering, as in most games, is done on an off-screen surface with a resolution lower than native and shines on the main surface, but the UI is drawn for clarity and readability without any changes in resolution. Thus, we get the best of both worlds - not a blurry UI, but not too gluttonous rendering in the game. For smoothing, 2x MSAA + FXAA was chosen experimentally, as those that give the best picture with the least amount of resources. Soundly judging that a logical game doesn’t need 60 frames per second, we decided not to reinvent the wheel and set the frame limit to 30fps (to say nothing, even consoles usually do this). Setting the frame limit has a positive effect not only on energy consumption, but also on the heating of the phone,

A difficult decision was ahead of us, and these are Finish points. Since at each launch of the level the characters were randomly selected from those available to the player, it would be problematic to draw any thumbnail of the figure from the characters. You may not believe it, but it was precisely this problem that was solved the longest and was delayed for later. Cubes at the finish did not seem like such an eerie idea then, and paper painting helped to pass the level and bring everyone to their place. After that, it was decided to use the same characters instead of cubes, but smaller ones, it became better, but only for us. A few days later, these characters were deployed and highlighted, it became much clearer who is who, but still not satisfactory. The final version was adopted a month later, by trial and error, and another couple of weeks is spent on creating icons for the finishes. Goodbye, Summer,



In our humble opinion, the clouds turned out to be quite pleasant in appearance. But in fact this is the simplest and not very dirty hack. When they just decided to add the clouds, the first thought was to make a 360 video backdrop. This approach has not paid off, since for mobile platforms it is desirable to fit the game into the size limit for downloading on LTE. In order for the video to look a little better than the compression jackals given to tear to pieces, he himself had to allocate 10-15 MB, which, in combination with the presence of night levels in the game with its clouds, is too much (the entire final build of the game on Android takes 61 MB). The second desire was to write your own system for the clouds, it was tempting as a developer, but as a person who wants to finish the game as soon as possible it was not suitable. The solution came in the form of creating a texture for the cloud and creating a system of particles with an infinite particle lifetime, and also a limited number of particles in total. After that we added random sizes between two constants along with random rotation. The result was more than satisfactory - our sky was filled with clouds that were pretty and did not make us want to cry when looking at them.



The shadows in the game (in the mobile version) consist entirely of quads, which are simply arranged manually, because I did not want to add real shadows to the mobile version. One of the reasons is the lack of soft shadows on mobile platforms with OpenGLES 2.0, and of course performance degradation on weak devices.



As mentioned earlier, we used 2x MSAA + FXAA for smoothing, but that's not all! Also, AmplifyColor has been added to our post-processing process - an excellent asset for your money, which allows you to use different Luts on post-processing. With the right lut, the picture gets better. During the development process, we tried different approaches, including the standard unity post processing stack, but in the build its shaders and options took up so much that neither a fairy tale nor a pen to describe. Some solutions were very beautiful, but they worked extremely poorly on phones that weren’t of the first freshness (believe me, if you think that everyone now has at least “normal” phones, you’re wrong. A huge number of people still go with a Chinese for $ 40 and complain to you in the comments that your DOOM does not go on their microwave).

The balance of the game is always not easy, and even now thoughts pop up, whether the levels are too complicated, or whether the difficult levels often fall out, etc. Having balanced as they could with one left foot, we decided to introduce tools to make the player easier (Go Back, Bomb, Ice Block, Teleport), and yes, it became easier to live, but not for us, but only for future players. We have more work and bugs.

We got to the game menu, strength and nerves to the limit, the creative nature hit the brakes, and we will not hide, I had to be inspired by other games, for which many thanks to them. And now "In the morning the turtle came out!". Not right the next morning, but came out, the UI was ready for the previously created layouts.



The desire to be stylish, fashionable, youth did not bypass us either. We decided to add cloud-based save and generally did not regret it. This was not the easiest task, since on different platforms, different cloud storage providers. On Steam, it’s Steamworks, for mobile, GooglePlay and GameRoom. So I had to unify the storage system for the possibility of substitution for the desired platform. To begin with, we decided to use EasyMobile for these purposes, but alas, sooner or later abandoned this idea. The plugin itself is good and has a huge number of features, but we did not really like the specifics of working with native cloud storage. As a result, the choice fell on the Firebase Realtime Database and authentication via Facebook. In short, I had to go through 7 circles of hell to make it work (and this is not a matter of programming, but rather in the 100500 settings that need to be done in 100500 places of the application and the offices in Facebook, Firebase, etc.). Also, the database has traffic limits and to save it, every time we write, we create a GUID and record it both in the database and on the device. Thus, if we see that the GUIDs on the device and in the cloud are the same, we can be sure that we do not need to read all the data from the cloud, but we can use a local copy of the data. As a result, synchronization was added, but ... One of the strangest bugs for us was the unobvious behavior of the Firebase Database in some cases. Since we use Json, we serialize classes for storing state, but Firebase sometimes behaves somewhat strangely. Firebase, etc.). Also, the database has traffic limits and to save it, every time we write, we create a GUID and record it both in the database and on the device. Thus, if we see that the GUIDs on the device and in the cloud are the same, we can be sure that we do not need to read all the data from the cloud, but we can use a local copy of the data. As a result, synchronization was added, but ... One of the strangest bugs for us was the unobvious behavior of the Firebase Database in some cases. Since we use Json, we serialize classes for storing state, but Firebase sometimes behaves somewhat strangely. Firebase, etc.). Also, the database has traffic limits and to save it, every time we write, we create a GUID and record it both in the database and on the device. Thus, if we see that the GUIDs on the device and in the cloud are the same, we can be sure that we do not need to read all the data from the cloud, but we can use a local copy of the data. As a result, synchronization was added, but ... One of the strangest bugs for us was the unobvious behavior of the Firebase Database in some cases. Since we use Json, we serialize classes for storing state, but Firebase sometimes behaves somewhat strangely. Thus, if we see that the GUIDs on the device and in the cloud are the same, we can be sure that we do not need to read all the data from the cloud, but we can use a local copy of the data. As a result, synchronization was added, but ... One of the strangest bugs for us was the unobvious behavior of the Firebase Database in some cases. Since we use Json, we serialize classes for storing state, but Firebase sometimes behaves somewhat strangely. Thus, if we see that the GUIDs on the device and in the cloud are the same, we can be sure that we do not need to read all the data from the cloud, but we can use a local copy of the data. As a result, synchronization was added, but ... One of the strangest bugs for us was the unobvious behavior of the Firebase Database in some cases. Since we use Json, we serialize classes for storing state, but Firebase sometimes behaves somewhat strangely.

If we pass in a Firebase for writing a dictionary object, for example, this kind of:

var  dict = new Dictionary { { 0, new SlotState() },  { 1, new SlotState() },  { 2, new SlotState() };


When we read it from the database, we get not a Json object, but a Json array (What?)
Well, it seems, of course, we will use lists everywhere and we will not experience problems, right? But it was not there.

If we write to Firebase:

var  dict = new Dictionary { { 0, new SlotState() },  { 1, new SlotState() }, { 100500, new SlotState() };

Or even:

var  dict = new Dictionary { { 0, new SlotState() },  { 1, null },  { 2, new SlotState() };

When we read it from the database, we still get a Json object with keys and values.

It is possible to understand the logic of developers to some extent, but this can lead to bugs that may only appear after a while (Remember the above GUIDs added for saving? As a result, rare readings from the database with relatively frequent entries to it).

When is the release? This question has been heard most often. But it was necessary to thoroughly prepare for this day. Make a list of markets, choose a release date, avoid major sales, quite a few nuances, because of which the release has moved at least 2 months. After listening to the advice of one article, we chose Tuesday and Wednesday for release. We decided to order an exact review on w3bsit3-dns.com, post news about the game on several forums and bomb social networks in particular Instagram (of course, paid). What of all this worked, we will learn in the second part of this story, but only later.

What do we have in the end? Creating a quick game is not always fast. And it is possible that the expected time frame for the creation of the game will have to be multiplied by 5. Get people who can help you with practical advice in areas unfamiliar to you. Relax whenever possible, as creating something, not just games, takes a lot of energy. It’s not worth it to be sluggish sausage and be less useful when starting a project. Well, money, look for money, you will need it. And from us, thank you for your attention, good luck and see you in the next article.

Also popular now: