Thursday, March 12, 2020


The base game comes with a single paper hexagonal map. It contains a variety of terrain features, hills, gullies, cover as well as a number of paths, roads and crossings. Villages are represented as wood, stone and brick buildings, some with alleyways. Hedgerows and walls are sparsely located, but add a level of complexity to the project.

The hexagonal base game map contained in Panzer. This will be a challenge to implement.

Each hex on the map will need to be represented in the system. A terrain key identifies all of the existing types of terrain on the map. Each hex has a single terrain such as Woods, Scrub, Bridge, Ford, Clear, Stream, Road etc.

Terrain key

Each terrain type has different properties, listed in the Terrain Effects table below. Each type of terrain is listed in the left column.

Terrain effects table
If we take a look at the "Clear" terrain type, we can determine that is has a height of "0" and a cover of "None".

Alternatively, the "Woods" terrain type has a height of 3. The height of the terrain type might block our line of sight to enemy units. We'll cover line of sight later on.

"Woods" also has a cover of "Medium", which allows us to hide from the enemy at certain distances.

Additionally, if we look across to the "T,H" column, we see that "Woods" terrain type has a movement cost of "3" for any track or half-track vehicles. If our Tiger I is moving through the "Woods" terrain type, it will use 3 of the 4 movement points to do so.

All in all, the terrain effects table is a very straight forward table to represent in my project.

The biggest overall challenge I faced is one of "Line of Sight". Line of sight in GMT Panzer is fairly straight forward in terms of game play. The technical challenge of applying this to a computer game was, at least in my opinion, one of the tougher pieces to consider.

In Panzer, we must be able to determine what a unit can see on the map board. After all, you can't hit what you can't see (generally speaking). So, before a unit fires a shell, bullet or volley, it must be able to see, or spot its intended target. Spotting a target requires "Line of Sight", in which we take a straight edge or piece of string and align it on the map from the center of the shooting unit's hex to the center of the target unit's hex. Centering the straight edge on each hex is made easy by the white dots in each.

Line of sight is measured from the center of the shooting unit's hex to the center of the target unit's hex. 

Once we have a line drawn from hex to hex, we verify that there are no obstructions between the units. We do not include the hexes that either unit occupies. From the image above, we can see that the Soviet SU-100 M44 (hex 1308) has line of sight to the German Tiger I (hex 1905). Our line crosses a number of hexes, including 1408, 1507, 1607, 1706 and 1806. We note that none of the hexes in which our line crosses has an obstruction. Therefore we have determined that the Soviet unit has line of sight to the German Tiger. We can also say that the German Tiger has line of sight to the Soviet SU-100.

This is a very simple example of line of sight in Panzer. Things get a little more complicated when the line crosses very small portions of hexes. Let's look at another example...

Our line crosses parts of other hexes. Each hex crossed  must be considered for obstructions.

The example displayed above demonstrates good line of sight from unit to unit, however the algorithm will need to be able to consider whether the line touches any portion of a hex in order to return line of sight determination. This line of sight crosses hexes 1307, 1406, 1507, 1607, 1707, 1807, 1906, and 2007.

Special Cases

Line of sight gets even more complicated. When our line is horizontal or a specific diagonal, it will be drawn across the entire side of a hex. This also means that the neighbouring hex that shares the side will also be included in the line of sight determination.

Consider the following example...

Horizontal line of sight must include hexes that share borders.

Both units have line of sight in the screen above. We need to include hexes that share a border with the line of sight. Let's start our line of sight determination with the Soviet T-34. We don't include the hex that the T-34 occupies, but we do include hexes 714 and 715 because the line crosses the entire length of each hex's sides. Moving on, we see that the line crosses through 0815. As we continue, we see that 0914 and 0915 must be included as well. This continues until we reach the German Panther.

If you take a close look at the map, the same situation arises when we have to determine line of sight on certain diagonals. In the image below, we can see that the line crosses the entire border of a number of hexes. The hexes include 0712, 0613, 0713, 0614 and 0714.

Some special case diagonal line of sight calculations are required.

I have identified all of these special cases and taken them into consideration. Along the way, I stumbled onto the fact that hex based maps have an offset column structure in terms of numbering. Hexes are "pushed down" every other column. This isn't exactly a perfect row and column numbering system here. I'll need to determine whether a unit is in an odd or even hex to determine the neighbouring hex numbers for these special cases.

I think that's enough for now. I'll explain how I managed to accomplish the map generation in a future post. Meanwhile, here's a short Panzer SOLO video of line of sight in action...

No comments: