Understanding Old Computer Games: Powermonger

Ramin Sadre

Published on October 10, 2025.

No responsibility is taken for the correctness or completeness of the information presented in this article.

1 Introduction

Powermonger is real-time strategy game made by Bullfrog Productions and published by Electronic Arts in 1990 for the Amiga. At first glance, it is somewhat reminiscent of Bullfrog’s first game, Populous, which had been released a year earlier. However, the two games differ significantly in terms of gameplay and implementation. Powermonger offers a true 3D view instead of the isometric 3D view of Populous, and the events in the world of Powermonger are simulated with great attention to detail. Each inhabitant has an age and gender and can pursue various occupations and manufacture tools. But in this article, we are more interested in the technical inner workings of Powermonger.

2 General thoughts on performance

The Amiga version was programmed entirely in assembly language. This is interesting insofar as Populous was written in C. I am not familiar with the Atari ST version, but I expect that it is based on the same assembly code, since both platforms use the Motorola 68000 CPU.

Remark: I recommend anyone interested to take a look at the Populous binary file with a decompiler such as Ghidra. Since C compilers in the 1980s were not yet capable of performing complex optimizations, the code is very easy to read.

Like many other games, Powermonger only uses a 16 color display with a resolution of 320 times 200, although the Amiga 500 and 2000 were capable of 64 colors at that resolution. Surprisingly, Powermonger does not make use of the Amiga’s Blitter coprocessor. As readers probably know, the Blitter is a hardware circuit in the Agnus chip capable of performing graphics operations in parallel with the CPU, which, if carefully planned, can significantly increase the performance of games and applications. Powermonger does not take advantage of this. All graphics operations, whether drawing lines, showing pictures, or moving windows, are performed by the CPU. This was probably due to the developers’ desire to keep the code as similar as possible between the Amiga and Atari versions. However, other multi-platform games from the same period did make use of platform-specific graphics routines with great success, such as Starglider 2 by Argonaut Software, which I analyzed in a different article. The lack of use of the hardware blitter could be the reason why Powermonger runs a bit slowly on first-generation Amigas.

There are also some other notable implementation decisions in terms of performance. I would like to present one of them here, as it is truly unusual for a game. In Powermonger, clicking on a button in the user interface turns it green, as visible in the above screenshot (look at the button with the two sword symbols left to the 3D map). In other computer games, this effect is usually achieved by replacing the image of the inactive button with a different, colored image of the active button. In Powermonger, however, a different, far more CPU-hungry method was chosen. The game contains an image with 1-bit color depth that specifies the contours of the buttons in the user interface. When you click on a button, a filling routine is executed that recolors the inside of the button by reading out the colors of the individual pixels within the button and replacing them with different colors according to a color table.

Contour bitmap for the buttons.

The algorithm for the filling routine is shown below:

colorizeButton(buttonID):
    x = buttonPositions[buttonID].x
    y = buttonPositions[buttonID].y
  
    if not contourBitmap[x,y]:
       while(true) {
           startX = x
           while not contourBitmap[startX,y]:
               startX--
           endX = x
           while not contourBitmap[endX,y]:
               endX++
           for t from startX to endX:
               oldColor = readPixel(t, y)
               newColor = colorReplacementTable[oldColor]
               writePixel(t, y)
           y++
           while contourBitmap[x,y]:
               x++
               if x>endX:
                   break               
       }
    }
}

3 To be continued…

I will write more about the game here.