Home Store Products Research Design Strategy Support News

RSS Feed

 News November, 2020

Designer’s Blog: November, 2020

October

24 November, 2020

So I thought today I would pick up pretty much where I left off last time: talking about the creation of the Stavka map. Last time we talked about elevation, but this time I thought I’d talk about hydrology: oceans, seas, lakes, and rivers.

(Click on the image to open the site in its own window.)

Whereas the story of how the elevation layer was made was fairly complex, the hydrology layer was not. It was mostly just tracing over my primary source map, selected sheets from the 1:1,000,000 International Map of the World.

(Click on the image to open the site in its own window.)

as you can see below, in this close-up of the mouth of the Volga:

Now the main features of the hydrology of this part of Europe will be well-known to the readers of this blog: the Baltic, Black Sea, Caspian Sea, and its major rivers, such as the Volga, Dnieper, and Danube. But there is a feature that I think deserves some attention but which is much less noticed and remarked upon: the stippling of lakes caused by the last great ice sheet of about 33,000 years ago, the line of which is about here:

North of that line, what you have, apart from the Scandinavian Mountains, is generally flat, with poor drainage and often with poor soil. In its natural state, that which isn’t forest is typically lake, pond, or marsh. Apart from the large trading cities on the Baltic coast, population densities tend to be low, due to the difficulties in farming much of the land, generally due to the effort required for drainage. (Lithuania, for example, is one of the most heavily drained countries in the world, with 47% of its total land and 87% of its arable land artificially drained.)

In game terms, what the glacial line means is that the terrain north of it, unless heavily drained, tended to be quite difficult for military operations, something we will come back to later in this series when we talk about how Stavka’s route system was created and how it models terrain.

And for now, of course, we can put the elevation and hydrology together:

But next up, my current thinking is to talk about land use. But we’ll see. In any event, for now, ’til later!

23 November, 2020

So, I thought that today I would talk about how the map for Stavka was created, because it is (I think) an interesting story. Let’s start with the elevation layers:

So: How did I make this? Did I hand-draw it all? No. No, no, no, no. I had done that for my previous games, but this looked like a whole ’nother level of effort, and I sought an easier way.

The starting point of the easier way was here:

(Click on the image to open the site in its own window.)

From this site you can download global digital elevation data. The data comes in blocks. I downloaded two: one bounded by 40°N, 90°N, 20°W, and 20°E, and one bounded by 40°N, 90°N, 20°E, and 60°E. Each block includes a set of header files explaining what the hell it is, and a big file containing the data, and, oh, also a thumbnail image that gives you some visual idea of coverage:

(Click on either image to download the files for that data block.)

Now, using this data for my purposes was going to be some work. (Bear in mind that the above image is not the data. The actual data is a binary file representing a grid, where each elevation point in the grid is represented by a two-byte signed integer.) Using this stuff would clearly require some programming. Happily for me, programming is something I have a lot of experience doing.

And so, I wrote a program.

The first order of business was to get the data into memory. This was a pretty easy task:

Now, the above isn’t a super general-purpose piece of code. I didn’t bother writing code to read in the header files and use it to understand the data, I just hard-wired the header file info into my program. The above code builds the file name, opens the file, checks to make sure it is the right size, reads it in, then swaps the bytes (Big-endian vs. Little-endian.)

Next, we gotta process the data to get it closer to something we can actually use to build the map elevation image. And that’s this guy’s job:

Let’s walk through it. The first thing is that we don’t need all the data in the block. Most of it is actually outside the map bounds, so we set up limits to ignore most of it. Next, we get to the main business: we’re going to loop through the data, an outer loop for each data row, then an inner loop for each data point in the row.

The most important job of this function is transformation. The Stavka map is a conic projection, and the elevation data is a latitude/longitude grid, so we need to translate between the two models: to figure out where on the Stavka map each elevation data point lies. And so, for every data point, we call this:

One of the great mis-conceptions non-programmers tend to have about programming is that it is very mathematical. Well, some of it is. Most of it, however, really isn’t. Software engineering is mostly analysis: taking a large, poorly defined problem and iterating on it, breaking it down into a series of ever-smaller, ever-better-defined problems, until finally you have problems so small and so well-defined you can explain to a computer how to do it. And back in the day doing that sort of analysis was very much my thing.

Even if not all programming is mathematical, however, some of it definitely is. Like the above function, for example. If analysis was my thing, math never was, and I really don’t enjoy the sort of coding in the above and find it a grind. (Fun fact: I flunked Calculus and with that my math education ended.)

Anyway, what the above function does is determine where on the Stavka map a particular elevation data point is going to fall.

Which brings us back to the double-loop function, which now knows where on the Stavka map the elevation data will go.

So, what does it do with it? Well, it is going to build a graphic image. It uses the three color channels: the green channel will be used for elevation data (after converting it from 16-bit data to an 8-bit form matching the elevation bands we want on your map), the blue channel for ocean, and the red channel for the latitude and longitude grid. A visual version of what we are producing (after processing both data blocks, and after more cropping, which comes later) is this:

(Click on the image to open the site in its own window.)

The above image, however, isn’t actually used in map production. Its job is to let me verify the accuracy of my code by giving me something I can overlay on top of this, which was the master source map for the game:

(Click on the image to open the site in its own window.)

Once validated, the real work was done by breaking the elevation data out into separate images, one for each elevation band in the game. The function that controlled that process that was this:

The function has a list of output files. For each file, it calls a filter function to remove unwanted data, and a write function to put it into a file. The filter function is here:

And the write function is here (one note: the output file format is a thing called PPM, which is a dead-simple graphics file format with no compression. Ideal for lazy programmers like me. I don’t leave it that way, though, because the files are huge and not a lot of programs can read them. I use Photoshop to convert it into GIF files.)

Anyway, you can see what the output files look like below:

Below Sea Level 100 Meter
200 Meter 300 Meter
500 Meter 700 Meter
1000 Meter 1500 Meter
2000 Meter 2500 Meter
3000 Meter

Each of the above images is the source for a map elevation layer. There is, however, still one thing to do. The source image pixels are large enough to be visible if directly used. Which is bad. So, what has to be done is to convert them into more curved shapes in order to get a more natural appearance. The method is through Adobe Illustrator, which as a Trace Image function and a Simplify Path function. After a little tweaking with both, the raw image data gets translated into something that looks more map-like, as you can see in the close-up below. (This is from the below-sea level data, which was the pixellated of the elevation layers and which took the most work to get into a usable appearance.)

Original Smoothed

And thus, one by one, each elevation data file image was converted into a Stavka map elevation layer, as you can see below:

Below Sea Level
100 Meter
200 Meter
300 Meter
500 Meter
700 Meter
1000 Meter
1500 Meter
2000 Meter
2500 Meter
3000 Meter

And then the different layers combine to form the elevation layers for the Stavka map, returning us to where we started today:

And here is where I think I will leave it off for today. It feels like a long enough blog entry; I hope it was interesting. Anyway, til later!

16 November, 2020

So, how about a card design update? I’ve been working on new suit icons since (it seems like) forever, on and off (more off than on – much more off than on, actually), but I finally have something to show you. So here you go:

Before discussing the changes to the icons in the current design, let me refresh your memory with the icons from the old design, to make it easy to see the changes:

The old design had an ink-and-watercolor quality to it that the new design does not have. The new design has simplified strokes that are stronger, and lack the hand-drawn quality of the old design. The colors are bolder as well. You might also notice that the typeface used for the numbers has changed, in thematically the same direction: bolder, cleaner, less quirky. The new design overall is intended to be less artsy and more (ahem) iconic.

Regarding the subjects of the different suits, three are the same as before (the cruiser Aurora, the Yak-3, and the tractor from the Stalingrad Tractor Factory) while one is new: the Kremlin has replaced St. Basil’s. The Aurora and the Yak-3 each have a new view angle: the Aurora barely so (the new angle puts the eye at deck level rather than the waterline, but is otherwise quite similar) and the Yak-3 very much so. The old Yak-3 design left me with an icon that was very wide compared with its height, which had proved a recurring nuisance in layout. The new one corrects that issue and brings its proportions more in line with the other icons. The tractor has the same view angle as before.

I hadn’t at first meant to replace St. Basil’s, but I found that when I tried to draw a new version of it, something in me just didn’t want to do it. I would sit down, draw a few strokes, and then feel the powerful urge to do something else instead. Because of that, literal weeks went by and all I had was a partial outline. I finally decided that I needed to change the subject. At the rate I was going, it was going to take me longer to draw St. Basil’s than it took to actually build St. Basil’s.

So, I decided to try the Kremlin instead. The problem with the Kremlin is that it’s really big. I thought of maybe a map-style image, but rejected that as it was too different than the other subjects. So, a section of the Kremlin seemed more like the way to go. I originally tried a strong perspective angle that emphasized the wall, but thought it ended up looking visually too much like the Aurora, and not very Kremlin-y. Really, I needed one of the towers, but a problem with the towers is the aspect ratio is really bad for a suit icon (much too height, not nearly enough width), so I decided to include a section of wall. I ended up going with the Spasskaya tower, the most recognizable of the Kremlin’s towers, but I actually cheated a little: the height of the wall in the suit icon is actually too high compared to the actual Kremlin. I did this because I just needed more visual mass, and the heightened wall made the image more imposing, which I thought was desirable.

Anyway.

So what else has been going on? Well, mostly playtesting and rules refinement, which has been the case the last couple of months.

A particular focus of the last couple weeks has been trying to get the Soviet army to work right in 1941. This has always been an issue in the design. As I’ve mentioned before, the basic modeling of the Soviet army in the game is in its mid-to-late war organization and capabilities, but it was such a different beast in 1941. In some versions of the game, the Soviet army has been too strong, in others too weak, but it has never really quite had the right feel. The current game has tried to represent it (in game terms) as unit-rich but card-poor. It has quite a few units, but not really enough cards (much less good cards) for it to operate those units effectively.

The main way this has been achieved is to basically create a separate system for the creation of Soviet units (called Mobilization) that doesn’t use the card economy production system to bring units on the game. In previous versions, the production system allowed the Soviet player to balance the number of units and cards, but I thought maybe I would try forcing an imbalance. What I want is the feeling of an army that is big, able to take enormous losses and keep fighting, but just not very good. So far, I think the unit-rich and card-poor model is promising, but it still almost untried and will need to be put through its paces for a while before it can really be determined how effective it is at modeling the Soviet army in 1941.

I think I’m going to wrap this one up here. (Short, I know, but they can’t all be epics.) Til next time!