Saturday, 28 May 2016

Week 12

Finalizing the Game

Summoner's Rift - League of Legends
 This week, the most important job had to be finished (also presumably one of the harder parts to code) - The Wave System Implementation!!

 While it was touched on during the previous weeks (as a Core Mechanic), it was never actually fully implemented and left as a String based system that didn't really affect game-play (it was like a game of its own).


 Blocks of Code were commented as "Insert Minion Spawn here" were never actually finished and the entire Wave System was left quite raw. So obviously the first thing that was attempted was to hook up exactly the way the blocks of code were commented -- put minion spawn here etc. etc.

 But unfortunately... that didn't exactly work...


This was because Julian's Minion Spawning Scripts happened on event ticks - meaning that every frame that the game runs, the game checks if the number of a minion spawned equalled its max wave - if not summon another one.

I had my "raw" Wave coding under a Custom Event that was called once instead of every frame. This Custom Event would've summoned X Minions were X is the Wave Length rather than spawning it one by one as in Julian's code.

It also so happens that due to the way Custom Event works in Unreal, I also could not connect it to the Event Tick Node. This meant that I had to completely redo the current Wave System to accommodate.

That had a fairly easy solve which was to imitate Julian's code and move the Wave Checker into the Event Tick - so every frame of the game, the game checks if every monster has been killed, if so - increment the wave and reset the variables.

But there the second problem arose... How to count the Dead Enemies.


The first way was of course, a series of simple steps
  1. Set an Integer called Enemies Killed
  2. In the Enemy AI, make it so when an enemy is killed, increase the integer
  3. If the Integer matches, start next wave
 But... coding never is so nice. To obtain the when an enemy is killed, you would have to cast to the Level Blueprints (an almost infamous problem at this point). With Unreal being quite strict on not allowing you to cast to the Level Blueprint (preferring you to use a much more painful Event Dispatchers which are complicated and frankly never work...), we had to forego this method.

The alternative was to put the Enemies Killed Integer in the Enemy AI Script and then collect it (calling it) at every tick in the Level Blueprints. This was met with several issues again...
  1. Flawed Logic - since every enemy is its own being, it doesn't share its variable. So every individual enemy will have 0 enemies killed, and when they die, it increases to 1. That doesn't mean that every enemy has their count increased... just that individual monster. 
  2. Casting to Ironshell AI -- Casting is used to obtain a variable from another script (in this case one of the Minion's AI). Unfortunately... Due to the way it spawns as a Pawn, there was no Object we could find to link with it and we could never call it.
The Solution

 It actually came to me while playing League of Legends. Every player had CS or "Creep Score" which indicates the amount of monsters killed in that game. Since I knew for sure that casting to the Player is possible (and the go-to method for all coding in Unreal), I ended up creating an Enemies Killed variable in the PLAYER'S script. 

 This acted as a "Creep Score" of sorts and every time the Number of Enemies Spawned equalled the Enemies Dead -- Start next wave, reset all the variables.



 While definitely NOT the hardest Code I had to do this semester, it was one that required a bit of thinking to figure out how to piece it together. As quite an important part of the game - a ton of play-testing to make sure it worked correctly was done. Minions had to spawn correctly, Wave had to increment, there had to be a Delay between the Waves... It all had to come together.

Fortunately. It did.

Friday, 20 May 2016

Week 11

Death Do Us Part!
Marvel Punisher
 This week - I got assigned to handle the Death Conditions - which means dying from Turrets, Minions, Environment Effects or just jumping off ledges. It's pretty good as it is a busy week from other subjects.

 So the first thing I did was to figure out the different ways people are resetting the Game State (so when you "Gamve Over!" you had something to fall back on.


 I found that most people utilized an "Open Level" Node which pretty much loads up another map. The main concern I had (before testing it and also why I googled for more ways before trying it) was that Opening a Level was used for a player entering new Levels as well (such as Level 1 -> Level 2) which meant variables could be saved such as Gold.

But... after testing - this was found to be a near non-issue so I decided to press forward with it. And as to provide player feedback - a very basic GUI was designed for the Game Over Screen.


 It was super simple - if you died - press the Restart Game button to... Restart the Game! Nothing much to say.

 So, the only coding left was when the player died... At first I thought this HAD to be handled in the Level Blueprint -- if a player reach 0 health, change the game state. But as I began coding it - I quickly figured out a faster and perhaps more efficient way of coding it.


 It was an EXTREMELY simple -- if the Character itself is destroyed (not it's health equalled to 0), create the Widget. After all, if the Character is destroyed, the player can't do anything EXCEPT click on the widget.

This of course, needed me to do a little more tinkering in other scripts (making sure that when enemies attack the player, if the player had 0 health, destroy him instead etc.). But the Script compiled and functioned as planned.

However, when the Enemies killed me, I could only observe as they continued to drone on mindlessly towards the Nexus and I remembered an old game I played. It's Game Over Screen significantly slowed down time as the minions continued moving in the background. It made it feel like the enemies was slowly stampeding on your corpse and I thought it was a fantastic idea.


With that, Time Dilation was added, it made the game progress in an extremely slow pace which meant that the Game State was not truly halted (which didn't matter since the Character was dead).

The only thing I didn't manage to hook up doing the Game Over State was the Environmental Effect "Acid Rain" which Mickey was working on this Week. Aside from that - this week was more of a relaxed week with quick rapid coding (which I was quite thankful for).

Sunday, 15 May 2016

Week 10

Waves... Waves... And More Waves!!!

Picture from League of Legends

This week, a fairly important aspect was given to me which was implementing a Wave System. This is one of the Core Mechanics of our Game and had to be tied up this week. As such, I was in charge of getting the Wave system itself while Julian had to handle the Minion Spawn.

 Based on the Skype Discussions, 2 options were thrown up for the Wave System.

  1. Waves Increment (Minions spawn) after all pre-existing Minions have been killed
  2. Waves Spawn after a certain set time - this imposes a penalty if the player doesn't kill all the minions in time.
Weighing the Pros and Cons of each option -- the team decided on the first option. This matches the style of more traditional Tower Defences. This allows a more relaxed pacing of the game instead of needing to constantly worrying when the next wave would spawn.

 With the Wave System "style" being chosen - Code has began to be processed. Unfortunately, after starting the basic "At the Start of the Game", I remembered that the Spawn Minions coding has not yet been implemented (thereby cannot be used).


 As such, a "substitute" set of codes was used which involved setting an integer called "Number Of Minions Available". In addition, a String shows up which presents to the user as a "proof" that X minions have spawned. This allows troubleshooting for future methods that will be implemented in the Wave System.

 This Code System should be replaced with the "Spawn Minions" code upon completion and was commented as such for other programmer's awareness upon implementation.


So, it's time for the actual Wave Implementation...

Like the design we agreed on, we check if there are any enemies still alive before initiating the Wave Incrementation system. As a Custom Event, the plan is to attach this to whenever a minion is killed (in other words, if a minion is killed - run this event).

If there are no enemies still alive - run a String announcing the Wave's end, increment the wave and respawn the enemies. Again... with the Spawn Minions being inexistant, this Implementation was all code-based.

Unfortunately, since the "actual" minion spawn hasn't been coded (which has been a fairly major issue when creating this code). Another method is needed to be made to reduce the integer created earlier (Number of Minions Spawn) to test if when the Number of Minion Spawn reaches 0, the wave system is activated.


Another more simple event based on a key-press ("V") was formed. All it did was "kill a minion" and reduce the Number of Minion Alive integer. Following this, it calls the custom event above (that is the actual Wave Implementation). 



This worked perfectly and while it wasn't the Wave System we all dreamt of - it's definitely a step in the right direction and that we had some idea where we want to go.

Friday, 6 May 2016

Week 9

Turret Fixes Galore!

Image from Halo
 With last week being... quite the disappointment in terms of production and this week being the first week of putting everything together - We had to work extremely quickly to get things functioning. Tons of Googling and Placing Towers YouTubing were done across the weekend to get the Tower Script working.

 I drew a lot of inspiration and code ideas from the "Unreal Engine 4 Simple RTS Building Placement" Video by pally qle.


 While the video's code didn't fit our needs exactly, I had to play around with the code to allow it to fit our needs a lot more... Thus coming up with the following code:


 This code was brought to the Programmer's Meet (where everything comes together and all bugs are fixed) where we decided to add various bits to the Spawn Towers bit based on Julian's code (Player value implementation).


The following code was added to the bottom of the Build Turret Code which was worked on by all 3 Programmers. This uses Julian's code which implements the player's Gold and checks if the player has enough gold to build the turret in the first place.

Overall, we've got the Player setup quite well this week - They can move around, build turrets, shoot and has values for Gold and Health.