Open Game Source: Civilization: Call To Power

by Dennis Payne

Name: Civilization: Call To Power
Version: 1.1
Publisher: Loki Software
License: Commercial (No source available)
Operating System: Linux (Ported from Windows)

LokiHack '99

Atlanta Linux Showcase spotlighted an event unparalleled in the history of computer games, LokiHack '99. For 48 hours a group of programmers were given a chance to modify Civilization: Call To Power in whatever manner they pleased. Although technically dubbed a contest, the Linux hackers were more interested in the challenge and the fun than any prize. At the start of the event, everyone introduced themselves and mentioned what they were thinking about doing as extensions.

What shaped the event was the attitude of the developers. Rather than hiding the knowledge painfully obtained from the half a million lines of code, if someone had learned about units, he would inform anyone else who asked about how to change something. The open source philosophy goes far beyond the software. It infects people all the way to the core.

Add a Civilization

As a quick change I modified the data files to include the Aztec civilization. Or at least that was the idea. I tried adding them before the contest by just editing the ctp_data/english/gamedata/civ_str.txt file in the CivCTP directory. That file only contains the text strings however. The file ctp_data/default/gamedata/civilisation.txt must also be modified. What should go into the files is fairly self explanatory. They are DOS text files although I've been told the Linux version of Civilization can handle unix text files as well.

Instead of quickly adding the civilization, I found myself faced with inadequate error messages. The error message code had been cut and pasted but sometimes the text string wasn't changed, so it ended up printing out incorrect error messages. If you want to add a civilization you may want to download my LokiHack version of Civilization since it correctly reports most errors. However, if CITY_IS_CAPITAL is misspelled it still simply complains about there being an unexpected number of civilizations. Eventually I finished a patch to add the civilization.

Flat World

Since compile time took several minutes I had perused a fair amount of the source during builds and was ready to rip into the code by the end of adding the Aztecs. I noticed, when I first tried Civilization: Call To Power, that a flat world was missing from the world types. Since they had implemented a doughnut world it seemed like a flat world would be the next logical choice. In looking over the source I discovered the SetXwrap and SetYwrap functions. Since it seemed like a nice simple hack, flat world joined the world types. It didn't work. Obviously too much relied on the fact that the world wrapped around in the x direction.

I was going to proceed to try other hacks but it kept gnawing at me. Civilization wasn't going to win that easily. A great deal of hacking ensued. Eventually everything seemed to be working. Even though I didn't feel quite right about it, I moved on.

Unit Abilities

While mulling over other ideas that were presented at the beginning, obsolete units preoccupied my thoughts. There had been some interesting proposals concerning them at the beginning of the hack. I decided to look into simply adding an upgrade unit option. Progress was going well until I came across a note describing how the IDs of units, strings, and other objects are not always the same on loading. Rather than assume they were, I decided to abandon the idea and try something else.

In examining the source, a number of unusual ability were observed. The unit stats and abilities are defined in ctp_data/default/gamedata/units.txt (unit_historic.txt is also included in the directory). Near the bottom of each unit is its special abilities. The source listed many others never used in the data files. For example, there are the wooden ship and attack wood ship bonus abilities. Neither are used in the game, although unlike some others these are actually implemented. The game data file even includes the cattle unit which was dropped from the game in January '99 according to comments. Of course, there is also the commented out functionality like land mines and rift gates. Implementing one of these was a possible option, but not one that really appealed to me.

"Multiply" and "Can't heal quickly" overwrote the old wooden ship and attack wooden ship bonus abilities. The idea for them come from several possible units: undead, slimes, and the ever popular Borg from Star Trek. Having them grow from defeating other units better represents their ability, but it seemed to duplicate the slavers ability too much. The can't heal option gives multiplying units a little disadvantage and is somewhat common for undead. It might also be useful for other units such as some sort of cheap defence unit. In testing the new abilities I discovered the severely broken flat world.

Flat World Revisited

The world in Civilization is a rectangular collection of squares. The view is an isometric world. Some simple math converts between the two mappings. Instead of creating two different classes or at least storing the format in the class, Activision made the MapPoint class represent either of the map coordinates. Needless to say checking that x doesn't wrap becomes more difficult this way.

At first it seemed logical to me to use the array mapping in the code as the real map edges. This would make the world parallelogram shaped. For a variety of reasons making the isometric edge the real world edge was easier and the original approach was dropped. Everything was cleaned up to a consistent state except for three things. First, the path finding algorithm wasn't updated, so movement near the world edge or across the world sometimes picks an invalid path. This was never part of my planned changes.

Unfortunately I couldn't resolve two other issues before the contest ended. MapPoint::GetNeighbor and Vision::CheckWrap still didn't handle the edge wrap properly; these are crucial for movement and fog of war. Just before the contest ended, I learned that a critical function I'd used didn't do what I'd expected it to do, but alas there wasn't time to fix the problem.

Final Notes

A lot of strings are used to reference information. Strings are easier to use than numbers or position in a file because you can easily see what they relate to. However, it consumes a great deal of memory. I keep thinking that a pre-processor used to convert the strings to numbers could have reduced the operating size by a significant amount. However, the memory usage of the strings is an implementation inefficiency.

The class structure, on the other hand, suffers from poor object oriented design. When I wanted to know about the gold of the civilization, I checked for the class that holds a civilization's data. Unfortunately the Civilization class holds very little. Instead you need to look at the Player class. When looking for unit data, three classes need to be checked for various things: Army, Unit and UnitData.

For those who think I begin rather harsh on the code, you're right. Open source works without time or budget constraints, or at least not in the way commercial products have them. They have the time to do it "right." Better designs, even if they are course corrections in the middle of things, might still have improved development speed and reliability.

I personally enjoyed the experience immensely and would like to thank both Loki and Activision for the chance to hack Civilization: Call To Power.

Related Links

Loki Hack 1999 Patches
The Hacking Contest Nobody Tried to Win
Coletti's 1999 Loki Hack Page

Back to OGS

Copyright (c) 1999 Dennis Payne / Identical Software