One of the cards I have on my Prototype board in Trello was “Show Attack Tiles”. I’ve already had the logic to highlight the movement tiles for a while, but I always knew that I wanted to come back and increase the range of highlighted tiles to show where the unit can’t actually damage other units with its equipped weapon.

The idea actually came from the Fire Emblem series, in particular, the ones on the 3DS (though I’m sure the GBA ones also did this). Honestly, that’s the only turn based RPG series I’ve played in the past decade. Of course, I came up with Final Fantasy Tactics, Shining Force, etc., but I haven’t played those in a damn long time. But as far as I can remember, those games didn’t have that. If you wanted to see if you were within range of hitting an enemy after a move, you would have to first move there, then check. This way removes a step, which in itself doesn’t seem like much, but if you add that up over hours of playing the game, plus add in the fact that you could potentially see X enemies you’re within range with, versus checking each one… You see where I’m going with this.

And this is really at the core of how I’m attempting to design this game. I want to eliminate as many superfluous steps as possible. The player should just be able to get on with the game, and not bothered by pop up confirmation buttons, or the aforementioned issue of finding out if you’re within range of attack and enemy.

Here is an example of how it is with Fire Emblem:

 

Pretty self explanatory. So, as you can see by looking at today’s GIF, you’ll see the following 4 units and their movement/attack ranges (denoted by the color of the circle that represents the unit):

  • Pink: Movement 2 – Attack Range 1

  • Dark Blue: Movement 2 – Attack Range 2

  • Teal/Light Blue: Movement 4 – Attack Range 2

  • Green: Movement 5 – Attack Range 1

Some things to consider for each of those units:

  • They cannot move to a tile that is occupied by another, and the attack highlighting does not show up for friendly units

  • While a tile may be unwalkable for one unit (mountains, water, etc.), they can still attack other units at those unwalkable units (i.e. flying unit)

  • If the unit has enough movement to technically make it to the other side of a unwalkable tile, but that tile ends up being orphaned (i.e. no connecting tiles), then that tile is inaccessible, and therefore not highlighted. Of course, if that unit can fly/teleport, that’s a different story. For now, I’m not even dealing with that. One thing at a time 🙂

Now, this took me… I guess 3 days to complete? I cannot remember, but I did have my daughter with me Friday night/all day Saturday as my wife was away, and I try not to be a terrible Father, so of course I couldn’t do as much as I would normally get done with her here to help. I ended up implementing different solutions, and the 3rd one ended up being the charm.

FIRST ATTEMPT

At first, I was like, “Oh yeah, this will be easy. I already implemented the highlighting of the movement tiles, so adding an additional x tiles to iterate over, and making them red will be easy.”

And I did just that. The movement highlighting logic loops over all 8 directions for x number of tiles the unit can move. So I just increased that by 2, and was hoping I would be on my merry way.

Then, it became apparent to me that I had a terrible bug in the system, where I was showing orphaned tiles. I had never really noticed it until I moving towards the water on the map with units that had a movement of >= 5. What I ended up seeing was this orphaned blue tile surrounded by red tiles. No bueno.

SECOND ATTEMPT

For this next attempt, I had to take a step back and think about it. How could I not show these orphaned tiles. I decided to start down a path where I would show all tiles, then run another function that would locate the orphaned the tiles and remove them from the game. This all happens pretty quickly, so the player would never see it, but it’s not that efficient. Again, I’m in prototype mode, so I didn’t let those details derail me.

I had some logic coded up in between playing with my daughter and putting her to sleep. When I came down to my man cave, I was excited to try it out. It seemed to be working… Most of the time, but there were edge cases where the right attack tile was not highlighted, or a movement tile, for that matter.

THIRD ATTEMPT

At this point, I was getting a terrible feeling I was going to have to leverage my pathfinding code to do something like… Check if every movement tile could actually be reached. Again, not terrible efficient, but again, this is a prototype.

Luckily, before I went down that path, I realized I had a bug in my IsOrphanedTile function, where it was only checking N, E, S, W tiles. All NE, SE, NW, SW tiles were ignored. Sigh… Even more, I realized that I had the same bug in my HighlightAttackTiles function as well. Double sigh… Also, because yay for code re-usability, I had all the logic for both attack and movement highlighting filtered to a single function, which calls IsOrphanedTile. Which of course doesn’t make sense for attack tiles, since those could legitimately be orphaned. Triple sigh…

Once I realized the error of my ways, I quickly coded up fixes, and voila, the shit worked.

So the way it works is as follows:

  • Clear out all highlighted tiles

  • Highlight all movement tiles (which will now handle kicking out orphaned tiles properly)

  • Taking the existing movement tiles, highlight all attack tiles. This is heavily predicated on the highlighted movement tiles being created properly.

Now, I have some small code changes before checking it in, merge the branch to master ,and moving on to the next card I have.

Speaking of that next card, it’s “Allow Clickable Turn Order GUI”. This terribly ordered card title simply means that when the user clicks on a portrait on the Turn Order GUI, the camera will focus on that unit on the map. I’ve never dealt with handling those types of events on UI objects before, so should be fun.

Till tomorrow…

P.S. All this logic I just put in should just work for the CPU. We’ll see…