├── images ├── pict_palette.png └── pixel-parsing-bridge.png ├── archive file spec.md ├── README.md ├── sprite data spec.md ├── simulation spec.md ├── text data spec.md └── sc2 file spec.md /images/pict_palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCity2k/SC2k-docs/HEAD/images/pict_palette.png -------------------------------------------------------------------------------- /images/pixel-parsing-bridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCity2k/SC2k-docs/HEAD/images/pixel-parsing-bridge.png -------------------------------------------------------------------------------- /archive file spec.md: -------------------------------------------------------------------------------- 1 | # Archive File Specification 2 | Specification on how asset files are stored inside of an archive. Include TIL, URK and some DAT files, as used in the DOS version. 3 | ## Archive Format 4 | There are several different archive files that all have the same format.\ 5 | ### Overall File Structure 6 | Archive files consist of two portions, a short header and a block of file contents.\ 7 | Header starts at address 0x00 and continues until the first byte of the first file.\ 8 | The archives are uncompressed. 9 | ### Header Structure 10 | The header consists of 16B entries that specify the 8.3 filename (including the point) and the little-endian 32-bit offset into the archive file where the stored file starts.\ 11 | Each 16B block contains:\ 12 | 0x00 .. 0x0B: The filename, in all-caps ASCII including the point, padded with NUL bytes, e.g. LARGE.DAT\\0\\0\\0.\ 13 | 0x0C .. 0x0F: 4B int, little-endian offset into the archive file where the stored file starts. 14 | ### Data Structure 15 | Files are stored in offset order, so the end of one file is one byte before the start of the next file, or the end of the archive.\ 16 | Files are also stored uncompressed, so extracting them is as easy as dumping from the beginning offset to the beginning offset of the next file. 17 | ## TIL / URK Files 18 | TIL and URK files effectively the same archive files that contain seven files: 19 | 20 | - SMALL.HED 21 | - LARGE.HED 22 | - OTHER.HED 23 | - Header files for the DOS sprite format 24 | - SMALL.DAT 25 | - LARGE.DAT 26 | - OTHER.DAT 27 | - Data files for the DOS sprite format 28 | - URKNAME.TXT 29 | - Information about the archive 30 | 31 | ## USER.DAT 32 | Contains all of the base assets for the game in various formats. 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SC2k-docs 2 | Unofficial documentation related to the implementation of Maxis' game, SimCity 2000.\ 3 | In general, these documents pertain to the Windows 95 Special Edition version of the game. 4 | ## License: 5 | [![licensebuttons by-sa](https://licensebuttons.net/l/by-sa/3.0/88x31.png)](https://creativecommons.org/licenses/by-sa/4.0)\ 6 | This work is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/). 7 | ## Contents: 8 | - `sc2 file spec.md`: specifications on the .sc2 file format. 9 | - `sprite data spec.md`: Specifications of the data files used to store the various building, terrain, road and other sprites in the game with a section for the additional specifications for MIF files. 10 | - `text data spec.md`: Specifications for the newspaper and other text data files for the game. The newspaper specification is considered a work in progress as it can parse all of the text, but very little around how stories are composed has been determined. 11 | - `simulation spec.md`: Specifications for how the actual simulation works. Examples: how the power or water system works, how traffic works. 12 | 13 | ## Status: 14 | The sc2 file specifications are largely complete. Sprite parsing is complete. The text data is useful enough to generate any complete newspaper stories, while the rest of the text format is simple and captured in the documents. 15 | 16 | The simulation spec is a start at cataloguing all of the information about the internals of the game. 17 | 18 | ## I'd like to help: 19 | Great! Open a Pull Request with a correction or additional information. If it's spelling or otherwise simple, it should be merged right away. 20 | 21 | For things more complex, please add supporting evidence, such as screenshots from the game, discussion of testing methodology, etc. Basically, enough that someone else can reproduce the results. Be wary of the manuals and other information floating around online, they're not always right on how the game actually works internally. 22 | 23 | Opening an issue is also a good place to get started, and allows discussion while figuring whatever out. -------------------------------------------------------------------------------- /sprite data spec.md: -------------------------------------------------------------------------------- 1 | # Sprite File Specification 2 | 3 | Specification on how the various sprite data files are formatted for the Windows 95 Special Edition version as well as the DOS version. Includes [MIF](#mif-files) files. 4 | 5 | ## Windows 95 Sprite Format 6 | 7 | This version stores sprite information in `LARGE.DAT`, `SMALLMED.DAT`, `SPECIAL.DAT`. 8 | 9 | ### Overall File Structure 10 | 11 | A header and chunks containing a sprite in them pointed to by the header. 12 | 13 | Header starts at address 0x00, and the sprite chunks fill the rest of the file. 14 | 15 | ### Header Structure 16 | 17 | The header contains two parts. A count of total number of sprites stored in the file, and then metadata related to each sprite. There's one metadata per sprite. 18 | 19 | _Note:_ some blocks with the same ID appear twice, the second is spurious and can be ignored. 20 | 21 | #### Sprite Count 22 | 23 | | Offset | Type | Length | Name | Notes | 24 | |--------|------|--------|------|-------| 25 | | 0x00 | Integer | 2B | Sprite Count | Contains the number of entries in the header. | 26 | 27 | #### Sprite Metadata 28 | 29 | | Offset | Type | Length | Name | Notes | 30 | |--------|------|--------|------|-------| 31 | | 0x00 | Integer | 2B | ID | ID that the chunk represents, this is the same scheme used in XBLD. | 32 | | 0x02 | Integer | 4B | Offset | The absolute offset from the start of the file where the start of a chunk is. | 33 | | 0x06 | Integer | 2B | height | The sprite's height, in pixels. Number of rows. | 34 | | 0x08 | Integer | 2B | width | The sprite's width, in pixels. Number of columns. | 35 | 36 | ### Sprite Data Structure 37 | 38 | Sprite data is made up of a sequence of chunks. Each block stars with metadata about the following pixel data. If count is `0`, then this is a blank row. 39 | 40 | | Offset | Type | Length | Name | Notes | 41 | |--------|------|--------|------|-------| 42 | | 0x00 | Integer | 1B | Count | Count, which means different things for different block types. | 43 | | 0x01 | Integer | 1B | Chunk Mode | Pixel data is packed into blocks differently, which is described below. | 44 | 45 | #### Pixel Data Chunk 46 | 47 | | Offset | Type | Length | Name | Notes | 48 | |--------|------|--------|------|-------| 49 | | 0x00 | Integer | 1B | Count | Varies by mode the pixel data is stored in. | 50 | | 0x01 | Integer | 1B | Mode | Observed to be 0, 3 and 4. See next section for more. | 51 | | 0x02 ... | varies | varies | Pixel Data | Structure varies by pixel mode. | 52 | 53 | #### Chunk Mode 54 | 55 | There are several different modes pixel data pixel data can be stored in a chunk. 56 | 57 | | Chunk Type | Notes | 58 | |------------|-------| 59 | | 0 | Empty block. This is ignored. | 60 | | 1 | Start of a new row. The count specifies the offset to the start of the next row. | 61 | | 2 | End of a sprite. | 62 | | 3 | Skip | Skip the number of pixels specified by the count value. | 63 | | 4 | Actual pixel data. | 64 | 65 | ##### Pixel Mode 0 66 | 67 | Ignored data. Skip this, it seems to be padding/filler. 68 | 69 | ##### Pixel Mode 3 70 | 71 | In this mode, pixels start at an offset from the left edge. 72 | 73 | | Offset | Type | Length | Name | Notes | 74 | |--------|------|--------|------|-------| 75 | | 0x00 | Integer | 1B | Edge Offset | Number of pixels from the edge to start the first pixel. | 76 | | 0x02 | Integer | 1B | Pixel Count | Count of pixels in this row. | 77 | 78 | #### Pixel Mode 4 79 | 80 | | Offset | Type | Length | Name | Notes | 81 | |--------|------|--------|------|-------| 82 | | 0x00 | Integer | 1B | Edge Offset | Number of pixels from the edge to start the first pixel. | 83 | | 0x02 ... | varies | 1B/pixel | Pixel Index | Index into the palette to look up [colour](#colours). | 84 | | Last | Byte | 1B | Null | `0x00` for padding, only if the number of pixels is odd. | 85 | 86 | ### Colours 87 | 88 | There are three palette files in the SC2k `Bitmap/` directory, that contain a 16x16 grid of pixel colours. The actual palette is stored in the bitmap, and is in `BGRX` form, where X is always fixed and can be safely ignored. It is 1024 bytes in size (8bpp). This appears to be standard for the time. 89 | 90 | The game colours the pixels it displays based on one of these palettes (`PAL_MSTR.BMP` seems to be the most common one, `PAL_STTC.BMP` has black for colour-cycling indices, so STTC probably means static) based on the pixel's number. It does this by taking the high order nibble of the bit, as an integer and uses that as an index for the row in the 16x16 array of colour values, and the low order nibble as the index to the column. 91 | 92 | Example: Pixel has value 0x42 = 0b01000010. Row: `0100` = 4. Column: `0010` = 2. so the index is (4, 2). 93 | 94 | ### Pixel Data Parsing Example 95 | 96 | For this example, we'll look at how the highlighted row is parsed in the following sprite from the suspension bridge. Note that white pixels are transparent in the final result. 97 | 98 | ![pixel data parsing example suspension bridge](images/pixel-parsing-bridge.png) 99 | 100 | With the raw data for the line being: 101 | 102 | ```raw 103 | 24 01 04 03 04 04 2A 29 28 28 01 03 01 04 26 00 03 03 00 00 01 04 26 00 02 03 00 00 08 04 2A 2A 00 00 28 28 00 00 104 | ``` 105 | 106 | Which is parsed as follows: 107 | 108 | - Row header `24 01`: 109 | - `24`: indicates 0x24 (36) bytes following. 110 | - `01`: indicates chunk mode, in this case, the start of a new row. 111 | - `04 03`: 112 | - 4 pixels in row mode 3, skip four (transparent) pixels. 113 | - `04 04 2A 29 28 28`: 114 | - `04 04`: 4 pixels in row mode 4. 115 | - `2A 29 28 28`: Palette indices to look up. 116 | - `01 03`: 117 | - 1 pixel in row mode 3, skip one (transparent) pixel. 118 | - `01 04 25 00`: 119 | - `01 04`: 1 pixel in row mode 4. 120 | - `25 00`: Palette index 0x25 with a null padding byte. Note that `00` is a valid palette index, but as there's only one pixel, this is a null byte. 121 | - `03 03` 122 | - 3 pixels in row mode 3, skip 3 pixels left. 123 | - `00 00` 124 | - Row mode 0, ignored. 125 | - `01 04 26 00` 126 | - 1 pixel in row mode 4. Palette index 0x26 with a null padding byte. 127 | - `02 03` 128 | - 2 pixels in row mode 3, skip 2 pixels left. 129 | - `00 00` 130 | - Row mode 0, ignored. 131 | - `08 04 2A 2A 00 00 28 28 00 00` 132 | - `08 04`: 8 pixels in mode 4. 133 | - `2A 2A 00 00 28 28 00 00`: Palette indices to look up. 134 | - The remainder of the row is assumed to be empty. 135 | 136 | ## MIF Files 137 | 138 | ### Overall MIF Structure 139 | 140 | Is an IFF file, like the .sc2 file format. Generated in SCURK and loaded into the game to change the way buildings looks.\ 141 | First 12 bytes are a header that consists of “MIFF”, length of file, “SC2K”. 142 | 143 | Two main sections:\ 144 | **INFO:** First 4B is count of length, rest (0x72 in length) appears to be information on the file, including where it was saved from and which version of SCURK it was made with, along with some other unknown information.\ 145 | **TILE:** First 4B is length of the contents, next two bytes is the number of sub pieces of data, either SHAP or NAME. 146 | 147 | #### NAME 148 | 149 | Comes before a SHAP object and changes the name displayed for that object. 150 | 151 | | Offset | Type | Length | Name | Notes | 152 | |--------|------|--------|------|-------| 153 | | 0x00 | Integer | 4B | Length | Length of data following. | 154 | | 0x04 | Unknown | 1B | Unknown | Unknown | 155 | | 0x05 | Integer | Building ID | Building type this name applies to. Same indices as the game uses for XBLD.| 156 | | 0x06 | Unknown | 1B | Unknown | Unknown | 157 | | 0x07 | Integer | 1B | Name Length | Number of ASCII characters following for the name. | 158 | | 0x08 ... | ASCII | 1B/character | Name Text | ASCII string with modified name. Maximum string length appears to be 0x16. | 159 | 160 | #### SHAP 161 | 162 | Metadata related to the sprite (or "shape"). 163 | 164 | | Offset | Type | Length | Name | Notes | 165 | |--------|------|--------|------|-------| 166 | | 0x00 | Integer | 4B | Length | Length of data following. | 167 | | 0x05 | Integer | Building ID | Building type this name applies to. Same indices as the game uses for XBLD.| 168 | | 0x06 | Integer | 1B | Width | Width in pixels of tile. | 169 | | 0x07 | Integer | 1B | Width | Width in pixels of tile. | 170 | | 0x08 | Integer | 4B | Pixel Data Length | Length of pixel data. | 171 | 172 | Observed tile widths: 8px, 16px, 24px, 32px, 48px, 64px, 96px and 128px 173 | 174 | _Note:_ Pixel data is in same format as stored in sprite data files, with one change. The end of a file in indicated by a row with the form \x02\x01\x02\x02. Other than that, parsing is the exact same, except that sometimes the pixel count in mode 4 is an odd number with no padding. This is likely due to a bug in SCURK and can be ignored. 175 | 176 | ## DOS Sprite Format 177 | 178 | ### Header Data 179 | 180 | Header data is stored in `LARGE.HED`, `SMALL.HED` and `OTHER.HED` 181 | 182 | These are the header files for the DOS version that describe the contents of the LARGE.DAT, SMALL.DAT and OTHER.DAT sprite files. They are always contained in an archive file with an associated DAT file, either the base archive or a TIL/URK file. 183 | 184 | ### Overall Header File Structure 185 | 186 | Each HED file contains 1500 entries with each entry being 6B + 2B of padding in between.\ 187 | Null entries (which do not correspond to a sprite) are all 0xFF, and the padding is always all 0xFF.\ 188 | 189 | | Offset | Type | Length | Name | Notes | 190 | |--------|------|--------|------|-------| 191 | | 0x00 | Integer | 4B | Offset | Little-endian offset into the DAT file where the sprite begins. | 192 | | 0x04 | Integer | 1B | Height | Sprite height. | 193 | | 0x05 | Integer | 1B | Width | Sprite width. | 194 | | 0x06 | Byte | 2B | Padding | Always 0xFFFF. | 195 | 196 | ### Sprite Data 197 | 198 | Sprite data is stored in `LARGE.DAT`, `SMALL.DAT` and `OTHER.DAT` 199 | 200 | Similarly named to the Windows 95 sprite files, these DOS sprite files have a completely different format. It is always contained in an archive file with an associated HED file, either in the base archive or a TIL/URK file. 201 | 202 | ### Overall Sprite File Structure 203 | 204 | DAT files contain sequences of variable length row data. Each sprite starts at an offset specified by the HED file.\ 205 | Each row starts with a marker value of 0x10, followed by a 1B int for the number of bytes in the row (this value includes the 1B for the length byte but not the row marker).\ 206 | Following the length byte is a byte that specifies the type of the chunk, which have different headers: 207 | 208 | - 0x04: This portion of the row starts at the next leftmost pixel. Followed by 1B for the number of pixels in this chunk. 209 | - 0x0C: This portion of the row starts at an offset. Followed by 3B: 210 | - 1B: The number of pixels for the offset 211 | - 1B: Unknown 212 | - 1B: The number of pixels in this chunk 213 | 214 | Pixel data follows, which is stored as palette indices, as with the other formats. 215 | 216 | Multiple chunks can be stored in the same row to allow for non-adjacent color regions. This is done by specifying a larger number of bytes in the row and putting multiple chunks in a row that don't have enough bytes to fill up the row. 217 | 218 | The end of a sprite is marked by 0x00 instead of the 0x10 that marks another row. Some TIL files use the pattern 0x10 0x01 0x00 to mark invalid sprites, as this signifies a sprite with one row with no pixel data in that row. 219 | -------------------------------------------------------------------------------- /simulation spec.md: -------------------------------------------------------------------------------- 1 | # Simulations Specifications 2 | 3 | ## About these specifications: 4 | 5 | At this point, these specifications are largely structured as notes rather an implementable specification due to the very incomplete nature of them. Written for the Windows 95 Special Edition version. 6 | 7 | ### Starting a New City 8 | 9 | The simulation is initialized with several values: 10 | 11 | - The start date to national population mapping is: 12 | - 1900 : 10,000. 13 | - 1950 : 25,000. 14 | - 2000 : 60,000. 15 | - 2050 : 150,000. 16 | - National value is: 3 * national population / 10. 17 | - National tax rate always starts at 1. 18 | - The national trend (whose effects are currently unknown) is the difficulty value - 1. 19 | - Difficulty: 20 | - Difficulty affects industrial demand somehow, by a likely small amount. 21 | 1. starting funds: $20,000. 22 | 2. starting funds: $10,000. 23 | 3. starting funds: $10,000. This is a bond at 3% interest. 24 | - Invention dates are calculated from the base year they can be [invented](sc2%20file%20spec.md#technology-discovery-years) with an additional 0 to 19 years randomly added. 25 | 26 | ### Terrain Generation 27 | 28 | #### Terrain Generation settings 29 | 30 | | Name | Range | Default | 31 | | --- | --- | --- | 32 | | Coast | 0 or 1 | 0 | 33 | | River | 0 or 1 | 0 | 34 | | Hills | 0 to 47 | 12 | 35 | | Water | 0 to 47 | 5 | 36 | | Trees | 0 to 47 | 15 | 37 | 38 | Selecting Coast also allow salt-water to be placed on the map. 39 | 40 | ### Water Production 41 | 42 | Water production is measured in the number of tiles it will serve, not the gallons displayed in game. 43 | 44 | There's a display bug where a single water pump in a city with no consumer makes the water shortage check fail, this does not mean that the city doesn't need water. This has been called the "Phantom Water Pump Trick", but it's not useful to **actually** get rid of the need for a water system. 45 | 46 | #### Water Pumps 47 | 48 | Water pump production is base on the sea level, how many fresh water tiles are bordering it (8 maximum) and how much precpitation is happening. 49 | 50 | The formula the game uses appears to be: `sea level * 5 + fresh water tiles * 10 + precipitation / 2` 51 | 52 | To convert to gallons of water, round this value down and multiply by 720. 53 | 54 | Example from a city with a sea-level of 4, 4 fresh water tiles around the pump and 14mm of rain: \ 55 | 4 * 5 + 4 + 10 + 14 / 2 = 67.0\ 56 | Game shows 48,240 gallons/month (=67 * 720). 57 | 58 | #### Desalinization 59 | 60 | The formula appears to be `salt water tiles * 20`. 61 | 62 | Note that as multi-tile buildings are calculated for each tile in a building, this means each tile needs to be calculated independently and summed up. 63 | 64 | This means that a desalinization plant surrounded on all sides by salt water will produce 640 files worth of water. 65 | 66 | How is this calculated? 67 | 68 | There are 9 tiles of the desalinization plant. 4 tiles border 3 saltwater tiles (the middle outside tiles), and 4 tiles border 5 saltwater tiles (the corner tiles), with one tile (the inside middle tile) bordering no saltwater tiles. This gives us `4 * 5 + 4 * 3 + 1 * 0 = 32` tiles. Which, multiplied by 20 = 640. 69 | 70 | Another example, with a power line going to the plant in the middle of one side. We have one less saltwater tile, so the calculation is now based on: 2 tiles of 5 (the two outside corners away from the power line), 3 tiles of 3 (the three edges without the power line), 2 tiles of 4 (the two corners near the power line), and finally one tile with two bordering salt water tiles (the tile the power line lands on): This gives `2 * 5 + 3 * 3 + 2 * 4 + 1 * 2 = 29`, and the game shows 580 tiles of water produced (29 * 20 is 580). 71 | 72 | Note that the internal game calculation goes a tile at a time, but I grouped tiles together for illustrative purposes. 73 | 74 | #### Water Towers 75 | 76 | Unknown exactly, but water towers appear to store a maximum of 400 tiles of water, in 100 tile increments. Water towers only store excess production from pumps, and "discharge" water only when production is lower than demand. 77 | 78 | #### Water Treatment Plants 79 | 80 | There's a bonus for having enough water treatment plants. 81 | 82 | One water treatment plant is needed for every 2,000 tiles in a city. 83 | 84 | ### Power Plants 85 | 86 | Methodology to determine: determined by building a city with low density zones and calculating how many tiles each power plant could power. Note that these numbers include the power plant, as it seems to require power to operate. 87 | 88 | | Plant | Nominal Output (MW) | Actual Output (tiles) | Efficiency | 89 | |---|---|---|---| 90 | | Coal | 200 | 704 | 44 | 91 | | Hydroelectric | 20 | 40 | 40 | 92 | | Oil | 220 | 768 | 48 | 93 | | Gas | 50 | 176 | 11 | 94 | | Nuclear | 500 | 1776 | 111 | 95 | | Microwave | 1600 | 5680 | 355 | 96 | | Fusion | 2500 | 8880 | 555 | 97 | 98 | Efficiency is simply the number of tiles a plant can power / the number of tiles the plant takes up. So for the Coal plant this is 704 / 16 = 44. This is not part of the simulation, just included for illustrative purposes. 99 | 100 | The energy saving ordinance appears to save 1/12 (~8.33%) power. 101 | 102 | #### Wind Power 103 | 104 | Methodology to determine: A city was made with all 32 terrain levels to determine how elevation affects output. 105 | 106 | The power output of a wind turbine is: `altitude // 2 + [0, 3]` where the 0-3 seems to be partially determined by how windy it is, normalized to a 0-32 range with some randomness added. 107 | 108 | | Altitude (steps) |Altitude (feet) | Minimum Tiles Powered | Maximum Tiles Powered | 109 | |---|---|---|---| 110 | | 0 | 50 | 0 | 3 | 111 | | 1 | 150 | 0 | 3 | 112 | | 2 | 250 | 1 | 4 | 113 | | 3 | 350 | 1 | 4 | 114 | | 4 | 450 | 2 | 5 | 115 | | 5 | 550 | 2 | 5 | 116 | | 6 | 650 | 3 | 6 | 117 | | 7 | 750 | 3 | 6 | 118 | | 8 | 850 | 4 | 7 | 119 | | 9 | 950 | 4 | 7 | 120 | | 10 | 1050 | 5 | 8 | 121 | | 11 | 1150 | 5 | 8 | 122 | | 12 | 1250 | 6 | 9 | 123 | | 13 | 1350 | 6 | 9 | 124 | | 14 | 1450 | 7 | 10 | 125 | | 15 | 1550 | 7 | 10 | 126 | | 16 | 1650 | 8 | 11 | 127 | | 17 | 1750 | 8 | 11 | 128 | | 18 | 1850 | 9 | 12 | 129 | | 19 | 1950 | 9 | 12 | 130 | | 20 | 2050 | 10 | 13 | 131 | | 21 | 2150 | 10 | 13 | 132 | | 22 | 2250 | 11 | 14 | 133 | | 23 | 2350 | 11 | 14 | 134 | | 24 | 2450 | 12 | 15 | 135 | | 25 | 2550 | 12 | 15 | 136 | | 26 | 2650 | 13 | 16 | 137 | | 27 | 2750 | 13 | 16 | 138 | | 28 | 2850 | 14 | 17 | 139 | | 29 | 2950 | 14 | 17 | 140 | | 30 | 3050 | 15 | 18 | 141 | | 31 | 3150 | 15 | 18 | 142 | 143 | #### Solar Power 144 | 145 | Nominal base output is ~136 (8 powered tiles/solar tile). Formula appears to be:\ 146 | `(Random % (100 - humid) // 10) + 5` where % is the mod operator. 147 | 148 | Inspection of a game showed that the minimum output was 0, the maximum output was 190 and the average was 136. 149 | 150 | ### Disasters 151 | 152 | Disasters won't start too early in the game, dependend on the game's difficulty (this might be incorrect): 153 | 154 | - On easy, no disaster for the first three months 155 | - On medium, no disasters for the first two months 156 | - On hard, no disaster for the first month. 157 | 158 | #### Disaster start conditions 159 | 160 | Most disasters have a random start component 161 | 162 | - Hurricane: 163 | - Weather has to be `0x0A` (Hurricane). 164 | - Has to have coastal terrain (from map generation). 165 | - Tornado: 166 | - Weather has to be `0x0B` (Tornado). 167 | - Riot: 168 | - Unemployment is 10 or more. 169 | - Heat is over 170. 170 | - Population is over 30,000 (without arcos). 171 | - Meltdown: 172 | - Nuclear power plant needs to exist. 173 | - Microwave: 174 | - Microsave power plant needs to exist. 175 | - Air Crash: 176 | - There have to be runway tiles. 177 | 178 | ### Game Models 179 | 180 | #### Crime Model 181 | 182 | Total amount of crime is stored in MISC as Crime Count. This is the sum of all values in XCRM.\ 183 | For purposes of display in the graph windows, 1 point in the window is 3750 points of crime, rounded up. 184 | 185 | The value stored in "Arrests" in MISC is the total number of arrests for each police station microsim. 186 | 187 | #### Land Value Model 188 | 189 | Total land value is stored in MISC as Land Value. This is the sum of all the values in XVAL. For display in the bond window, the displayed value is `city value * 1000`. For the graph display, 1 point in the window is 3200 points of value, rounded up to the nearest whole number. \ 190 | City value seems to be `land value / 2`. 191 | 192 | #### Traffic Model 193 | 194 | Total traffic is stored in MISC as Traffic Count. It does not appear to be the sum of all the values in XTRF. 195 | 196 | #### Weather 197 | 198 | The game tracks four different variables relating to weather: 199 | 200 | - Heat (temperature). In the newspaper, this degrees F, minus 100. So 186 in game is 86°F in the newspaper 201 | - Wind: range 0-255. This appears to nominally be in miles per hour. 202 | - Humidity: Appears to be rain, newspaper shows this as mm (not inches?) of rain. 203 | - The actual weather. [Weather types](sc2%20file%20spec.md#weather-type) 204 | 205 | Reportedly, crime and the weather are linked, and weather can effect disasters as well. 206 | 207 | #### Budget 208 | 209 | For bonds, the game appears to display decimal rates rounded down in the budget window, but calculates costs based on the actual rate. 210 | 211 | The bond sum rate may be used to determine credit rating, in conjunction with the city's land value. 212 | 213 | ##### Taxes 214 | 215 | Tax revenue is calculated as `tax rate * population / 75`. Land value does not appear to affect tax revenue, but reportedly it was _intended_ to affect tax revenue. 216 | 217 | Difficulty appears to change how sensitive sims are to taxes. 218 | 219 | ##### Ordinances 220 | 221 | Ordinances appear to have effects on zone demand, taxes raised and other effects. 222 | 223 | Notes: 224 | 225 | - This is still incomplete, and ?'s are used in place of unknown values. 226 | - ?? means unknown if effect exists. 227 | - Cost is given of that % of tax revenue it costs. 228 | - Demands changes were determined experimentally. 229 | - Costs were estimated based on looking at the cost versus tax revenue. 230 | - LE/EQ boosts are unknown, but seem to exist. 231 | - Parking fines may not actually impact traffic. 232 | 233 | | Name | Demand Effect | Tax Effect | Other Effect(s) | Cost | 234 | | --- | --- | --- | --- | --- | 235 | | 1% Sales Tax | -1% Commercial | +1% Commercial Revenue | - | 0% | 236 | | 1% Income Tax | -1% Residential | +1% Residential Revenue | - | 0% | 237 | | Legalized Gambline | - | +2% Commercial Revenue | (?) crime increase | 0% | 238 | | Parking Fines | - | +0.5% Residential Revenue | (??) traffic change | 0% | 239 | | Pro-Reading Campaign | - | - | ?? Increased EQ | 1/6% Res | 240 | | Anti-Drug Campaign | - | - | ?? Increased LE | 1/5% Res | 241 | | CPR Training | - | - | ?? Increased LE | 1/6% Res | 242 | | Neighborhood Watch | - | - | - | 1/3% Res | 243 | | Energy Conservation | - | - | Power usage drops by 1/12 (~8.333%) | 1/2% All | 244 | | Nuclear Free Zone | - | - | No Nuclear Power plants can be built. | 0% | 245 | | Homeless Shelter | +1% Commercial | - | - | 0.5% Res | 246 | | Pollution Controls | -1% Industrial | - | Less pollution | 1% Ind | 247 | | Volunteer Fire Dept. | - | - | ?? Increased fire power. | 1/3% Res | 248 | | Public Smoking Ban | - | - | ?? Increased LE | 1/6% Res | 249 | | Free Clinics | - | - | ?? Increased LE | 1/2% Res | 250 | | Junior Sports | - | - | ?? Increased LE/EQ | 1/4% Res | 251 | | Tourist Advertising | +1% Commercial | - | - | 1% Comm | 252 | | Business Advertising | +1% Industrial | - | - | 1% Ind | 253 | | City Beautification | +1% Residential | - | - | 1/4% Res | 254 | | Annual Carnival | +1% Commercial | - | - | 1/3% Comm | 255 | 256 | #### Miscellaneous Notes 257 | 258 | The buildings that cause NIMBY reactions are: 259 | 260 | - Gas Power Plant 261 | - Oil Power Plant 262 | - Nuclear Power 263 | - Coal Power 264 | - Prison 265 | - Water Treatment Plant 266 | 267 | Churches appear every 5000 people, without arcos. 268 | 269 | ##### Citizen Demands 270 | 271 | Citizens demand services at certain points. Unless otherwise noted, population counts are without arcos. 272 | 273 | - Schools are every 20,000 sims. 274 | - Fire stations are every 20,000 sims. 275 | - Hospitals are every 25,000 sims. 276 | - More water capacity is needed if utilization reaches 98%. 277 | - More power capacity is needed if utilization reaches 98%. 278 | - Churches are automatically built every 2,500 sims, but only replace an existing 2x2 residential building. 279 | - Residential recreation demand only crops up after 10,000 population. 280 | - Each tile of a recreation building increases the demand cap by 1,000 (except the large park, which is 1,000/3). 281 | - A marina increases the residential demand cap by 9,000 total. 282 | - A big park increases the residential demand cap by 3,000 total. 283 | - Zoos and stadiums each increase the residential demand cap by 16,000 total. 284 | - Airport demand is every 10,000 commercial population (potentially only the runway cross counts). 285 | - A road connection satisfied 2,000 commercial population demand. 286 | - Seaport demand is every 10,000 industrial population (only the crane counts). 287 | - A rail connection also satisfies 10,000 industrial population. 288 | - A highway connection also satisfies 10,000 industrial population. 289 | 290 | ## Cheats 291 | 292 | ### Windows 95 293 | 294 | 0. `fund` 295 | 1. `cass` 296 | 2. `iamacheat` 297 | 3. `noah` 298 | 4. `newhouse` 299 | 5. `priscilla` 300 | 6. `gilmartin` 301 | 7. `joke` 302 | 303 | - `newhouse` doesn't work, because when 'n' is typed, the game starts looking for noah, and never reaches this. 304 | -------------------------------------------------------------------------------- /text data spec.md: -------------------------------------------------------------------------------- 1 | # Text File Specifications 2 | 3 | Covers the contents of the newspapers in DATA_USA and [other ingame text](#other-ingame-text) in TEXT_USA (though it should work for other localizations, only tested with the USA version). Written for the Windows 95 Special Edition version, with differences noted. The DOS version of the data files is different, but the text and rules inside appear to be the same, barring some minor differences. 4 | 5 | ## Newspapers 6 | 7 | DATA_USA.DAT has the raw newspaper text, and some metadata on how to build stories. 8 | DATA_USA.IDX has an index for reading the various parts of the newspaper data file. 9 | This specification is incomplete in exactly how this file works, but is enough to figure out what is going on. 10 | 11 | ### Basic format specification: 12 | 13 | DATA_USA.IDX contains offsets for certain sections in the DATA_USA.DAT file. This is used to break segments into specific lengths. The names for each section come from the Mac version of SimCity 2000, where this data is stored in DATA resources in the resource fork. 14 | 15 | | id | length | name | purpose | 16 | |-------|--------|---------------|------------------------------| 17 | | 0x3e8 | 500 | Group Start | start points of token groups | 18 | | 0x3e9 | 500 | Group Count | token counts in each group | 19 | | 0x3ea | 10000 | Token Pointer | pointers to each token | 20 | | 0x3eb | 149227 | Token Data | actual newspaper data | 21 | | 0x3ec | 160 | Story Power | unknown | 22 | | 0x3ed | 160 | Story Decay | unknown | 23 | 24 | #### Token Pointer 25 | 26 | A series of 32-bit values, stored big-endian. Each value is an offset into the `Token Data` section, and defines the start of a token. 27 | 28 | #### Token Data 29 | 30 | The text data itself. Each individual token is terminated with `0x00`. 31 | 32 | #### Group Start and Group Count 33 | 34 | These segments contain a series of two-byte values, stored big-endian. Each value in `Group Start` stores the index of a token from the `Token Pointer` section, and indicates the start of a group. The corresponding value in the `Group Count` segment contains the number of tokens in each group. 35 | 36 | #### Story Power and Decay 37 | 38 | Unknown at present. There are many repeated values that are about right to be 8B integers. More work needed to figure out what these do. 39 | 40 | ### Compression 41 | 42 | Uses a simple substitution compression to substitute two letters next to each other (and taking two bytes) with a single byte token. Potentially chosen based on analysis of the input data. Some values are also meant to be substituted with other things, such as they Mayor's name or city name. 43 | 44 | #### Byte -> Value Mapping Table: 45 | 46 | Note that all-caps values are not something to decompress, but a pointer to fill in a word from a different spot in the data file. 47 | 48 | | Value | Output | Value | Output | Value | Output | Value | Output | 49 | |-------|-----------|-------|------------|-------|--------|-------|--------| 50 | | 0x0 | None | 0x40 | @ | 0x80 | | 0xC0 | di | 51 | | 0x1 | th | 0x41 | A | 0x81 | | 0xC1 | mo | 52 | | 0x2 | in | 0x42 | B | 0x82 | | 0xC2 | bu | 53 | | 0x3 | re | 0x43 | C | 0x83 | | 0xC3 | ho | 54 | | 0x4 | to | 0x44 | D | 0x84 | | 0xC4 | ea | 55 | | 0x5 | an | 0x45 | E | 0x85 | | 0xC5 | un | 56 | | 0x6 | at | 0x46 | F | 0x86 | | 0xC6 | | 57 | | 0x7 | er | 0x47 | G | 0x87 | | 0xC7 | | 58 | | 0x8 | st | 0x48 | H | 0x88 | | 0xC8 | io | 59 | | 0x9 | en | 0x49 | I | 0x89 | | 0xC9 | pa | 60 | | 0xA | on | 0x4A | J | 0x8A | | 0xCA | ra | 61 | | 0xB | of | 0x4B | K | 0x8B | | 0xCB | ke | 62 | | 0xC | te | 0x4C | L | 0x8C | | 0xCC | lo | 63 | | 0xD | ed | 0x4D | M | 0x8D | | 0xCD | ly | 64 | | 0xE | ar | 0x4E | N | 0x8E | | 0xCE | ri | 65 | | 0xF | is | 0x4F | O | 0x8F | | 0xCF | sh | 66 | | 0x10 | ng | 0x50 | P | 0x90 | | 0xD0 | | 67 | | 0x11 | me | 0x51 | Q | 0x91 | | 0xD1 | | 68 | | 0x12 | co | 0x52 | R | 0x92 | | 0xD2 | | 69 | | 0x13 | ou | 0x53 | S | 0x93 | | 0xD3 | | 70 | | 0x14 | al | 0x54 | T | 0x94 | | 0xD4 | | 71 | | 0x15 | ti | 0x55 | U | 0x95 | | 0xD5 | | 72 | | 0x16 | es | 0x56 | V | 0x96 | | 0xD6 | | 73 | | 0x17 | ll | 0x57 | W | 0x97 | | 0xD7 | | 74 | | 0x18 | he | 0x58 | X | 0x98 | | 0xD8 | | 75 | | 0x19 | ha | 0x59 | Y | 0x99 | | 0xD9 | pe | 76 | | 0x1A | it | 0x5A | Z | 0x9A | | 0xDA | ch | 77 | | 0x1B | ca | 0x5B | [ | 0x9B | | 0xDB | tr | 78 | | 0x1C | ve | 0x5C | \ | 0x9C | | 0xDC | ci | 79 | | 0x1D | fo | 0x5D | ] | 0x9D | | 0xDD | hi | 80 | | 0x1E | de | 0x5E | ^ | 0x9E | le | 0xDE | | 81 | | 0x1F | be | 0x5F | _ | 0x9F | or | 0xDF | so | 82 | | 0x20 | `space` | 0x60 | \` | 0xA0 | | 0xE0 | | 83 | | 0x21 | ! | 0x61 | a | 0xA1 | | 0xE1 | | 84 | | 0x22 | " | 0x62 | b | 0xA2 | | 0xE2 | | 85 | | 0x23 | # | 0x63 | c | 0xA3 | | 0xE3 | | 86 | | 0x24 | $ | 0x64 | d | 0xA4 | | 0xE4 | | 87 | | 0x25 | % | 0x65 | e | 0xA5 | | 0xE5 | | 88 | | 0x26 | & | 0x66 | f | 0xA6 | | 0xE6 | | 89 | | 0x27 | ' | 0x67 | g | 0xA7 | | 0xE7 | | 90 | | 0x28 | ( | 0x68 | h | 0xA8 | | 0xE8 | | 91 | | 0x29 | ) | 0x69 | i | 0xA9 | ma | 0xE9 | | 92 | | 0x2A | * | 0x6A | j | 0xAA | li | 0xEA | | 93 | | 0x2B | + | 0x6B | k | 0xAB | we | 0xEB | | 94 | | 0x2C | , | 0x6C | l | 0xAC | ne | 0xEC | | 95 | | 0x2D | - | 0x6D | m | 0xAD | | 0xED | | 96 | | 0x2E | . | 0x6E | n | 0xAE | se | 0xEE | su | 97 | | 0x2F | / | 0x6F | o | 0xAF | nt | 0xEF | rt | 98 | | 0x30 | 0 | 0x70 | p | 0xB0 | wa | 0xF0 | ta | 99 | | 0x31 | 1 | 0x71 | q | 0xB1 | wh | 0xF1 | ge | 100 | | 0x32 | 2 | 0x72 | r | 0xB2 | pr | 0xF2 | rs | 101 | | 0x33 | 3 | 0x73 | s | 0xB3 | si | 0xF3 | ow | 102 | | 0x34 | 4 | 0x74 | t | 0xB4 | as | 0xF4 | us | 103 | | 0x35 | 5 | 0x75 | u | 0xB5 | | 0xF5 | ss | 104 | | 0x36 | 6 | 0x76 | v | 0xB6 | | 0xF6 | sp | 105 | | 0x37 | 7 | 0x77 | w | 0xB7 | | 0xF7 | ac | 106 | | 0x38 | 8 | 0x78 | x | 0xB8 | nd | 0xF8 | il | 107 | | 0x39 | 9 | 0x79 | y | 0xB9 | po | 0xF9 | ic | 108 | | 0x3A | : | 0x7A | z | 0xBA | la | 0xFA | pl | 109 | | 0x3B | ; | 0x7B | { | 0xBB | no | 0xFB | fe | 110 | | 0x3C | < | 0x7C | | 0xBC | ce | 0xFC | wo | 111 | | 0x3D | CITYNAME | 0x7D | } | 0xBD | fi | 0xFD | da | 112 | | 0x3E | TEAMNAME | 0x7E | MAYORNAME | 0xBE | yo | 0xFE | ai | 113 | | 0x3F | ? | 0x7F | wi | 0xBF | do | 0xFF | ur | 114 | 115 | Notes: 116 | 117 | - `0x20`: is " ", the space character, 118 | - `0x3E`: team name is probably one of the sports team names, unclear how this is chosen from the available ones. 119 | 120 | ### Other mappings 121 | 122 | #### Escape Characters 123 | 124 | `[` byte is an escape value. This means instead of using the previous lookup table, instead treat it as a pointer to some other piece of data in the [escape values table](#escape-value-table) below. 125 | 126 | `^` seems to behave similarly. `^0x97` is a country name just like `[0x97`, but it's used to disambiguate between two different countries that should stay the same within the news story. 127 | 128 | `@` also `@0xa4` seems to be a foreign last name. Just link `[0xa4`. 129 | 130 | `*` seems to behave slightly differently. With the previous escape characters, when a value is selected the same value will be used throughout the article. For instance, every instance of `[0xB0` will map to the same last name. However, `*0xB0` will pick a random last name for each occurrence in the article. If the `*` is in a headline, the occurrences in the body should match. This is not the case in the DOS version. 131 | 132 | #### Numbers 133 | 134 | `%x` is some number. X seems to be the maximum the number will be. Multiple numbers can be stacked together, for example in the time templates: `%12:%5%9 am` and `%12:%5%9 pm`. The number can contain a 1000s separator, like `%250,000`. The minimum appears to be 1. 135 | 136 | There appears to be a bug in the Windows 95 version affecting number generation. The Mac and DOS versions correctly generate number in the right range. This may be due to running the game on modern Windows versions, perhaps the random function changed. 137 | 138 | Broken examples from the Win95 version.: %100=1200, %1000 = 7000, %20 = 30,370, %50 = 360, %250 = 1350, %4 = 30 %250,000 = 2350,000 139 | 140 | `0x0402 bit flags? 000000000000->0000010000000010 899 | 900 | Doesn’t actually seem to affect the simulation if it’s blanked. However, planes/helicopters seemed to disappear when blanked. Maybe this is a flight path for planes or something? 901 | 902 | Last byte was 0x00 in 1114 cities looked at. 903 | 904 | Made up of 40x12B chunks. 905 | 906 | First chunk appears to be a header 907 | 908 | 39x other chunks after (39 pointers in XTXT) 909 | 910 | Basic structure for a chunk seems to be: 911 | 912 | |Offset|Usage| 913 | |---|---| 914 | | 00 | int representing the id of the tile, given below | 915 | | 01 | Seems to be the tile rotation. | 916 | | 02 | Seems to be a modifier, for id=9, this seems to turn the boat into nessie | 917 | | 03 | tile x coordinate | 918 | | 04 | tile y coordinate | 919 | | 05 | tile z height (how far above the ground is this, for plane/helicopter) | 920 | | 06 | "px", unknown | 921 | | 07 | "py", unknown | 922 | | 08 | "dx", unknown | 923 | | 09 | "dy", unknown | 924 | | 0A | "label", unknown | 925 | | 0B | "goal", unknown | 926 | 927 | **Observed tile ids:**\ 928 | 0x1: Airplane\ 929 | 0x2: Helicopter\ 930 | 0x3: Ship\ 931 | 0x4: Unknown\ 932 | 0x5: monster\ 933 | 0x6: Explosion\ 934 | 0x7: Police Deploy\ 935 | 0x8: Fire Deploy\ 936 | 0x9: Sailboat\ 937 | 0xA: Train (seems to be front of the train)\ 938 | 0xB: Train (seems to be for the other two train cars.)\ 939 | 0xC: Seems related to a train in a subway tunnel.\ 940 | 0xD: Seems related to a train in a subway tunnel.\ 941 | 0xE: Military Deploy\ 942 | 0xF: tornado 943 | 944 | ## XBIT 945 | 946 | 1B per tile, storing 8 single bit flags. 947 | 948 | |Bit Position | Flag Meaning| 949 | |---|---| 950 | | 0 | Powerable (Does this tile receive power).| 951 | | 1 | Powered (Is this tile receiving power).| 952 | | 2 | Piped (Can this tile receive water).| 953 | | 3 | Watered (Is this tile receiving water).| 954 | | 4 | XVAL mask. | 955 | | 5 | Water (is this tile covered in water).| 956 | | 6 | Rotate the tile by 90 degrees.| 957 | | 7 | Salt Water (Will water on this tile be fresh or salt water).| 958 | 959 | _Bit #4 Notes:_ This bit is set for a mask for xval. 64x64 and needs scaling. Doesn’t appear in all cities. Ignoring it does not seem to cause issues as value 0x00 in xval is already transparent. Maybe only old/DOS created cities.\ 960 | _Rotation Notes:_ For example, LR pier becomes TB peir with this set, LR runway becomes TB with this set, LR onramps become TB onramps with this set, bridge pieces as well. 961 | 962 | ## 64x64 Minimaps 963 | 964 | Total # is 4096 = 64x64. 965 | 966 | Show in city appears to split into 2x2 blocks, for a total of 4096 blocks.\ 967 | Going with 16 colours from white to black makes bitmaps that are very similar to the in game minimap. 968 | 969 | ### XTRF 970 | 971 | Traffic data. This is why the game shows traffic in 2x2 blocks, even for roads that are only 1x1 tiles in size. 972 | 973 | ### XPLT 974 | 975 | Pollution 976 | 977 | ### XVAL 978 | 979 | Land Value, simulation shows these values using human friendly 1 indexed. 980 | 981 | ### XCRM 982 | 983 | Crime 984 | 985 | ## 32x32 Minimaps 986 | Total # is 1024 = 32x32. Show in city appears to split into 4x4 blocks, for a total of 1024 blocks.\ 987 | Minimap window seems to bin these in 16 even blocks. 988 | 989 | ### XPLC 990 | 991 | Police coverage 992 | 993 | ### XFIR 994 | 995 | Fire coverage. 996 | 997 | ### XPOP 998 | 999 | Population density. 1000 | 1001 | ### XROG 1002 | 1003 | Rate of Growth graph information. 1004 | 1005 | 7F: no change (7F seems to be the default for a new city what hasn’t been run yet).| 1006 | >82: + change (Green)| 1007 | <7D: - change (Red) 1008 | 1009 | _Note:_ Numbers chosen after experimentation, numbers in the very middle could affect the simulation, no 00 or FF noted. 1010 | 1011 | ### XGRP 1012 | 1013 | Historical graph data for the graph window.\ 1014 | 16 different tracked stats, shows 1, 10 and 100 years. Appears to update every month, every 1/2 year and every 5 years.\ 1015 | 16*(20+20+12)=832*4B=3328B 1016 | 1017 | **Contents:**\ 1018 | Each section contains 52*4B integers containing historical data for the graph.\ 1019 | 12 for 1 year, 20 for 10 years, 20 for 100 years. (1/month, 1/6months, 1/5years) 1020 | 1021 | From beginning: 1022 | 1023 | |Offset|Graph| 1024 | |---|---| 1025 | |0000 .. 00CF | City Size| 1026 | |00D0 .. 019F | Residents| 1027 | |01A0 .. 026F | Commerce| 1028 | |0270 .. 033F | Industry| 1029 | |0340 .. 040F | Traffic.| 1030 | |0410 .. 04DF | Pollution.| 1031 | |04E0 .. 05AF | Value| 1032 | |05B0 .. 067F | Crime| 1033 | |0680 .. 074F | Power %| 1034 | |0750 .. 081F | Water %| 1035 | |0820 .. 08EF | Health| 1036 | |08F0 .. 09BF | Education| 1037 | |09C0 .. 0A8F | Unemployment| 1038 | |0A90 .. 0B5F | GNF (GNP?), in 1000s.| 1039 | |0B60 .. 0C2F | Nat’n Pop., in 1000s| 1040 | |0C30 .. 0CFF | Fed Rate| 1041 | 1042 | ## Additional Fields for Scenario Files 1043 | 1044 | ### TEXT 1045 | 1046 | Textual description of the scenario. Max lengths are unknown. 1047 | 1048 | There are two entries. The first four bytes describe the type of entry: 1049 | 1050 | - `80 00 00 00`: the scenario selection screen description. 1051 | - `81 00 00 00`: the extended description shown in game when the scenario starts. 1052 | 1053 | ### SCEN 1054 | 1055 | Scenario information. This includes which disaster to trigger and where, as well as win conditions and the time limit 1056 | 1057 | The entries after the time limit are the goals that need to be met before that time limit expires. 1058 | 1059 | | Offset | Length | Type | Use | Notes | 1060 | |---|---|---|---|---| 1061 | | 0x00 | 4B | Bytes | Header | Header, always `80 00 00 00`. | 1062 | | 0x04 | 2B | Integer | Disaster | Type of disaster, as defined in the MISC section. | 1063 | | 0x06 | 1B | Integer | Disaster X Location | | 1064 | | 0x07 | 1B | Integer | Disaster Y Location | | 1065 | | 0x08 | 2B | Integer | Time Limit (Months) | | 1066 | | 0x0A | 4B | Integer | City Size | Seems to be comparing against the normal city population without arcos from MISC. | 1067 | | 0x0E | 4B | Integer | Residential Population | | 1068 | | 0x12 | 4B | Integer | Commercial Population | | 1069 | | 0x16 | 4B | Integer | Industrial Population | | 1070 | | 0x1A | 4B | Integer | Cash Goal | Seems to be total cash on hand, not counting debts from bonds. | 1071 | | 0x1E | 4B | Integer | Land Value Goal | Total city land value should be above this. | 1072 | | 0x22 | 4B | Integer | Pollution Limit | Pollution should be below this limit. | 1073 | | 0x26 | 4B | Integer | Crime Limit | Crime should be below this limit. | 1074 | | 0x2A | 4B | Integer | Traffic Limit | Traffic should be below this limit. | 1075 | | 0x2E | 1B | Integer | First Building | Building ID per [XBLD](#xbld) to be built to win. | 1076 | | 0x2F | 1B | Integer | Second Building | As above, but a second goal. | 1077 | | 0x30 | 2B | Integer | First Building Tile Count | Count of tiles that need to be built to win. Untested, but this means that building a single 4x4 building would require 16 tiles to be built to win. | 1078 | | 0x32 | 2B | Integer | Second Building Tile Count | As above, but for second building goal. | 1079 | | 0x34 | 4B | Null | Padding (Optional) | Sometimes there’s an extra 4 bytes of 0s at the end of the scenario as padding, but these don't seem appear in all scenarios. Potentially one version of the game needed a specific alignment. | 1080 | 1081 | ### PICT 1082 | 1083 | Image data for the scenario. All of the observed scenarios appear to be 65x65 pictures, with a 1px border on them, making the effective size actually 63x63. 1084 | 1085 | **Data Format:** 1086 | 1087 | | Offset | Length | Use | 1088 | |---|---|---| 1089 | | 0x00 | 4B | Header, always `80 00 00 00` | 1090 | | 0x04 | 2B | X size of image in pixels. | 1091 | | 0x06 | 2B | Y size of image in pixels. | 1092 | | 0x08 | varies | Rows of image data. | 1093 | 1094 | Each row of image data is the Y dimension single pixel bytes, with an additional `0xFF` denoting the end of a row. Additionally, the first and last row being all `0x01` and the first and last pixel of all other rows being `0x01`. 1095 | 1096 | The pixel bytes are colours chosen from an internal palette, seemingly based on `PAL_MSTR.BMP` as used for all other ingame graphics. There seems to be a -16 offset from the indices used to render the tile sprites. 1097 | 1098 | Not all values in the `PAL_MSTR.BMP` are actually valid values, with the observed range being from 18 to 169 inclusive. Additionally, values in the range 160 to 170 (in `PAL_MSTR`) appear to be remapped to indices 0 to 10. Note that 170 is where the first colour cycling value appears in `PAL_MSTR.BMP`. 1099 | 1100 | There are also two special case remapping between the `PAL_MSTR.BMP` and the PICT palette index: 1101 | 1102 | - (0, 0, 0): 0 1103 | - (127, 127, 127): 254 1104 | 1105 | Note: The game does not appear to actually care if the "border" values are `0x01` as `0x00` has been observed to work as well. It also doesn't appear to require the `0xFF` byte at the end of a row of pixels, instead seeming to use the X/Y dimensions specified in the header to determine pixel data. Only older scenarios seem to use the explicit border and row end values, with newer ones using all `0x00`. 1106 | 1107 | Note 2: Some images appear to have full black (0, 0, 0) in them, but enumeration of the palette did not produce the black pixels, and it is presently unclear how this works. 1108 | 1109 | This image shows the colours produced for each value between 0 and 255 (inclusive). For any value without a colour mapping, the game renders it as either (127, 127, 17) or (159, 159, 159). It is unclear why or how it chooses differently between the two. As noted previously 254 seems to be the "real" index for the mid-gray, but it's unclear which is the "real" for the 159 gray. 1110 | 1111 | ![PICT image index to palette mapping.](images/pict_palette.png) 1112 | 1113 | ### TMPL 1114 | 1115 | This only appears in the 5 scenarios originally shipped with the game. 1116 | 1117 | Each entry consists of a pascal style string, followed by a data type in a 4-character shortened format. 1118 | 1119 | It has no function in actual game usage, but lays out what the contents of the `SCEN` section contain, presumably so that people can make their own scenarios. It is unknown why later scenarios omit this information. This information is identical to the [SCEN](#scen) section of this documentation. 1120 | --------------------------------------------------------------------------------