Gamasutra: Carl-Henrik Skarstedt’s Blog – Space Moguls map screen retrospectiveSeptember 25, 2020
The following blog post, unless otherwise noted, was written by a member of Gamasutras community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.
(This article was also posted at https://spacemoguls.com/space-moguls-map-screen-retrospective/)
This is a technical article describing the development of the map screen of Space Moguls for Commodore 64 and published by Protovision. The article is not reasoning why I develop Commodore 64 games, but a technical and design deep dive into the map screen of the title. There are no code snippets in this article.
Space Moguls is a 2018 four player strategy game inspired by M.U.L.E. that was released 35 years earlier in 1983 by Ozark Softscape and published by then just-founded Electronic Arts. Both games are based on taking turns claiming land, generating items and trading between players and the store with the goal of having the most wealth at the end.
To learn more about the game feel free to look over the Player’s Guide here: space-moguls-players-guide
One aspect where Space Moguls differs from M.U.L.E. is the map screen which instead of being two color black on white uses the full 16 color palette the computer is capable of, This was the first system created for the game and contains several features that may not be obvious while playing the game.
The map is procedurally generated at the start of the game, and much of the map is covered in fog so that the final map is not known in the beginning. Since each land cell type produces different amounts of each item type this means players may change their strategy as the game reveals more of the map.
This is how the final map screen looks like during the Production stage, one of the seven stages of each turn:
The end result of the Map Screen during the Production Phase 4 rounds into a game.
Going back to the planning, here is the full on-paper map design of the game. For a short while the town covered three land cells, but as seen above the town sits in land cell #42. This picture was printed on paper and all the subsequent design was based on notes written over it. This is not its final form, but a readable capture from mid-development!
Design notes, this page is the entire documented map design of Space Moguls
One early decision was to use a hex grid for the map. This required some planning for hardware built for 40 by 25 characters of 8 by 8 pixels. In multi-color mode the pixels are also double width, meaning each pair of pixels share the same color.
The first design question was what is the best orientation for the hex grid?
The noticeable difference between A and B in the image above is that the hex cells are larger in A allowing more art detail per cell, but the slanted edges look worse due to the double width pixels. This stage of just drawing different grid layouts and seeing how each compared to the rest took quite a bit of time and these examples are just the most workable ones I came up with.
This choice ended up with B as the winner because I could fit exactly 10 hex cells horizontally on even lines and 9 on odd lines, and 8 rows perfectly filling 40 by 25 character cells! Of course this didn’t leave any room for a game HUD but that’s a different problem that future me will have to deal with.
Commodore 64 multicolor bitmap mode uses 3 out of 16 colors plus a shared background color for each screen character (8×8 pixels). Below is an example of one screen character with the background color black, and custom colors dark gray, mid gray and light gray.
An example of one bitmap character (8×8 pixels with double width to specify multicolor)
The top and bottom of the hex cells the screen characters are shared with neighboring cells. This means those screen characters need to share the same 3 colors + background, which is too restrictive in the source art.
Being able to use all 3 colors for each 8×8 character in the hex cell art helps add color and distinctiveness to each hex cell type so the best solution is to accept drawing cells in overlapping characters with color remapping.
The simplest useful remapping is just counting how many pixels of each color is used in each 8×8 cell (out of 32 double pixels) and pick the 3 most used colors. Pixels with colors that are discarded are replaced by looking up the closest match in a table.
Mixing characters and remapping colors is not a fast rendering approach on a 6502 series CPU running at 1 MHz, but it isn’t unreasonable. Anytime you draw in bitmap mode you’re not updating every frame (unless doing extreme speed-coding!)
But why stop at hex cells with straight edges, since rendering hex cells is so complex anyway? Drawing outside the lines allows for a sense of ground height, like the trees in the forest cell, cactuses in the desert cell or mountain peaks in the mountain cell.
The various types of hex cells in Alia Terra of Space Moguls, from left to right: Plains, Forest, Desert, Mountains, Steppe, Marsh and Lake.
This is what the source art of the desert land type looks like
In the desert cell example above, to the left is the art made up of 4×5 characters (8×8 pixels). The middle white shape is the background mask, these are the parts of the art that are drawn on top of the land cells above. To the right is the overlay mask which represents pixels drawn on top of other cells background and river cells.
The rendering is done one 8×8 screen character at a time so if just part of the land cell needs to redraw only the characters that actually change needs to redraw.
Another early design decision was that a river crosses the map between the top and the bottom. Land cells with a river has a bonus for producing food, but a negative effect for most other kinds of items. The river can be seen both in the map screenshot and the paper design above and rendering the river layer fits easily into rendering the land cell layers. It is nearly essential to capture a good river/plains cell early in the game to have a good supply of food throughout the game.
Each river cell has a background and a draw mask.
There are six sides to each cell which results in 13 combinations of land cell inlet and outlet. The direction of the river doesn’t matter.
For the example below I’m showing a desert cell neighboring a lake cell and with a river running through it. It would be unlikely to appear in the game in this configuration but it is easier to see the river and forest/lake cells being drawn.
A step by step drawing of all the land cell layers except gameplay
The steps represented by the image above are:
- Draw background bottom parts of the cells above left and above right
- Draw the cell itself with the background mask
- Draw the top parts of the cells below left and right with their background mask
- Draw the river if one intersects the Land Cell
- Draw the cell itself again with its overdraw mask
- Draw the top parts of the cells below left and right with their overdraw mask
On top of the map the Installed Droid and production tabs can be drawn.
The final color remapping back to 3 colors + background color for each 8×8 pixel character is not shown here.
As soon as a player claims a Land Cell a house icon using that player’s color is drawn into the cell to mark it as occupied. This happens during the Land Grant or the Land Auction stages, and in rare cases a Global Event can award one player an extra Land Cell.
The icons above represent:
- Unassigned owned land (House)
- Ore mining droid
- Food producing droid (Land)
- Food producing droid (Lake)
- Materials producing droid
- Rare Materials producing droid
- Energy producing droid (Land)
- Energy producing droid (Lake)
There may be strategy games that play well without any text / icons over the game map but not this game. It is vital that after looking away from the screen for a second you can immediately see what is going on when the eyes return to the action.
But apart from the zigzag edge of the map there is no part of the screen space left and drawing text using double wide pixels makes it hard to read.
Conveniently on the Commodore 64 there are top and bottom borders that can be tricked into displaying sprites. Commodore 64 sprites are 24 by 21 pixels so each sprite can display multiple lines of text and placing all eight of them horizontally allows for 192 pixels wide lines which is not bad at all.
And even if you use 8 sprites in a single line you can reuse them as the screen draws which means a fairly large amount of UI is possible by just using sprites. Of course the sprites used for text also need to coexist with the gameplay usage of sprites so some careful planning is needed when placing the information on the screen.
One problem that occurred fairly late in production was learning that NTSC borders are more narrow on normal TVs, guaranteeing only a few pixels on top and as few as 9 pixels below the screen. The solution was to allow larger text for those that play on a better TV and smaller for those on a more limited TV system.
There is only one font so the text scaling was implemented by using a line lookup table and carefully placing horizontal elements of the letters along the most used lines. The font size needs to be set before the game start due to the lack of in-game menus.
Space Moguls main menu, selecting the HUD text size. Text size A is the largest option.
Text size B
Text size C
Text size D
Without an actual map layout to render there isn’t much point to the renderer. Maps are generated randomly to make each play session a little bit unique. The code for generating maps use a lot of weights and rules to make the land feel natural and consistent.
The first step in generation is placing the river starting at cells neighboring the town cell in the center, then walking sideways and upwards/downwards until the top or bottom is met.
After the river is laid out the generator starts with the center land cell occupied by the town and generates a neighbor tile to the town or any previously generated tile until the board is full.
Each cell starts with an array of chance indexed by each type of land and then a land type is picked randomly weighted by the array. The array is filled out based on the occurrence of that land type for the planet, and modified by the neighboring cells and the occurrence of a river in the same cell.
For example, a lake cell is more likely to occur next to other lake cells and on a river. A desert cell is unlikely to occur next to a lake cell and so forth.
Once the map is complete all the cells are covered in fog except the town cell, and a planet specific number of fog cells are cleared up immediately. The rule for clearing fog is that only cell neighboring a cell without fog can be cleared so there can not be isolated holes in the fog.
With a map and the ability to draw it computer controlled players need a way to navigate efficiently. There isn’t anything in Space Moguls that block computer players from always walking in a straight path but certain land types make you move slower and trying to walk through fog is particularly slow.
While pathfinding is almost a non-issue on modern computers trying the same approaches with a much slower CPU and much less RAM is not always productive.
To be fair, A* was originally implemented and works just fine, there is not much else going on while CPU players navigate the map, but it is not as elegant as I wanted it to be.
The definition for “elegant” in this context is entirely personal but with some goals such as:
- Fast but not at the expense of the worst case for an 8-bit CPU
- As static as possible – avoid dynamic lists, no stack based function recursion
- Using a limited and constant amount of RAM
- Ideally re-using memory that is not currently in use
There is no need for decompressing data while pathfinding so a buffer reserved for that purpose can be reused here. In this buffer each land cell is represented by a byte. This byte represents how much “effort” is used to reach that cell from the cell currently occupied by the player.
Initially the buffer is filled with the value 127 unless it is covered by fog which sets it to 255. Fog is significantly slower to walk through so it should never be crossed by a computer player. Finally the value for the cell the player currently occupies is set to zero.
In addition to the map array there is also two arrays of the previous iteration’s added cells so that while traversing one array the other array is populated and the next iteration the arrays are reversed. The player’s current cell is added to the first list.
For each iteration the previously populated list for each cell look at each of its neighbor and if it isn’t traversed yet, add it to the next added list and add the cost of traversing it from the current cell’s cost plus the cost of traversing the new cell.
When the entire map is filled out look at the destination cell, add it to the end of the path and traverse each step to the lowest effort neighbor until the starting point is reached.
This approach is not the fastest but the goal here is to be as consistent as possible while using the least amount of memory. The size of this code is also fairly small.
In any off-earth game I’m personally curious how something approximating earth would look like but also what other planets might be like. Space Moguls contains four different destination planets: Alia Terra (earth-like), Mars, Winternus (earth-like but winter) and finally 46C which is more post modern art inspired than realistic.
Space Moguls is a large game with plenty of systems and the map screen is just one of these systems, but it is something I’ve wanted to share since my early successful experiments. The map screen is also central to the game experience since most turn stages takes place on the map.
The goal with this article is mostly to share a neat implementation of a map screen in a Commodore 64 screen, and to highlight what is possible to do even with limited hardware resources.
On a final note, since I also enjoy making custom tools there is a nearly finished mod tool, but I have no insight into the overlap of modders and retro strategy game enthusiasts. Let me know if there is any interest in something like that.