Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

City records

The world has room for 128 cities, shared by all eight civilization slots. townbuf[128] starts at DGROUP offset 0x70ec. Each record is 28 bytes, so the array occupies 3,584 bytes. A status of −1 marks a free record.

struct city {
    long buildings;             /* bit (n-1) set: improvement n is built */
    unsigned char x, y;
    char status;
    signed char size;
    char visible_size;
    char production;
    char trade;
    signed char owner;
    int food_box;               /* accumulated food */
    int shield_box;             /* accumulated production */
    long workers;               /* worked tiles 0..20, specialist count 26..31 */
    int specialists;            /* eight two-bit specialist types */
    char name_id;               /* unsigned index into place_name */
    char routes[3];             /* destination city indices, -1 if empty */
    char garrison[2];           /* unit type plus veteran bit 0x40, -1 if empty */
};

o20_city() in CITY.C finds a free record when a Settler founds a city. city_create() sets up its position, owner, name, workers and reserves. vanish() in ECONOMY.C removes a city, clears its map flags and removes references to it from trade routes and supported units.

Record layout

OffsetFieldUse
0x00buildings32-bit mask; improvement n uses bit n−1
0x04–05x, yMap position
0x06statusState flags; −1 means unused
0x07sizePopulation size
0x08visible_sizeLast reported size for the map display
0x09productionUnit ID, or negative improvement ID
0x0atradeTrade used in route calculations
0x0bownerCivilization slot
0x0cfood_boxStored food, a 16-bit integer
0x0eshield_boxStored production, a 16-bit integer
0x10workersWorked tiles in bits 0–20; specialist count in bits 26–31
0x14specialistsEight two-bit specialist types
0x16name_idUnsigned index into place_name[256][13], accessed with a cast
0x17–19routesUp to three destination cities; −1 means empty
0x1a–1bgarrisonTwo stored unit types, with veteran bit 0x40; −1 means empty

Workers and specialists

radius_dx and radius_dy give the 21 tile offsets around a city. The centre is tile 20 and is worked free of charge. Other worked tiles use citizens. city_process() reserves neighbouring cities’ worked tiles and centres before assigning workers, so two cities cannot work the same tile.

The specialist count and specialist types are stored separately. set_specialist() and get_specialist() use 0 for an unused slot, 1 for a taxman, 2 for a scientist and 3 for an entertainer. Indices of eight or more read back as taxmen. Each specialist adds two points to taxes, science or luxuries, respectively, before building multipliers.

Stored garrisons

garrison_in() in UNITS.C can store two fortified units in the city record, keeping the first qualifying unit in the ordinary unit array. The stored bytes hold types and veteran flags. unpack_garrison() recreates those units with their fortified and veteran status.