Overview
This week I spent the majority of my time learning that my movement system needs a rehaul. Another good chunk of my time was spent on finishing the basics of my attack system and adding some quality-of-life changes.
Movement System
Prior to now I had designed a movement system using simple vector math to move units in a straight line, avoiding obstacles and each other. That system might work out well for a more straightforward map, but mine is procedurally generated and has giant holes between each of the big platforms.

Clearly that idea wasn’t going to fly. An alternative I spent a good chunk of time trying to design was a little more based on pathfinding. Each Big Hex (the big platforms) has a list of Big Exits (Big hexes adjacent to it) and Exits (small hexes that serve as the connection from one Big Hex to another). On creating the map, I saved each of these values, so the Flock Master can theoretically move to the correct big hex before trying to move in a straight line.
public void SetExits()
{
Exits = new Hex[(int)Exit.numExits];
Exits[(int)Exit.TopLeft] = Map[Map.Count - 1];
Exits[(int)Exit.TopRight] = Map[Map.Count - Size];
Exits[(int)Exit.BottomRight] = Map[0];
Exits[(int)Exit.BottomLeft] = Map[Size - 1];
Exits[(int)Exit.Left] = Map[Map.Count / 2 + Size - 1];
Exits[(int)Exit.Right] = Map[Map.Count / 2 - (Size - 1)];
if (HexNum.x == 0)
{
Exits[(int)Exit.BottomLeft] = null;
Exits[(int)Exit.BottomRight] = null;
}
if(HexNum.x == MapManager.GetInstance().GetBounds().x - 1)
{
Exits[(int)Exit.TopLeft] = null;
Exits[(int)Exit.TopRight] = null;
}
if(HexNum.y == 0)
{
Exits[(int)Exit.Right] = null;
if (HexNum.x % 2 == 0)
{
Exits[(int)Exit.TopRight] = null;
Exits[(int)Exit.BottomRight] = null;
}
}
if (HexNum.y == MapManager.GetInstance().GetBounds().y - 1)
{
Exits[(int)Exit.Left] = null;
if (HexNum.x % 2 != 0)
{
Exits[(int)Exit.TopLeft] = null;
Exits[(int)Exit.BottomLeft] = null;
}
}
}
public void SetBigExits()
{
BigExits = new BigHex[(int)Exit.numExits];
if (HexNum.x % 2 != 0)
{
int[] xPos = { 1, 1, 0, -1, -1, 0 };
int[] yPos = { 1, 0, -1, 0, 1, 1 };
for (int x = 0; x < xPos.Length; ++x)
{
BigExits[x] = MapManager.GetInstance().GetBigHex(new Vector2Int(HexNum.x + xPos[x], HexNum.y + yPos[x]));
}
}
else
{
int[] xPos = { 1, 1, 0, -1, -1, 0 };
int[] yPos = { 0, -1, -1, -1, 0, 1 };
for (int x = 0; x < xPos.Length; ++x)
{
BigExits[x] = MapManager.GetInstance().GetBigHex(new Vector2Int(HexNum.x + xPos[x], HexNum.y + yPos[x]));
}
}
}

Not only did I not implement this correctly, but in doing so, I found other problems inherent in it. For one thing, even if the Flock Master moves correctly along the hexes, if the group flocking is big enough, units will still be walking on air. There’s nothing pushing them to squeeze onto a single platform. Along with that, I would have to give each individual unit that moves its own Flock Master. That’s some extra overhead and would require reworking my current system since commands would need to go through my Unit Manager. For a worker just gathering rocks, it should only really need to know where it is and where the rock is. I didn’t want to overcomplicate that.
In essence, I learned I need to rework my system. I plan on really leaning into the fact that each hex is numbered and in a grid in order to implement a regular pathfinding algorithm instead of my current monstrosity. I don’t have any specific thoughts on which algorithm I’d like to use, but I know I want to find one that works well with oddly shaped grids and won’t be too hard on processing power.
Attack System
This is mostly a continuation of my attack system from last week. Previously, only the AI could attack, and the animations and damage amounts were a little wonky. I’ve improved on all of those facets. The player can now attack both buildings and units with voice recognition, and overall I think it looks a little neater. Here’s what it looks when the player attacks.

You may have noticed something new with that last gif. I added death functionality and animations to units so that death actually has a consequence. Next on the agenda is doing the same for buildings.
The commands are simple yet cover most needs for the game. You can attack either Nearby, All, That/Those, or The units/buildings. If you have multiple units and multiple targets, they’ll choose their targets randomly. Nearby will target units or buildings on Big Hexes adjacent to the one the player is looking at, and That/Those will target units and buildings on the same Big Hex. Eye control will be implemented very similarly to how selecting friendly units works, where the player specifies how many units they’d like to attack when selecting a hex with attackable units or buildings.
Naming Buildings
I received a suggestion that naming buildings so that they can easily be selected later would be a good idea. It turns out, yes, and also it’s pretty easy. The only big change I had to allow for was multi-word phrases, as my current system only handled one-word commands (as in “build three workers“). The reason for this is that I split up my commands into a list of space separated strings to make parsing better. So in the case of multi-word phrases, I combine my list into a single command and check for the index of the start of that phrase.
Once I had multi-word commands, I just needed a command for naming things and selecting things based off of a user-defined command (the name of the building). All that required was changing my phrases from an array of strings to a list so that the size is mutable, and I read in the new words. In the case of renaming a building, I look for the old name and replace it if necessary.
To implement this, I also added a command for selecting the last building placed. It can also select by building type, like barracks, school, tower, or base. This makes selecting each building possible. In the future, I’d like to expand on this to be able to select buildings created a few buildings ago so you aren’t stuck with only naming the last one, or with giving every building a unique name at the start.

Speaking of giving something a unique name at the start, I did just that for units. This was used mostly for debugging as the names are not visible to the player and are currently without functionality. I personally have always loved randomly generating names, so this is something I’d like to go a bit further with if it can be of benefit to the game.
Quality-of-Life
I made some minor improvements to the game to let the player both know what the AI is currently up to and to let the player know if they make a mistake. They both use the same system, and it’s pretty easy to add onto. Any time it’s necessary, I make this little dialogue box pop up in the corner to communicate something to the player. I want to have some sound effect for them talking, a la the Onion King in Overcooked. Something reminiscent of human speech, but not quite sensical.

One thought on “PPP Week 8”