Friday, November 14, 2014

Update 41: Code Reorganization

This last week has been productive and I have almost completed path finding! This involved a complete reorganization of the code files to implement namespaces. The new structure really enabled me to connect all the pieces together so that I can now click around my levels, moving my units from side to side. My new namespace structure looks like this:

Characters

--Actions
--Pathfinding
--UI
Common
LevelEnvironment
Main
--UI

I debated having UI at the root level with "Main" and "Character" children, but ultimately decided that these UI elements would be completely different. The diagram below should what the code map looks like after the new reorganization:





I've also developed a process to implement new features in a safe and comprehensive way, using several levels of prototyping. This is similar to branching, which many software development processes use (but I do not). My process usually starts with an almost blank level. Once the feature has been implemented, I usually integrate my new feature up to one of my intermediate test levels, testing in a controlled environment with a 
few buttons to test movement and shooting. This is typically my 'tank test' level which has a few static objects and buttons to constrict movement, almost in a unit test sort of way for regression testing. The final step of my process is to integrate in the feature with my actual game levels. This means it can take a while for a new feature to make it into the game, but it's also a comfortable way for me to test new features and not put them into the main game until I am ready. 




I've been using this with path finding really successfully, which is why I'm confident I will have it complete by the end of November.


Finally, I have the bug of the month. In the top design view panel, you can see an in progress picture with a sample level. All of the red nodes indicate areas that are not-walkable, generated by my path finding. In the bottom game view panel , you can see that... I have no grass/ground. Where did my ground go? It turned out it was a relatively simple problem, my camera had turned off the option to show the ground, but it did create a few interesting levels...




Thursday, October 30, 2014

Update 40: Dynamic Pathfinding

The last two weeks have been focused on getting a basic dynamic path finding algorithm to work. This includes getting the object to follow the seeker path, and allowing for dynamic environments.

The first screenshot shows where I've been up until today. The path finding is 'baked' into the screen and there is a path from the beginning (green gate) to end (red gate).



The second screenshot shows me what it looks like with some dynamic objects added to the scene and dynamic 'baking'. Here I can see that my green path adjusted to avoid the new dynamic obstacles and created a new path to the end gate.


The ultimate test of this is to move the end gate to the other end of the screen. 



This is all good news. Now that my prototype is working, I can integrate the path finding within my game.

Friday, October 17, 2014

Update 39: Exploring Pathfinding

Another week, another round of bugs fixed.

  • Added some basic sounds for explosions and shooting
  • Fixed some bugs around shooting when I missed. The bullet would stop at the target, instead of continuing into the sunset. 
  • Upgraded the shooting range modifier using the formula:
    • RangeModifier = 50 - ([tiles between source & target * 5)
  • Upgraded the AI to choose the best target based on the difficulty, instead of taking the first enemy off the list
  • Started work on creating a path finding solution. I'm using the Aron A* Pathfinding Project. You can see an early prototype below. The first screenshot shows no smoothing, the second with smoothing.




Friday, October 10, 2014

Update 38: Adding messages and more polish

This week I added a messaging system and fixed bugs. The messages show a status with showing a hit or miss with each shot . This really ties each action to a result, which I think is important.






I also have a few bloopers. This is a result of my very simple movement AI. When two tanks get close to one another, the physics pushes one of top of another, in a manner very similar to a tectonic plate in the earth's crust, but creating some humorous situations.





Next week I'll have some initial path finding results, after having some success this week using Aron's path finding plugin.

Friday, October 3, 2014

Update 37: Polishing the new UI

Another productive week, where I created more prototypes than I ever have before (in game development). When we last left off, I had created a GUI with a very discrete representation of health. 



The next step was to try and use the parallelogram design that so many modern games use. Fellow Turn based development enthusiast Stew Trezise (His website: boymeetsdinosaur.com) mocked up the following design: 




My first attempt seemed to have the health cells a little tight together. It looked great in the mock up, but needed more room. 



It also needed a slightly bigger border to give it more definition. The next revision was starting to make sense, but the empty health cells were not quite looking right as a white color.


I experimented with different colors before settling on no color. Here is the (current) final version, with transparent empty health cells.



As soon as I integrated this in the game (which was very easy since I was working off a GUI prefab), I noticed that having so many GUI's visible was a bit distracting. My solution was to show the selected player (and target) with the normal brightness and lower the transparency of everyone else by about 50%.


This works well, especially when there are a lot of units piled on top of each other.


Next, I'm going to work on creating a little hover to indicate status (and health) changes.

Friday, September 26, 2014

Update 36: Integrating the new UI to the game

I have a working game again. Each of my tanks now has the new GUI and I have more objects in my levels that provide cover and explode. I clearly have more work with the GUI, but it's giving me many opportunities to improve.

First, here is a screenshot of my slightly upgraded tile set. It is the first step in having more environmental objects. These will eventually become buildings, but for now are just big stacks of bricks.




Here are a few screenshots of the new 
GUI in action. It's currently pretty busy.
Very busy. There is a lot of GUI overlap, mostly because I'm using the default GUI slider control, which has a white border. 



I started by dropping the white border around the red bar. This helped, but the next stage is to highlight the targeted enemy, hiding the rest of the the (non selected) player GUI's


Eventually, I'll be creating a new GUI with a more discrete representative of the health. This will help to show how strong a player is, and really simplify the overall GUI.



Friday, September 12, 2014

Update 35: Back after a summer break and the new GUI

I had a little break over the summer to focus on a few other projects, but I never stepped that far away. With the release of Unity 4.6 Beta, I've jumped straight into implementing the new GUI. I've also further enhanced the explosion script and reworked the hover tank prefab to work with the new GUI. While the screenshot certainly doesn't look amazing, it is a big step forward for me to have a GUI that follows the character. Next is adding all of the new buttons and actions to the main GUI.



Here is an early sample of the new GUI in the main game:


Friday, May 9, 2014

Update 34: The AI is playing itself and the beginnings of a campaign.

Accomplishments this week:


AI: One of my next tasks was to apply the AI to both teams of the tactical game. While I wait for Unity 4.6's new UI to be released, using AI on both sides allows me to ignore the UI and refine the AI code. This also has the positive side-effect of preparing the AI to work better in multi-player games. This also includes selecting, targeting and dead (smoldering) tank animations. You can see these below.



Campaign: Moving next to the campaign, my goal was to create a very simple UI where:

  • Time would pass
  • Enemy encounters would be spawned
  • The game would load the tactical level with the right players and enemies
  • Auto resolve the battle with the AI
  • Return back to the campaign, where the players would receive experience and abilities as they level up.


I had to fix a lot of bugs with the AI and camera to make this all work, including creating a new static game object, but it all works great.

What is next:


  • Game Balance: The tactical game isn't currently very fair 
  • Refining the character sheet: I need to add some new properties to the characters that I am now using
  • Adding in the Campaign Diorama
  • Adding objects to the tactical game
  • Leveling up the tanks: Character progression is very important to this game

Friday, May 2, 2014

Update 33: More Refined Destruction

After refining the decay code, I went to work combining it with the destruction code. As I mentioned before, the idea was to dynamically explode my object and then use the decay to clean up the exploded blocks. This would double as a garbage collector and visually clean up the screen after the object had been destroyed. I also spent a lot of extra time making sure it would work with objects of different sizes and objects rotated. Subtle, but challenging to get right in all places. Below is a series of screenshots showing the current explosions and results. The biggest trouble I had was creating an object in the middle of my explosion with the right force. I'm very happy with the results here. You'll also notice in the during screenshots that 30% of my cubes are applied the same explosion texture as the center of the explosion. I found that this helped with performance and the explosion animation.

Square before:

Square during:

Square after:

Tank before:

Tank during:

Tank after:

Friday, April 25, 2014

Update 32: Decaying objects

I wrote a class today that I add to components I want to remove from the game (for example, my destructed walls). 

I add it to a gameobject like this: (where character is a gameObject)

            character.AddComponent<DynamicExplosionPiece>();

In the "Awake" method of this class, it randomly generates a number between 0 and 10, which is the number of seconds in the game before the object dies. What this means, is when I create 100 little objects for my destructed object, the game cleans them up after 10 seconds - at the most!. Because it's random, it has a decay effect. Here is a screenshot, of a recently dead enemy (red) tank. The turret has decayed, the cannon has not, and about 25% of the square body has decayed.



The actual class is here:

using UnityEngine;
using System.Collections;

public class DynamicExplosionPiece : MonoBehaviour
{
    void Awake()
    {
        StartCoroutine(StartTimerBeforeDestruction(Utility.GenerateRandomNumber(0, 10)));
    }

    private IEnumerator StartTimerBeforeDestruction(float time)
    {
        yield return StartCoroutine(Wait(time));
        Destroy(this.gameObject);
    }

    private IEnumerator Wait(float time)
    {
        yield return new WaitForSeconds(time);
    }
}

Sunday, April 20, 2014

Narrowing in on the game design: "Hovertank Wars"

Things are coming together nicely after an extended break from posting here.

I've had a positive look at the scope of my project and make a few changes to simplify what I'm trying to achieve. As a result, I've spent the last few months rewriting the design document and refactoring the code to create a new spin I am calling: "Hovertank Wars". Instead of soldiers, I will now have these hovertanks. Here is a screenshot of the test level I created to animate and test the new model:



I have a rotating tank, with pivoting turret and cannon. It fires explosive bullets:


I'm now refactoring the levels to use a new scale appropriate to these tanks as well as building a new campaign. 

Friday, February 14, 2014

Line of Sight

I've managed to implement a simple line of sight mechanic with ray casting. If my character can't see an enemy - because they are behind another object and therefore, not in 'line of sight' of my character, I hide the mesh renderer on the object, effectively making it invisible. 



The great part about this solution is that the enemy character is still there and it's AI is still running. When the enemy character comes back into view again, I just enable the mesh renderer. Every time a character moves, I ray cast between each character and enemy to see if they are visible and then hide and show the enemy character depending on if they are in the line of sight of my player.

Here is a sample where I can't see the enemy (although, because I haven't yet replaced the UI of the enemy characters, you can see their health bars - this will be fixed later):



And here, after I move around the obstacle, I can see the enemy character again.


Monday, January 27, 2014

Random Levels - Part 3

With the theory done and a solid prototype, it was time to implement the more advanced level creation into the main engine. I started by implementing the 6 tiles I needed, a vertical, horizontal, and the 4 turn pieces. I considered refactoring the pieces so that there were just two tiles and then rotate them to fit, but I realized it would be better to create the extra variation. Here is a screenshot all 12 tiles available now:


I moved my prototype code over to the main engine, replaced a few lines of code that were specific to the console app and generated my first dynamic level with a river.


With that working, I brought in the rest of the tiles (the previous screenshot was just river and a blank tile). The following two screenshots show two random maps with more of the pieces.




I can't begin to explain what a giant leap forward this is for me.

Sunday, January 26, 2014

Random Levels - Part 2

Happy with my new random levels, I quickly discovered that some of my map combinations didn't make much sense, especially when rivers or roads were involved. In the sample below, you can see two river tiles are connected with a tile with no river - it just doesn't look right.



To make better maps, I needed to a river/road to start on one edge and finish on the opposite edge. I started a prototype to solve the problem, migrating over a few level data structures from my game - fortunately my design and structures were generic enough to allow this. My initial plan was to take my level area, draw a continuous river/road across the level, and then fill in the blank tiles with random tiles. To work through this, I created a simple console application to output ASCII, using these tiles as samples:

╔0══╗╔1|═╗╔2══╗╔3|═╗╔4|═╗╔5══╗╔6══╗
║   ║║ | ║─────║ └────┘ ║──┐ ║║ ┌──
╚═══╝╚═|═╝╚═══╝╚═══╝╚═══╝╚═|═╝╚═|═╝

With the templates in place, I started work on the tiles. The first level, running my current level creation algorithm, looked like this, again highlighting how ridiculous this all looks:



Next, I went to work drawing the river first, and then filling in the remaining tiles. This wasn't too difficult, starting with a simple (3x3 level): 



...and scaled nicely, getting more complex quickly (8x8 level):



Finally, I adjusted the path-finding of the river, so that it wouldn't drop back on itself. Essentially, if I start from the left, let my river go up, down and right, but never backwards (left). The output looks like this:



This is exactly the result I was looking for. Additionally, it scales up easily, I ran some 100x100 samples in less than a second.  The next phase is to recreate these tiles in my game, the next post will be about this process. If you'd like to play with the prototype, I've posted the level creation tool online here.

Saturday, January 11, 2014

Random Levels - Part 1

After scaling up my levels and populating them with the new assets, I went to work creating randomized levels. The original xcom had 10x10 tiles that were randomly added to a level to create a 100x100 sized level. This worked very well to create a new experience in every level, even though the buildings were often recognizable.



I've only created four 10x10 tiles so far, but I've made them all prefabs. In the screenshots below, you can see two of the prefabs highlighted. Note that this is only a 20x20 level, with only 4 tiles of 10x10 each. 




Now when I load a level I am able to randomly choose, arrange and rotate these tiles to create a random level. This is a huge step forward for my project. By creating 10x10 prefabs with content in the center, I can really create some interesting levels. Here are a few more samples:




This last sample is a 30x30 sample (9 tiles total) from a five tile set (one of the tiles is blank):