The story of the development of Cosmos at Unity
In my article, I will try to describe my experience in creating a game in two weeks, from choosing a genre and setting, ending with final credits, as well as all the rakes that I stepped on during the development process, and which I don’t want to step on anymore. For those who have quite a lot of experience in game development, the article will most likely be uninteresting, but beginning developers, I think, will be able to find something interesting for themselves.

The name is that part of the game, work on which was postponed to the very last moment. As a result, nothing worthwhile came up with, unfortunately, failed.
It all started fairly standardly, the contest, the theme - “Choice” (interpret as you like, called), the term - two weeks. I suffer from a slight rejection of 2D games, so the 2D / 3D issue did not stand at all. With the genre and setting it was already more difficult, it was decided to build on two favorite games, for which more than one hundred hours were spent - “Space Rangers” and “Mechanoids”. So I decided on the genre - a game built on the mechanics of Elite, of course, greatly reduced. The logical setting for this genre was Sci-fi, the place of action is space, because in two weeks to create minimally worthy “ground levels” is very problematic.
To minimize the required amount of content, it was decided to abandon the generated planetary systems, and from any scale as a whole. The whole game takes place within one asteroid belt, divided into several sectors, the number of points of interest is minimal. But such a decision left time for other aspects of the game, if you delve into the study of the world, there will be no time left for everything else.

On the first day, a sketch of the interface and a set of features were born, which were implemented in the next 14 days.
With the plot, I acted even more barbarously (in vain, as it turned out later) - the first idea that came to mind about the mysterious invaders encroaching on the asteroid belt in which the base of the GG was taken was taken as the basis. Thinking over the details was left for later, as well as coming up with story assignments.
Ahead was the most important - features.
I really wanted to give my best and implement as many different chips as possible, many of which had only one goal - to please that they were generally implemented in the game. One of these pieces was homing missiles. It seems that despite their ability to explode small enemies with one hit, none of those who played the game really really used them. At the same time, it took a decent time to create them.
In general, an approximate list of the main features looked something like this:
The list turned out to be quite large, but one way or another, all these features were implemented in the game with varying degrees of elaboration.
After it was decided with a genre and a set of features, two models were quickly sketched in the 3d editor - the protagonist's spaceship and one of the opponents.

The primitiveness and cubicity of enemy ships has a plot justification.
And now, finally, it was possible to start programming.
The first step was to implement the movement of the spacecraft and the camera.
The movement is implemented quite simply, no inertia and other realistic things. The player’s ship is a model with a Rigidbody, to which each tick is given angular and translational speeds. To obtain the angular velocity, a displacement vector from the center is taken from the mouse, with each tick the current delta of the mouse movement is added to the displacement, and the vector itself is multiplied by a coefficient less than 1. A fairly smooth control is obtained, with the illusion of a small inertia of the ship.
For translational motion it’s even easier - the ship moves in the direction of the local “forward”, the speed gradually increases or decreases when you press the W / S keys.
With Camera everything turned out quite simple too. Attaching a camera to a ship on the forehead is a bad idea, so the camera and the ship are not connected, but for the camera there is a target point from the back-top of the ship that it is aiming at and target rotation angles. The current and target points are interpolated, thereby obtaining the effect of a “smooth tracking camera”.
To give a sense of speed, with the acceleration of the ship, the field of view of the camera increases slightly, while slowing, it accordingly slows down.
You can see how the ship twitches unpleasantly. This was cured by enabling interpolation in the rigidbody settings of the ship.
Moving in empty black space is somehow uninteresting. Therefore, the next step was filling the cosmos with objects.
Since the asteroid belt was the venue of the game in the setting, the task was solved very simply - a couple of hundred larger asteroids were randomly scattered in a space of several tens of cubic kilometers. Seed for random generation was stored in advance, so there was no need to worry that the base or quest item would be inside the asteroid.

It looks like this from a distance.
For greater "liveliness" and dynamism, in addition to large asteroids, small and "stardust" were added. These little things were no longer generated throughout the location, but were created directly around the moving ship.
The main character’s ship was decided to give the opportunity to carry weapons at six points of suspension (two or four points is too solid for a heavily armed fighter). Arms attachment points were set using GameObjects-dummies, the number of points for the suspension was hardcoded (yes, I repent). At the same time, the suspension points were divided into two types - the main weapon and auxiliary. There was essentially one difference - the weapons on the main slots were activated on LMB, and on the additional ones - on the spacebar. Weapons interacted with the ship quite limitedly - through an interface that provides access to the basic functions, which made it easy to add new types of weapons. In addition, as it was developed, several more functions were added to it, which are responsible for its appearance in the store and hangar interface.

One of the first screenshots of a ship with suspended weapons.
Five types of weapons were made: a double-barreled cannon, a laser, unguided missiles, a heavy homing torpedo, and a homing missile.
A homing missile for greater accuracy calculated the lead point, with the assumption that the target will move in the same direction at the same speed. As a rule, this was enough for the missile to hit a moving target with a rather high probability.
Below is a video of the work of two types of weapons. Also, the video shows the effect of the destruction of the enemy, but since it is quite simple, I will not dwell on it separately.
The time spent on the interface unexpectedly turned out to be very significant, the development of the interface took at least three days of work. I used the UI system, which appeared in Unity 4.6, in my opinion it is very convenient and fairly easy to learn.
The most difficult part of the work on the interface was the base interface, it was necessary to implement quite a lot of functionality. Dialogues, purchase / sale of weapons, sale of items from the hold, repair. As the cargo / weapon icons, their models in orthogonal projection were used, because there was simply not enough time to draw the icons. A short description was compiled for each item, telling the player what it was in front of him.

The first version of the interface, the curve, without the tasks tab
Later, the interface was refined graphically (thanks to the person who helped me with sprites for him, I myself would never have been able to), and began to look noticeably nicer and neater.

The final version, the essence is the same, but more pleasing to the eye.
The flight interface was made easier. The player in fact does not interact with him in any way, and in and of itself he is quite minimalistic. For progress bars, a regular sprite was used, cut by means of Unity into 9 parts and stretched horizontally, very simply and quite nicely. With curved bars on the side of the scope, everything is more complicated. Just stretching the sprite along one of the axes will not work, you need to use a more complex solution. A simple shader was written with one parameter - the cutoff height. It was set from a script, and in accordance with it, the sprite was drawn with the desired filling.
Screenshot of the flight interface:

The screenshot shows a half-filled health indicator in the center of the screen
In my opinion, one of the weaknesses of the game. They have only one tactic - to fly after the player, if he is in their field of view, and approaching the distance of firing, start shooting. Despite this, in large numbers even such enemies pose a serious danger.
Of course, in addition to the behavior mentioned above, they also had auxiliary functions. For example, having lost sight of a player, they flew to the last point where they saw him, and not having found him there, randomly started wandering or returned to the starting point. And also, they sometimes avoided collisions with asteroids, but only if they did not fly too fast. A full-fledged state machine for opponents' AI was not implemented like that, the AI script launched a pass every 0.1 seconds, in which it decided what the enemy would do in the next 0.1s. Because of this, in order to achieve more or less tolerable behavior, I had to start many additional variables that describe the state of the AI.

The main boss was completely defenseless, and relied only on a huge number of his minions.
Before that, I had never done a quest system, so I had no idea where to start. But there was no time to reason or look for lessons - it was necessary to act, because the second week was going on! As a result, a very ugly system was born with a hard-coded list of quests (to add a new quest, you had to write its name in the variables of the Main Quest Script, increase the number of quests by one, and prescribe which base the quest refers to), with a fixed number of answer options in the dialogs (three pieces), and with other signs of rake jumping.
Dialogs were saved in xml, for their editing a simple editor was even made there, in Unity.

The editor is probably the best part of the quest system.
The quests themselves were made by prefabs, which were instanced upon activation of the quest and deleted after receiving the award. It is crooked, but it worked. The quest system, writing dialogs and the quests themselves took another three days. The deadline was drawing to a close.
I would like to list here various chips that are unworthy of a separate section, but which I would like to talk about nonetheless.
Perhaps I'll start with the effect of hyper-jumping. How it looks, you can see below.
It is implemented very simply. First we start the sound, start shaking the camera, show on top of the main model a slightly enlarged model of the same ship, but with the texture of the “energy field”, then animate it using Animation Curves, and before the jump we launch the particle-flash system and hide the main model . It seems to me that for the "low-budget" effect it turned out well.
I also want to tell a few words about the save system. Oddly enough, she is present in the game. The xml file with the player’s name is saved in the game folder, the player’s name itself is saved in PlayerPrefs (in the registry). Theoretically, you can even use several saves by changing the name of the player in the main menu. Saving is automatic, after each completed quest.
It is implemented very simply: the SaveInfo class was created, where all the necessary state parameters of the game are saved, the class implements two methods: Load () and Save (), which serialize / deserialize the data into an xml file using standard C # tools.
That's all, nothing else needs to be done, it remains only to parse the fields of this class.
So, if you are too lazy to go through the game, you can conjure with save and accelerate progress, or put a weapon more powerful.
I would also like to thank the good people who, right in the development process, volunteered to help me with the graphic content for the game. Given its quantity (several dozens of models only), I doubt that I would be able to catch it on time, and there’s no need to talk about quality. As a result, almost all of the graphics in the game (except for two backgrounds and skybox) was created specifically for this game.
More than half a year has passed since the end of work on the game, and it's time to take stock.
I did not take the prize place with this game, apparently I did not fall into the trend of pixel art adventure. But during the work on the game a huge amount of invaluable experience and skills was gained, and the bumps from the overtaken rake will remind me for a long time that some things are not worth doing.
Conclusions:
Of course, many of my conclusions may seem obvious, but sometimes without trying, you will not understand. For example, the desire to make the project as complex as possible is one of the most common mistakes made by novice developers. I could not avoid this problem either.
Finally, I want to show you the gameplay video from the game. On it you can approximately evaluate what happened in the end.
I hope the article was useful to you in some way, or at least it was interesting for you to find out the history of the development of another small game.
Link to the build:
yadi.sk/d/j-v8WoyCiaNuQ
Link to the GitHub repository (Raw code, after the contest almost didn’t correct, and since everything was written in a hurry, the pearl is full there)
github.com/TxN/TWG6-Spacesim
The name is that part of the game, work on which was postponed to the very last moment. As a result, nothing worthwhile came up with, unfortunately, failed.
Genre, setting and plot
It all started fairly standardly, the contest, the theme - “Choice” (interpret as you like, called), the term - two weeks. I suffer from a slight rejection of 2D games, so the 2D / 3D issue did not stand at all. With the genre and setting it was already more difficult, it was decided to build on two favorite games, for which more than one hundred hours were spent - “Space Rangers” and “Mechanoids”. So I decided on the genre - a game built on the mechanics of Elite, of course, greatly reduced. The logical setting for this genre was Sci-fi, the place of action is space, because in two weeks to create minimally worthy “ground levels” is very problematic.
To minimize the required amount of content, it was decided to abandon the generated planetary systems, and from any scale as a whole. The whole game takes place within one asteroid belt, divided into several sectors, the number of points of interest is minimal. But such a decision left time for other aspects of the game, if you delve into the study of the world, there will be no time left for everything else.

On the first day, a sketch of the interface and a set of features were born, which were implemented in the next 14 days.
With the plot, I acted even more barbarously (in vain, as it turned out later) - the first idea that came to mind about the mysterious invaders encroaching on the asteroid belt in which the base of the GG was taken was taken as the basis. Thinking over the details was left for later, as well as coming up with story assignments.
Ahead was the most important - features.
Opportunities
I really wanted to give my best and implement as many different chips as possible, many of which had only one goal - to please that they were generally implemented in the game. One of these pieces was homing missiles. It seems that despite their ability to explode small enemies with one hit, none of those who played the game really really used them. At the same time, it took a decent time to create them.
In general, an approximate list of the main features looked something like this:
- Player-controlled spacecraft, with the ability to customize weapons
- Several types of weapons that can be hung at different points of suspension
- The ability to pick up the wreckage of enemies and take them to the bases, receiving money for this
- Multiple sectors that are hyper-jumped between
- Guided and uncontrolled weapons
- Several types of opponents with different characteristics
- Ten or two story quests, at least two endings
- The boss, and an important element of the game is the boss fight
The list turned out to be quite large, but one way or another, all these features were implemented in the game with varying degrees of elaboration.
Start: First models and movement in the void
After it was decided with a genre and a set of features, two models were quickly sketched in the 3d editor - the protagonist's spaceship and one of the opponents.

The primitiveness and cubicity of enemy ships has a plot justification.
And now, finally, it was possible to start programming.
The first step was to implement the movement of the spacecraft and the camera.
The movement is implemented quite simply, no inertia and other realistic things. The player’s ship is a model with a Rigidbody, to which each tick is given angular and translational speeds. To obtain the angular velocity, a displacement vector from the center is taken from the mouse, with each tick the current delta of the mouse movement is added to the displacement, and the vector itself is multiplied by a coefficient less than 1. A fairly smooth control is obtained, with the illusion of a small inertia of the ship.
For translational motion it’s even easier - the ship moves in the direction of the local “forward”, the speed gradually increases or decreases when you press the W / S keys.
With Camera everything turned out quite simple too. Attaching a camera to a ship on the forehead is a bad idea, so the camera and the ship are not connected, but for the camera there is a target point from the back-top of the ship that it is aiming at and target rotation angles. The current and target points are interpolated, thereby obtaining the effect of a “smooth tracking camera”.
To give a sense of speed, with the acceleration of the ship, the field of view of the camera increases slightly, while slowing, it accordingly slows down.
You can see how the ship twitches unpleasantly. This was cured by enabling interpolation in the rigidbody settings of the ship.
Fill the void
Moving in empty black space is somehow uninteresting. Therefore, the next step was filling the cosmos with objects.
Since the asteroid belt was the venue of the game in the setting, the task was solved very simply - a couple of hundred larger asteroids were randomly scattered in a space of several tens of cubic kilometers. Seed for random generation was stored in advance, so there was no need to worry that the base or quest item would be inside the asteroid.
It looks like this from a distance.
For greater "liveliness" and dynamism, in addition to large asteroids, small and "stardust" were added. These little things were no longer generated throughout the location, but were created directly around the moving ship.
Asteroid Trivia Generator Code
public class MiniAsteroids : MonoBehaviour
{
private Transform tx;
private GameObject[] asteroids = new GameObject[155];
public GameObject[] prefabs = new GameObject[2];
public int asteroidsMax = 100;
public float asteroidSize = 1;
public float asteroidDistance = 10;
public float asteroidClipDistance = 1;
private float asteroidDistanceSqr;
private float asteroidClipDistanceSqr;
private ParticleSystem pSystem;
private int updateEvery = 5;
private int counter = 0;
GameObject root;
void Start()
{
root = new GameObject();
root.transform.position = Vector3.zero;
root.name = "Small Asteroid Field";
tx = transform;
asteroidDistanceSqr = asteroidDistance * asteroidDistance;
asteroidClipDistanceSqr = asteroidClipDistance * asteroidClipDistance;
pSystem = GetComponent();
}
private void CreateStars()
{
for (int i = 0; i < asteroidsMax; i++)
{
asteroids[i] = Instantiate(prefabs[Random.Range(0, prefabs.Length - 1)]) as GameObject;
asteroids[i].transform.position = Random.insideUnitSphere * asteroidDistance + tx.position;
asteroids[i].transform.parent = root.transform;
asteroids[i].GetComponent().angularVelocity = Random.insideUnitSphere * 2f;
}
}
void Update()
{
counter++;
if (asteroids[0] == null) CreateStars();
if (counter == updateEvery)
{
counter = 0;
for (int i = 0; i < asteroidsMax; i++)
{
if ((asteroids[i].transform.position - tx.position).sqrMagnitude > asteroidDistanceSqr)
{
asteroids[i].transform.position = Random.insideUnitSphere.normalized * asteroidDistance + tx.position;
asteroids[i].GetComponent().velocity = Vector3.zero;
}
}
}
}
}
We arm the ship
The main character’s ship was decided to give the opportunity to carry weapons at six points of suspension (two or four points is too solid for a heavily armed fighter). Arms attachment points were set using GameObjects-dummies, the number of points for the suspension was hardcoded (yes, I repent). At the same time, the suspension points were divided into two types - the main weapon and auxiliary. There was essentially one difference - the weapons on the main slots were activated on LMB, and on the additional ones - on the spacebar. Weapons interacted with the ship quite limitedly - through an interface that provides access to the basic functions, which made it easy to add new types of weapons. In addition, as it was developed, several more functions were added to it, which are responsible for its appearance in the store and hangar interface.
Interface
interface IWeapon
{
void Shoot(Transform target);
void Refill();
int GetAmmoNum();
void SetAmmoNum(int n);
Vector3 GetJointOffset();
string GetWeaponName();
string GetWeaponTitle();
string GetWeaponDesc();
int GetWeaponPrice();
Vector3 GetGUIRotation();
Vector3 GetGUIScale();
}
One of the first screenshots of a ship with suspended weapons.
Five types of weapons were made: a double-barreled cannon, a laser, unguided missiles, a heavy homing torpedo, and a homing missile.
A homing missile for greater accuracy calculated the lead point, with the assumption that the target will move in the same direction at the same speed. As a rule, this was enough for the missile to hit a moving target with a rather high probability.
Guided Missile Script Code
public class GuidedRocket : MonoBehaviour
{
public float selfDestructTime = 5f;
public float safetyDelay = 0.5f;
public float damageRadius = 6f;
public int damage = 120;
public float acceleration;
public float steerCoef = 0.09f;
float maxSpeed = 10f;
public Collider col;
bool armed = false;
public Transform smoke;
public GameObject explosion;
public GameObject target;
Vector3 estimatedPosition;
Vector3 targetVelocity;
Rigidbody targetBody;
public Vector3 fwd = -Vector3.up;
public Vector3 fixAngle = new Vector3(-90, 0, 0);
float startSpeed;
bool first = true;
Rigidbody body;
public LayerMask hitMask;
void Start()
{
Invoke("SelfDestruct", selfDestructTime);
Invoke("Arm", safetyDelay);
body = GetComponent();
}
void FixedUpdate()
{
if (first)
{
first = false;
startSpeed = transform.InverseTransformDirection(GetComponent().velocity).magnitude;
maxSpeed = startSpeed * 2;
if (target != null)
{
targetBody = target.GetComponent();
}
}
Vector3 fwdDir = transform.TransformDirection(fwd);
if (armed)
{
startSpeed += Time.deltaTime * acceleration;
if (target != null)
{
Vector3 enemyPos = target.transform.position;
Vector3 dir = enemyPos - transform.position;
if (targetBody != null)
{
float distance = dir.magnitude;
Vector3 tgVel = targetBody.velocity;
estimatedPosition = target.transform.position + (distance / startSpeed) * tgVel; //примерная точка упреждения
dir = estimatedPosition - transform.position;
}
else
{
}
Quaternion targetRotation = Quaternion.LookRotation(dir) * Quaternion.Euler(fixAngle);
body.MoveRotation(Quaternion.Lerp(transform.rotation, targetRotation, steerCoef));
}
}
body.velocity = Vector3.Lerp(body.velocity,fwdDir * startSpeed , 0.5f);
}
void SelfDestruct()
{
smoke.parent = null;
smoke.gameObject.AddComponent().Set(5f);
smoke.gameObject.GetComponent().enableEmission = false;
explosion.transform.parent = null;
explosion.SetActive(true);
Destroy(this.gameObject);
}
void Arm()
{
armed = true;
col.enabled = true;
}
void OnTriggerEnter(Collider col)
{
if (armed)
{
Debug.Log(col.gameObject.name);
foreach (Collider c in Physics.OverlapSphere(transform.position, damageRadius))
{
if (c.GetComponent())
{
c.GetComponent().AddExplosionForce(20, this.transform.position, damageRadius);
c.GetComponent().AddTorque(new Vector3(Random.Range(-30f, 30f), Random.Range(-30f, 30f), Random.Range(-30f, 30f)));
}
if (c.gameObject.GetComponent() != null)
{
c.gameObject.GetComponent().DoDamage(damage);
}
}
CancelInvoke("SelfDestruct");
SelfDestruct();
}
}
}
Below is a video of the work of two types of weapons. Also, the video shows the effect of the destruction of the enemy, but since it is quite simple, I will not dwell on it separately.
Interface
The time spent on the interface unexpectedly turned out to be very significant, the development of the interface took at least three days of work. I used the UI system, which appeared in Unity 4.6, in my opinion it is very convenient and fairly easy to learn.
The most difficult part of the work on the interface was the base interface, it was necessary to implement quite a lot of functionality. Dialogues, purchase / sale of weapons, sale of items from the hold, repair. As the cargo / weapon icons, their models in orthogonal projection were used, because there was simply not enough time to draw the icons. A short description was compiled for each item, telling the player what it was in front of him.
The first version of the interface, the curve, without the tasks tab
Later, the interface was refined graphically (thanks to the person who helped me with sprites for him, I myself would never have been able to), and began to look noticeably nicer and neater.
The final version, the essence is the same, but more pleasing to the eye.
The flight interface was made easier. The player in fact does not interact with him in any way, and in and of itself he is quite minimalistic. For progress bars, a regular sprite was used, cut by means of Unity into 9 parts and stretched horizontally, very simply and quite nicely. With curved bars on the side of the scope, everything is more complicated. Just stretching the sprite along one of the axes will not work, you need to use a more complex solution. A simple shader was written with one parameter - the cutoff height. It was set from a script, and in accordance with it, the sprite was drawn with the desired filling.
Shader code
Shader "Custom/CrosshairShader" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Angle ("Angle (Float)", Float) = 0
_Color ("Tint", Color) = (1.0, 0.6, 0.6, 1.0)
}
SubShader {
Tags{"Queue" = "Transparent" }
Pass {
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform float _Angle;
uniform fixed4 _Color;
float4 frag(v2f_img i) : COLOR
{
float4 result = tex2D(_MainTex, i.uv);
float angle = i.uv.y;
if(angle > _Angle)
{
result.a = 0;
}
return result*_Color;
}
ENDCG
}
}
}
Screenshot of the flight interface:
The screenshot shows a half-filled health indicator in the center of the screen
Opponents
In my opinion, one of the weaknesses of the game. They have only one tactic - to fly after the player, if he is in their field of view, and approaching the distance of firing, start shooting. Despite this, in large numbers even such enemies pose a serious danger.
Of course, in addition to the behavior mentioned above, they also had auxiliary functions. For example, having lost sight of a player, they flew to the last point where they saw him, and not having found him there, randomly started wandering or returned to the starting point. And also, they sometimes avoided collisions with asteroids, but only if they did not fly too fast. A full-fledged state machine for opponents' AI was not implemented like that, the AI script launched a pass every 0.1 seconds, in which it decided what the enemy would do in the next 0.1s. Because of this, in order to achieve more or less tolerable behavior, I had to start many additional variables that describe the state of the AI.

The main boss was completely defenseless, and relied only on a huge number of his minions.
Quests
Before that, I had never done a quest system, so I had no idea where to start. But there was no time to reason or look for lessons - it was necessary to act, because the second week was going on! As a result, a very ugly system was born with a hard-coded list of quests (to add a new quest, you had to write its name in the variables of the Main Quest Script, increase the number of quests by one, and prescribe which base the quest refers to), with a fixed number of answer options in the dialogs (three pieces), and with other signs of rake jumping.
Dialogs were saved in xml, for their editing a simple editor was even made there, in Unity.
The editor is probably the best part of the quest system.
The quests themselves were made by prefabs, which were instanced upon activation of the quest and deleted after receiving the award. It is crooked, but it worked. The quest system, writing dialogs and the quests themselves took another three days. The deadline was drawing to a close.
Other little things
I would like to list here various chips that are unworthy of a separate section, but which I would like to talk about nonetheless.
Perhaps I'll start with the effect of hyper-jumping. How it looks, you can see below.
It is implemented very simply. First we start the sound, start shaking the camera, show on top of the main model a slightly enlarged model of the same ship, but with the texture of the “energy field”, then animate it using Animation Curves, and before the jump we launch the particle-flash system and hide the main model . It seems to me that for the "low-budget" effect it turned out well.
I also want to tell a few words about the save system. Oddly enough, she is present in the game. The xml file with the player’s name is saved in the game folder, the player’s name itself is saved in PlayerPrefs (in the registry). Theoretically, you can even use several saves by changing the name of the player in the main menu. Saving is automatic, after each completed quest.
It is implemented very simply: the SaveInfo class was created, where all the necessary state parameters of the game are saved, the class implements two methods: Load () and Save (), which serialize / deserialize the data into an xml file using standard C # tools.
Load and Save
public void Save(string path)
{
var serializer = new XmlSerializer(typeof(SaveInfo));
using (var stream = new FileStream(path, FileMode.Create))
{
serializer.Serialize(stream, this);
stream.Close();
}
}
public static SaveInfo Load(string path)
{
var serializer = new XmlSerializer(typeof(SaveInfo));
using (var stream = new FileStream(path, FileMode.Open))
{
return serializer.Deserialize(stream) as SaveInfo;
}
}
That's all, nothing else needs to be done, it remains only to parse the fields of this class.
Save file
Mingebag 150 460 500 2500 25 3 1.99 1.98 Machinegun 0 Machinegun 0 GuidedLauncher NursLauncher NursLauncher GuidedLauncher 6 18 18 9 false 0 true false 0 0 Equipment3 Двигатель Кубоидов Компактный плазменный двигатель, практически аналогичен человеческому. 300 1 100 Equipment2 Граббер Кубоидов Маломощный эмиттер гравитонов. Используется кубоидами как захват 150 1 100 Debris Кусок обшивки Обломки космического корабля. Содержит ценные конструкционные материалы 50 1 10 So, if you are too lazy to go through the game, you can conjure with save and accelerate progress, or put a weapon more powerful.
I would also like to thank the good people who, right in the development process, volunteered to help me with the graphic content for the game. Given its quantity (several dozens of models only), I doubt that I would be able to catch it on time, and there’s no need to talk about quality. As a result, almost all of the graphics in the game (except for two backgrounds and skybox) was created specifically for this game.
Summary
More than half a year has passed since the end of work on the game, and it's time to take stock.
I did not take the prize place with this game, apparently I did not fall into the trend of pixel art adventure. But during the work on the game a huge amount of invaluable experience and skills was gained, and the bumps from the overtaken rake will remind me for a long time that some things are not worth doing.
Conclusions:
- Of course, you can embrace the immensity, but if you have tight deadlines, it’s better not to, nothing good will come of it
- The plot in the game is not the last thing, and it is worth working on it in advance
- Better fewer features implemented than many glitchy ones that the player doesn't necessarily get to.
- Stupid opponents are good for a slasher, for a game with less of them it is better to make them smarter
- Balance is also important, and it is also worth taking the time.
- Optimization is important, and you should think about it in advance.
Of course, many of my conclusions may seem obvious, but sometimes without trying, you will not understand. For example, the desire to make the project as complex as possible is one of the most common mistakes made by novice developers. I could not avoid this problem either.
Finally, I want to show you the gameplay video from the game. On it you can approximately evaluate what happened in the end.
I hope the article was useful to you in some way, or at least it was interesting for you to find out the history of the development of another small game.
Link to the build:
yadi.sk/d/j-v8WoyCiaNuQ
Link to the GitHub repository (Raw code, after the contest almost didn’t correct, and since everything was written in a hurry, the pearl is full there)
github.com/TxN/TWG6-Spacesim