On the way - to the start climb the ridge!

"When something is right, you just know it. Remember the feeling, dont doubt about it when the times are hard and use that feeling to motivate yourself. As the knowledge in the magic of creation will grew wider so the power to create." 

It was a lovely Christmas day and with my lovely all knowing partner we were watching the most christmas film ever made - Hacksaw ridge. It was also a time when I was thinking about a new game. In fact I had one in my head for a long time but I was still not satisfied with the idea and this time I did not want to do something what does note pull me into "my world". "My world" is a term used by my all knowing partner when I am focused on something and forget about the world around. But I liked that idea a lot and so the game below was created.

Game description

"Dive into the battlefield to save your companions while trying to avoid being seen by the enemies."

This is the core idea of the game - the pitch. A player role is to save as many wounded soldiers as he can from the battlefiled by going for them into the battlefield and brining them back to the ridge. There are enemies randomly spawned and moving on the battlefield with the visible field of view. The player has to avoid this field of view otherwise the soldiers will shoot him and the game is over.

Of course more I thought about it more ideas were added into the game. For example there was a scene where soldier told to Desmond something like " Do you know about the sorting order? This man does not have a huge change to live.", but Desmond responded that he promised him to be saved. I really wanted to capture this and therefore the idea of the "morale" mechanic was created. By running on the battlefiled the wounded soldiers spawn randomly around you with the countdown. If the countdown hit the zero, they die. If you save someone you gain morale and if you are not be able to save someone, you lose morale. If you have negative morale - game over. If the enemy kill you in the process - game over.


You encounter quite boring section about mechanics of the game (apart of enemy ai, i think thats quite good). In case you would like to avoid it and read summary skip to section summary . In case you have read enough, feel free to stop reading here. If you are not able to make a decision for yourself throw a dice. If the result is 1 - 3 read next section ,if it is 4 - 6 stop reading.

Core mechanics

Altought I mostly use the courses which I bought I did use free tutorial on youtube to create core features of this game and I have to say I was not dissapointed. The level of the tutorial is on the same level as the ones which I paid for and sometimes even higher (in comparison to visual effect tutorials or tutorials from awesome dudes).

Field of view

One of the crucial mechanic for the game is the field of view - what enemy can see. You can find first episode of the course here. It helped me to create the field of view (vision) for enemies. And not only that - it was so clear that it was not hard at all to understand what is going on. Altought I would not be able to rewrite from scratch (at least at this point) I was able rewrite it for 2D and also update the code a bit to prevent marking as visible object itself. Whole code and the tutorial remind me good old days of computer programming class at university. It took me 3 hours to get this done.

pic.1 - field of view in progress; red - rays from raycasting
The summary here is pretty easy - in fact it is nothing more than checking the collision inside of the radius and comparing the angle between the visible object with the angle of the field of view. The angle has to be compared in local space coordinates of the object holding the field of view otherwise it would not work. The purpose of the raycasting (the red lines on the picture 1.) is solely for creating the mesh (looks like triangle fan) to visualise the field of view.

"If it is that simple why did you spend 3 hours to get it done?". Well, first of all I had a typo in the code. At the time of this post I was not on the level of wisdom to get a rest if something does not work as it is supposed to. So more I was tired more it was hard to find it. I would not lie if i told you that at least one hour was spend to find it. Secondly it is not just about what is visible but there was also some optimization of the code and lastly - in theory it is simple but to do it in unity is other thing. There were some new methods which I did not know and to understand it I had to read the documentation.

pic.2 - field of view finished and in action

A* path finding algorithm

One of the topic which I wanted to explore was A* path finding algorithm. I have an account on Trello for topics which I want to explore divided into three main section - identification, discovery and practise. In the identification I have a topics which I red somewhere about and want them to learn or discover more about them. In discovery there are topics which I am currently learning about and in practise there are topics which I learned but need them to practise in order to remember them and undrestand them more deeply.

Anyway it was a right time to try it the algorithm because in 2D I was missing the possibility to navigate enemies to certain point on the scene. NavMeshAgent component does not work by default for 2D and rather than bend the component to work with 2D I have made a decision to try write solution by myself. Of course with the help of the tutorials.

pic. 3 - TOP - grid for algorithm and the shortest path between enemy and player, BOTTOM - gameplay

What is going on anyway? Quick summary would be that the world is covered by grid of nodes where for each node (well, more for the neighbors on the way) the cost of movement is calculated from start position to the node and from end position to the node. The path if then compounded from nodes with lowest sum of cost of movement from start to position and from ending position. Again, sounds simple, right? Well it took my 07:31:00 and I did not have to do any extensive modifications.

pic 4. - final result of A* path algorithm without smoothing and weights

Enemy AI

For enemy AI I prepared 5 states in which the enemy can get into. More precisely it is:

  1. Searching
  2. Follow
  3. Alarmed
  4. Execute
  5. Lost

pic. 3 - enemy states

I actually wrote this part of the blog in advance but after the prototype was finished I had to rewrite it. I had a plans big as Death Star itself and it failed just as the first Death Start - it was not proton torpedo proof.

For the first implementation I had decide to use enums and switch statements. Enemy state was switch in numerous different methods covered with so many ifs statements that when I had to do some change it took my without exaggeration almost an hour and everything what worked till the moment of change felt apart after the change was made. After this piece of art was finished, some tears where shed and looking at the bottom of empty glass (of water, you alcoholic! put down the glass and get your life together) was done I rewrote it using the interfaces and unity events. Of course some of the ifs had to remain but just to prevent going from one state to state not allowed.



Rest of the main mechanics

Morale

"God, please, one more, just one more!". The morale keeps you going. If you lose morale, you lose the game. I was in fact thinking that it could be called willpower or something like that but for the prototype it is called morale. I heard that a lot and it sounds right but I am not even sure why. Mechanic is quite simple. As the player run around the battlefield he hears wounded soldiers. If any soldiers who he heard die he lose morale. If he save him, he gain morale.

Life countdown

Each wounded soldier is spawned with some life countdown. It should mirror the state he is in (how badly he is hurt). If the count down runs the zero the wounded soldier die. If his screaming was heard by the character the character lose morale. If the wounded solider is spotted by enemy he is executed.

Vitality

More player run around battlefiled more he lose vitality. If the vitality hits zero the player movement is slowed down. He can get it back by stop moving, moving silently or by saving wounded soldier. The vitality was introduced to limit the movement of the player so the enemies have got a chance to catch him and kill him. It is also other resources to take care of. I am also thinking about limit the vitality with more wounded soldiers saved, but we will see.

Restricted zone

Restricted zone was developed because I was playing with the idea that game should get harder more the player dive into the battlefield. So I created zones for spawning wounded soldiers/items based on the score of the player. For example, if the player has score 5, the wounded soliders will be spawned between 0 - 10 unit of distance from ridge. If the player has got a 11 then the boundaries for the spawn zone will be from 10 - 20 unit of distance from the ridge. This should be neverending, but it is not since I have to first figure out how to do procedural generated levels. Anyway, to prevent the player visit zones where nothing happend the restricted zone was created. It is moving with the spawn zones (really captain obvious?). 

Summary

It was a long route for sure and much more is in front of me. Assets like sounds (there is going to be dubbing), sprites and effects has to be made. UI has to be done, level has to be prepared - where the enemy will be moving, how the obstacles will be positioned. But so far I am happy with the result. More happy than with my first game. I have also ideas for items to be spawned (like morphine to extend life countdown), obstacles which block vision just from one direction to simulated trenches.

During the development I decided to take some courses of C# and math because I felt how lack of kwowledge in this areas were limiting me. Therefore the game can take longer to be finished. My best guess is around end of the february it should be done. :)



Important note: 

  1. StarCouroutine(string name) can be then stopped by StopCouroutine(string name). If you use StartCouroutine(Method()) it cannot be stop!


Time spent on learning [121:32:00] - and guess what?! Every second is important!










Comments