├── README.md ├── archive file spec.md ├── images ├── pict_palette.png └── pixel-parsing-bridge.png ├── sc2 file spec.md ├── simulation spec.md ├── sprite data spec.md └── text data spec.md /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /images/pict_palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCity2k/SC2k-docs/1062334f8cc63b2bd297bb8ebffaefadc6b5b4f8/images/pict_palette.png -------------------------------------------------------------------------------- /images/pixel-parsing-bridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCity2k/SC2k-docs/1062334f8cc63b2bd297bb8ebffaefadc6b5b4f8/images/pixel-parsing-bridge.png -------------------------------------------------------------------------------- /sc2 file spec.md: -------------------------------------------------------------------------------- 1 | # SimCity 2000 Windows 95 .sc2 File Specification 2 | 3 | ## Basic File Layout 4 | 5 | The basic file structure is of an EA IFF file: \ 6 | It starts with a 12B (byte) header which contains: 7 | - First 4B is the IFF type, for .sc2 files this is FORM. 8 | - Next 4B is the length of the file (not counting the first 8B) 9 | - Last 4B is a container for the rest of the file, for .sc2 files this is SCDH. 10 | 11 | ## Other file notes 12 | For anything on a grid in the save (most segments), the grid goes from top corner (default rotation) to bottom, row by row right to left. 13 | 14 | This is an unofficial specification, and is therefore incomplete. However, large sections are complete. This specification also only applies to the .sc2 file format, and not how the game interprets the given values. 15 | 16 | Complete sections:\ 17 | CNAM, XTER, XBLD, XZON, XUND, XBIT, XTRF, XPLT, XVAL, XCRM, XPLC, XFIR, XPOP, XROG, XGRP, TEXT 18 | 19 | Mostly complete sections:\ 20 | MISC, XTXT, XLAB, XMIC, SCEN 21 | 22 | Sections that need more work:\ 23 | XTHG, PICT 24 | 25 | ## Chunks: 26 | 27 | Rest of the file has a 4B chunk id (which is 4 ASCII characters between 0x20 and 0x7F inclusive), a 4B integer size for the chunk and finally the chunk data of the same length, in bytes, as the size of the compressed chunk. 28 | 29 | #### Chunks in the file and their uncompressed lengths: 30 | 31 | - [CNAM](#cnam): 32 (Stored uncompressed. May be optional in Mac files.) 32 | - [MISC](#misc): 4800 33 | - [ALTM](#altm): 32768 (Stored uncompressed.) 34 | - [XTER](#xter): 16384 35 | - [XBLD](#xbld): 16384 36 | - [XZON](#xzon): 16384 37 | - [XUND](#xund): 16384 38 | - [XTXT](#xtxt): 16384 39 | - [XLAB](#xlab): 6400 40 | - [XMIC](#xmic): 1200 41 | - [XTHG](#xthg): 480 42 | - [XBIT](#xbit): 16384 43 | - [XTRF](#xtrf): 4096 44 | - [XPLT](#xplt): 4096 45 | - [XVAL](#xval): 4096 46 | - [XCRM](#xcrm): 4096 47 | - [XPLC](#xplc): 1024 48 | - [XFIR](#xfir): 1024 49 | - [XPOP](#xpop): 1024 50 | - [XROG](#xrog): 1024 51 | - [XGRP](#xgrp): 3328 52 | 53 | #### Chunks only in Scenario Files 54 | 55 | Scenario specific entries are uncompressed. 56 | 57 | - [TEXT](#text): variable length (2 entries) 58 | - [SCEN](#scen): 56 59 | - [PICT](#pict): variable length 60 | - [TMPL](#tmpl): 338 61 | 62 | ## Compression: 63 | 64 | A variant of Run-Length Encoding. Comes in two variants, a 1 + n byte version and a two byte version. 65 | 1. 1 + n byte version: first byte is in range [0 .. 127] means that there are n bytes of uncompressed data corresponding to the byte’s value after it. 66 | 2. 2 byte version: first byte is in range [129 .. 255] means to repeat the next byte n times (the RLE part), where (byte value) - 127 = n. 67 | 68 | Note that this encoding scheme can lead to certain sections being larger than if they were uncompressed if they’re very random or alternating data. \ 69 | It appears that every byte is compressed, even if it’s a single byte on its own. There are lots of 0x01 followed by single bytes. Runs are compressed as normal. 70 | 71 | ## Chunk Data Format: 72 | 73 | ### CNAM 74 | 75 | Contains 0x1F as its first byte and then 31 bytes after that. The first ASCII range bytes are the name, but the rest could be garbage data. \ 76 | _Notes:_ Maybe 0x1F (31) is supposed to be the length of the title after it. There appears to be garbage in it though, but the name is terminated with 0x00. If no valid name (starts with 0x00), game uses all-caps filename as city name. This looks a lot like an unsafe memory copy without checking the length of memory copied for the cstring (null terminated) in the original game code. 77 | 78 | ### MISC 79 | 80 | Miscellaneous city data, 4B/32b integers: 81 | 82 | | Offset | Name | Notes| 83 | |---|---|---| 84 | |0000| Unknown (header?) | `00 00 01 22` in 114 cities checked.| 85 | |0004 | City Mode | 0 for terrain edit mode, 1 for city, 2 for disaster mode.| 86 | |0008 | Rotation | Internally called compass. Number between 0 and 3 corresponding to number of counter-clockwise rotations.| 87 | |000C | Year Founded | Year city was founded.| 88 | |0010 | City Age | days since city was founded in 300 day years, and 25 day months? example: date=2435, founded= 2050, (2435-2050)=385. month=July=07, so 385(300)+7*25=115,650. In save file: 115,663, so probably a few day into July.| 89 | |0014 | Money | Stored as signed 32b int | 90 | |0018 | Number of bonds. | 91 | |001C | Game Level | Game difficulty. 0 = None (Map), 1 = Easy, 2 = Medium, 3 = Hard. | 92 | |0020 | City Status | Reward tier obtained. 0 = None, 1 = Mayor's Mansion, 2 = City Hall, 3 = Statue, 4 = Military, 5 = Llama Dome, 6 = Arcos. | 93 | |0024 | City Value | Unknown exactly, stores something to do with total city value.| 94 | |0028 | Land Value | Sum of all the values in XVAL. | 95 | |002C | Crime Count | This is a sum of all of the values stored in XCRM.| 96 | |0030 | Traffic Count | Something to do with traffic, **not** a sum of all value sin XTRF. | 97 | |0034 | Pollution | Unknown | 98 | |0038 | City Fame | Unknown | 99 | |003C | Advertising | Unknown | 100 | |0040 | Garbage | Unknown | 101 | |0044 | Work Force % | What percentage of the population is working? | 102 | |0048 | Work Force LE | LE = Life Expectancy | 103 | |004C | Work Force EQ | EQ = Education Quotient | 104 | |0050| National Population | Population of SimNation| 105 | |0054 | National Value| Unknown | 106 | |0058 | National Tax | Unknown | 107 | |005C| National Trend | How is the sim nation economy doing? This affects interest rates. | 108 | |0060| Heat | Temperature in F. In the newspaper, this degrees F, minus 100.)| 109 | |0064 | Wind | Wind speed. In miles/hour, as shown in newspaper. | 110 | |0068 | Humid | Seems to be rain amount. Measured in mm, as shown in newspaper. | 111 | |006C | Weather | Called weatherTrend by the game. See [Weather Type table](#weather-type).| 112 | |0070 | Disasters | See [Disaster Type table](#disaster-type).| 113 | |0074 | Residential population| Unknown exactly.| 114 | |0078 | Rewards availability | (0s)11111= all 5, 00001=mayor’s only, 10000=arcos only, etc.| 115 | |007C .. 0168 | Population/Health/Education Graph Data| 20 values each, interleaved in that order.| 116 | |016C .. 01EC | Industry Graph Data | 33x4B. Each appears to be for the industry window. There are 3 different graphs, each of which appears to show be stored as ratios, tax rate, demand. _Ranges on values unknown._| 117 | |01F0 .. 05EC | Building Tile Counts | Same index as XBLD, count of that # of building tiles in the city.| 118 | |05F0 | Populated Tile Count | Total number of populated tiles.| 119 | |05F4 | ? | Unknown, but seems like it'd be the other part of Populated Tile count | 120 | |05F8 | Residential Tile Count | | 121 | |05FC | ? | Something like it should be the other half of Residential Tile Count.| 122 | |0600 | Commercial Tile Count | | 123 | |0604 | ? | Something like the other half of commercial tile count.| 124 | |0608 | Industrial Tile Count | | 125 | |060C | ? | Something like the other half of industrial tile count.| 126 | |0610 .. 06D7 | Bond Data | bonds, maximum of 50, signed 32b int. Famous overflow in game. | 127 | |06D8 .. 0718 | Neighbour Data | 4x4B of neighbour information. Form is: neighbour index, neighbour population, neighbour value (unknown what exactly this is) and neighbour fame (again unknown). Ordering is: lower left, upper left, unknown, upper right, bottom right.| 128 | |0710 | Unknown | Seems to be 0 in an established city (full RCI), +’ve in others. Unknown exactly.| 129 | |0718 .. 0720 | RCI demand | Signed 32b int from -2000 to +2000. First R, second C, third I.| 130 | |0738 .. 0778 | Technology Discovery Years | Contains the year the technology was discovered. Appears to be 0 if the city was saved after the technology was invented. Details in [Technology Discovery Years Table](#technology-discovery-years)| 131 | |077C .. 08BF | Property taxes | Each takes 27*4B. See [Tax Rate Table](#budget-tax-rate-details) | 132 | | 077C | residential tax rate | Residential zoned building tax rate, between 0 and 20. | 133 | | 07E8 | commercial tax rate | Commercial zoned building tax rate, between 0 and 20. | 134 | | 0854 | Industrial tax rate | Industrial zoned building tax rate, between 0 and 20. | 135 | | 08C0 .. 092C | Ordinances budget window information | Contents follow the same 27x4B format, but exact contents unknown at this time | 136 | | 0930 .. 0994 | Bond budget window information | Stores information for the budget window. Details in section [Bond Details](#bond-details). 137 | | 0998 .. .0E38 | City services from the budget panel | See [Budget City Service Details](#budget-city-service-details) section.| 138 | | 0E3C | Year end | Unknown | 139 | | 0E40 | Water level | Water table level.| 140 | | 0E44 | terrain - coast | Was this city generated with coastal terrain. | 141 | | 0E48 | terrain - river | Was this city generated with river terrain. | 142 | | 0E4C | Military Base | Not offered base: 0, offered base but no suitable location/refused base: 1, 2: army base, 3: airbase, 4 navy: base, 5: missile silos | 143 | | 0E50 .. 0EC4 |Newspaper List | Unknown exactly, 6x5B structure.| 144 | | 0EC8 .. 0EFC | Newspaper List | Unknown exactly, 9x6B structure.| 145 | | 0FA0 | Ordinances flags | Bit flags for which of the 20 ordinances are enacted. 00000000:none, 000fffff:20. First ordinances (finance) section are rightmost bits. | 146 | | 0FA4 | unemployed | Unknown | 147 | | 0FA8 .. 0FE4 | Military Count | 16x2B count of military tiles. See [Military Tile Count](#military-tile-count-details) section. | 148 | | 0FE8 | Subway Count | Count of underground subway tiles. | 149 | | 0FEC | Speed | Speed setting: 1=paused, 2=Turtle, 3=Llama, 4=Cheetah, 5=African Swallow | 150 | | 0FF0 | Auto Budget | Auto budget setting. | 151 | | 0FF4 | Auto Goto | Auto goto setting. | 152 | | 0FF8 | Sound | Sound effects setting. | 153 | | 0FFC | Music | Music setting. | 154 | | 1000 | Disasters | No disasters setting. | 155 | | 1004 | Paper Delivery | Is paper delivery enabled. | 156 | | 1008 | Extra Newspaper | Is the Extra!!! newspaper enabled. | 157 | | 100C | Newspaper Choice | Which newspaper is chosen to be delivered.| 158 | | 1010 | Unknown | Observed to be 0x80 in many cities. | 159 | | 1014 | Seems to have something to do with zoom and position of map. | 160 | | 1018 | View X | X coordinates for the center of the view. | 161 | | 101C | View Y | Y coordinates for the center of the view. | 162 | | 1020 | Arco Population | Total city population from arcos. | 163 | | 1024 | Connection Tiles | Appears to be a count of tiles that are connected to neighbours.| 164 | | 1028 | Sports Teams | Count of active sports teams from stadiums.| 165 | | 102C | Normal Population | Total city population from normal zones (not arcos). | 166 | | 1030 | Industry Bonus | Unknown | 167 | | 1034 | Pollution Bonus | Unknown | 168 | | 1038 | Old Arrest | Sum of all the police station microsim arrests. | 169 | | 103C | Police Bonus | Unknown | 170 | | 1040 | Disaster | Unknown | 171 | | 1044 | Unknown | Unknown | 172 | | 1048 | Disaster Active | Seems to be 1 if there’s a disaster happening, 0 otherwise. | 173 | | 104C | Go Disaster | Unknown | 174 | | 1050 | Sewer Bonus | Unknown, game doesn't have sewers. Perhaps another name for the water pipes? | 175 | | 1054 .. 10B4 | All Zero Bytes | Observed in all cities checked. | 176 | | 10B8 | Unknown | small (~-15000) negative number or small positive (~20) signed 32b int. Does not appear in most cities checked.| 177 | | 10BC - 12BC | All Zero Bytes | Observed in all cities checked. | 178 | 179 | ### MISC Tables 180 | 181 | #### Weather Type 182 | 183 | |Value | Type| 184 | |---|---| 185 | |00 | Cold| 186 | |01 | Clear| 187 | |02 | Hot| 188 | |03 | Foggy| 189 | |04 | Chilly| 190 | |05 | Overcast| 191 | |06 | Snow| 192 | |07 | Rain| 193 | |08 | Windy| 194 | |09 | Blizzard| 195 | |0A | Hurricane| 196 | |0B | Tornado| 197 | 198 | #### Disaster Type 199 | 200 | |Value | Type| 201 | |---|---| 202 | |0x0 | none| 203 | |0x1 | fire| 204 | |0x2 | flood| 205 | |0x3 | riot| 206 | |0x4 | toxic spill| 207 | |0x5 | buggy air crash| 208 | |0x6 | quake| 209 | |0x7 | tornado| 210 | |0x8 | monster| 211 | |0x9 | meltdown| 212 | |0xA | microwave| 213 | |0xB | volcano| 214 | |0xC | firestorm| 215 | |0xD | mass riots| 216 | |0xE | mass floods| 217 | |0xF | pollution accident| 218 | |0x10 | hurricane| 219 | |0x11 | buggy helicopter crash| 220 | |0x12 | plane crash| 221 | 222 | #### Technology Discovery Years 223 | |Offset|Technology |Notes| 224 | |---|---|---| 225 | |0738| Gas power | | 226 | |073C | Nuclear power | | 227 | |0740 | Solar power | | 228 | |0744 | Wind power | | 229 | |0748 | Microwave power | | 230 | |074C | Fusion power | | 231 | |0750 | Airport | | 232 | |0754 | Highways | | 233 | |0758 | Buses | | 234 | |075C | Subways | | 235 | |0760 | Water treatment | | 236 | |0764 | Desalinization | | 237 | |0768 | Plymouth arco | | 238 | |076C | Forest arco | | 239 | |0770 | Darco | | 240 | |0774 | Launch Arco | | 241 | |0778 | Highways | Odd, but observed in a few cities.| 242 | 243 | #### Budget Tax Rate Details 244 | Population is total population of occupied tiles being taxed. 245 | The number corresponds to a 4B offset for the start of the segment. 246 | 247 | 0. Current population. (Maybe) 248 | 1. current tax rate (0 .. 20%) 249 | 2. unknown 250 | 3. January population 251 | 4. tax rate January 252 | 5. February population 253 | 6. tax rate February 254 | 7. March population 255 | 8. tax rate March 256 | 9. April population 257 | 10. tax rate April 258 | 11. May population 259 | 12. tax rate May 260 | 13. June population 261 | 14. tax rate June 262 | 15. July population 263 | 16. tax rate July 264 | 17. August population 265 | 18. tax rate August 266 | 19. September population 267 | 20. tax rate September 268 | 21. October population 269 | 22. tax rate October 270 | 23. November population 271 | 24. tax rate November 272 | 25. December population 273 | 26. tax rate December 274 | 275 | #### Bond Details 276 | 277 | The rate for the bond is stored as an integer, multiplied by 10,000. Example: a rate of 4% is stored as the integer 40,000. 278 | 279 | The average rate is the arithmetic average of all of the bonds currently floated, while the sum rate is just the sum of all the rates. Example: A 4% bond and a 25% bond have an average rate of 14.5%, with a sum rate of 29%. 280 | 281 | Note: In cities that have used the negative FUND trick/cheat, the "Sum Bond Rate" is incorrect. This is likely an artifact of the bug that allows the trick to work, and doesn't seem to matter. 282 | 283 | 1. Current Count of Bonds Floated 284 | 2. Current Average Bond Rate 285 | 3. Sum Bond Rate 286 | 4. January Count 287 | 5. January Average Rate 288 | 6. February Count 289 | 7. February Average Rate 290 | 8. March Count 291 | 9. March Average Rate 292 | 10. April Count 293 | 11. April Average Rate 294 | 12. May Count 295 | 13. May Average Rate 296 | 14. June Count 297 | 15. June Average Rate 298 | 16. July Count 299 | 17. July Average Rate 300 | 18. August Count 301 | 19. August Average Rate 302 | 20. September Count 303 | 21. September Average Rate 304 | 22. October Count 305 | 23. October Average Rate 306 | 24. November Count 307 | 25. November Average Rate 308 | 26. December Count 309 | 27. December Average Rate 310 | 311 | #### Budget City Service Details 312 | 313 | Each segment has 27 x 4B entries structured. 314 | The number corresponds to a 4B offset for the start of the segment. 315 | 0. current number of that building. 316 | 1. current funding rate (0 .. 100%) 317 | 2. unknown 318 | 3. January count of building 319 | 4. funding % for January 320 | 5. February count of building 321 | 6. funding % for February 322 | 7. March count of building 323 | 8. funding % for March 324 | 9. April count of building 325 | 10. funding % for April 326 | 11. May count of building 327 | 12. funding % for May 328 | 13. June count of building 329 | 14. funding % for June 330 | 15. July count of building 331 | 16. funding % for July 332 | 17. August count of building 333 | 18. funding % for August 334 | 19. September count of building 335 | 20. funding % for September 336 | 21. October count of building 337 | 22. funding % for October 338 | 23. November count of building 339 | 24. funding % for November 340 | 25. December count of building 341 | 26. funding % for December 342 | 343 | Starting offset for section (relative to start of MISC segment): \ 344 | _Note:_ Bus stations have no funding setting in the game and therefore aren't stored in the saved city either. 345 | 346 | |Offset|Section Type| 347 | |---|---| 348 | | 0x0998 | police funding rate | 349 | | 0x0A04 | fire funding rate | 350 | | 0x0A70 | health funding rate | 351 | | 0x0ADC | education funding rate, Schools | 352 | | 0x0B48 | education funding rate, Colleges | 353 | | 0x0BB4 | transit funding rate, Roads | 354 | | 0x0C20 | transit funding rate, Highways | 355 | | 0x0C8C | transit funding rate, Bridges | 356 | | 0x0CF8 | transit funding rate, Rail | 357 | | 0x0D64 | transit funding rate, Subway | 358 | | 0x0DD0 | transit funding rate, Tunnel | 359 | 360 | #### Military Tile Count Details 361 | 362 | | Index | Tile ID | Tile Name | 363 | |---|---|---| 364 | | 0 | None | Unknown. Total count of military tiles? | 365 | | 1 | 0xDD | Straight Runway | 366 | | 2 | 0xDE | Cross Runway | 367 | | 3 | 0xEF | Military Parking Lot | 368 | | 4 | 0xF2 | Cargo Yard | 369 | | 5 | 0xEA | Radar | 370 | | 6 | 0xE3 | Warehouse | 371 | | 7 | 0xE4 | Airport Building 1 | 372 | | 8 | 0xE5 | Airport Building 2 | 373 | | 9 | 0xF1 | Top Secret | 374 | | 10 | 0xE0 | Crane | 375 | | 11 | 0xE2 | Military Control Tower | 376 | | 12 | 0xE7 | F-15B | 377 | | 13 | 0xE8 | Small Hangar | 378 | | 14 | 0xE8 | Large Hangar | 379 | | 15 | 0xF9 | Missile Silo | 380 | 381 | ## ALTM 382 | 383 | Altitude map of the city. Stores the altitude of a tile. 384 | 385 | 2 bytes per tile, stored as a 16 bit integer:\ 386 | Bits 0 to 5: This may be related to tunnel levels. _Needs further investigation._\ 387 | Bits 6 to 10: 5 bit water level height (32 levels) \ 388 | Bits 11 to 15: 5 bit land altitude - for underwater tiles, this is the sea floor (32 levels) 389 | 390 | ## XTER 391 | 392 | Describes how a terrain tile slopes, based on its 4 corners and is represented as 1 byte per tile. 393 | 394 | a is top left:\ 395 | |a|b|\ 396 | |x|y| 397 | 398 | Tile type denoted as: 0=down, 1=up\ 399 | Given as value: tile type\ 400 | **Dry Land:**\ 401 | 00: 0000\ 402 | 01: 1100\ 403 | 02: 0101\ 404 | 03: 0011\ 405 | 04: 1010\ 406 | 05: 1101\ 407 | 06: 0111\ 408 | 07: 1011\ 409 | 08: 1110\ 410 | 09: 0100\ 411 | 0A: 0001\ 412 | 0B: 0010\ 413 | 0C: 1000\ 414 | 0D: 1111\ 415 | 0E .. 0F: unknown. There aren't any other possible sprites in the game files. 416 | 417 | **Underwater:**\ 418 | 10 .. 1D: Same as for dry land, but underwater.\ 419 | 1E .. 1F: unknown 420 | 421 | **Shoreline:**\ 422 | 20 .. 2D: Same as for dry land, 1 = up, or dry land, 0 = down or in the water.\ 423 | 2E .. 2F: unknown 424 | 425 | **Surface Water:**\ 426 | 30 .. 3D: Same as for dry land and shoreline, just with surface (0 depth water).\ 427 | 3E: Waterfall tiles (such as under dams and elsewhere).\ 428 | 3F: unknown 429 | 430 | **More surface water:**\ 431 | 40: LR stream\ 432 | 41: TB stream\ 433 | 42: bay, water Bottom\ 434 | 43: bay, water Left\ 435 | 44: bay, water Top\ 436 | 45: bay, water Right\ 437 | 46 .. FF: unknown\ 438 | _Note: none of the above unknown values appeared in multiple cities._ 439 | 440 | ## XBLD 441 | Stores what building occupies a tile. 442 | Index: Name (SCURK name if different) 443 | 444 | **Ground Cover:**\ 445 | 00: Clear Ground\ 446 | 01: Rubble (Rubble 1)\ 447 | 02: Rubble (Rubble 2)\ 448 | 03: Rubble (Rubble 3)\ 449 | 04: Rubble (Rubble 4)\ 450 | 05: Radioactive Waste (Radioactivity)\ 451 | 06: Trees (Tree)\ 452 | 07: Trees (Couple O Trees)\ 453 | 08: Trees (More Trees)\ 454 | 09: Trees (Morer Trees)\ 455 | 0A: Trees (Even More Trees)\ 456 | 0B: Trees (Tons O Trees)\ 457 | 0C: Trees (Veritable Jungle)\ 458 | 0D: Small park 459 | 460 | **Power Lines:**\ 461 | (L = Left, R = Right, T = Top, B = Bottom, H = High: top of slope)\ 462 | 0E: L-R\ 463 | 0F: T-B\ 464 | 10: HT-B\ 465 | 11: L-HR\ 466 | 12: T-HB\ 467 | 13: HL-R\ 468 | 14: BR\ 469 | 15: BL\ 470 | 16: TL\ 471 | 17: TR\ 472 | 18: RTB\ 473 | 19: LBR\ 474 | 1A: TLB\ 475 | 1B: LTR\ 476 | 1C: LTBR 477 | 478 | **Roads:**\ 479 | 1D: L-R\ 480 | 1E: T-B\ 481 | 1f: HT-B\ 482 | 20: L-HR\ 483 | 21: T-HB\ 484 | 22: HL-R\ 485 | 23: BR\ 486 | 24: BL\ 487 | 25: TL\ 488 | 26: TR\ 489 | 27: RTB\ 490 | 28: LBR\ 491 | 29: TLB\ 492 | 2A: LTR\ 493 | 2B: LTBR 494 | 495 | **Rail:**\ 496 | Additional slope pieces denoted with H for the half-high end.\ 497 | 2C .. 3A: Coding as for power lines\ 498 | 3B: HT-B\ 499 | 3C: L-HR\ 500 | 3D: T-HB\ 501 | 3E: HL-R 502 | 503 | **Tunnel Entrances:**\ 504 | 3F: T\ 505 | 40 :R\ 506 | 41: B\ 507 | 42: L 508 | 509 | **Crossovers:**\ 510 | 43: Power-TB, Road-LR\ 511 | 44: Power-LR, Road-TB\ 512 | 45: Road-LR, Rail-TB\ 513 | 46: Road-TB, Rail-LR\ 514 | 47: Power-TB, Rail-LR\ 515 | 48: Power-LR, Rail-TB 516 | 517 | **Highways:**\ 518 | 49: LR\ 519 | 4A: TB 520 | 521 | **Highway Crossovers:**\ 522 | 4B: LR, Road-TB\ 523 | 4C: TB, Road-LR\ 524 | 4D: LR, Rail-TB\ 525 | 4E: TB, Rail-LR\ 526 | 4F: LR, Power-TB\ 527 | 50: TB, Power-LR 528 | 529 | **Bridges:**\ 530 | 51: Suspension bridge start B\ 531 | 52: Suspension bridge middle B\ 532 | 53: Suspension bridge center\ 533 | 54: Suspension bridge middle T\ 534 | 55: Suspension bridge end T\ 535 | 56: Raising bridge tower\ 536 | 57: Causeway pylon\ 537 | 58: Raising bridge middle (lowered)\ 538 | 59: Raising bridge middle (raised)\ 539 | 5A: Rail bridge, pylon\ 540 | 5B: Rail bridge\ 541 | 5C: Elevated Power Lines 542 | 543 | **Highway Entrance (Onramps):**\ 544 | _Note:_ These can be rotated 90 degrees by bit 6 in XBIT.\ 545 | 5D: Highway-T, Road-L\ 546 | 5E: Highway-T, Road-R\ 547 | 5F: Highway-B, Road-L\ 548 | 60: Highway-B, Road-R 549 | 550 | **Highway bits:**\ 551 | 61: HT-B\ 552 | 62: L-HR\ 553 | 63: T-HB\ 554 | 64: HL-R\ 555 | 65: BR\ 556 | 66: BL\ 557 | 67: TL\ 558 | 68: TR\ 559 | 69: LTBR 560 | 561 | **Reinforced Bridge:**\ 562 | 6A: Pylon\ 563 | 6B: No pylon 564 | 565 | **Subway to Rail:**\ 566 | 6C: Subway-T\ 567 | 6D: Subway-R\ 568 | 6E: Subway-B\ 569 | 6F: Subway-L 570 | 571 | **Residential 1x1:**\ 572 | 70: Lower-class homes (Lower Class Homes 1)\ 573 | 71: Lower-class homes (Lower Class Homes 2)\ 574 | 72: Lower-class homes (Lower Class Homes 3)\ 575 | 73: Lower-class homes (Lower Class Homes 4)\ 576 | 74: Middle-class homes (Middle Class Homes 1)\ 577 | 75: Middle-class homes (Middle Class Homes 2)\ 578 | 76: Middle-class homes (Middle Class Homes 3)\ 579 | 77: Middle-class homes (Middle Class Homes 4)\ 580 | 78: Luxury Homes (Upper Class Homes 1)\ 581 | 79: Luxury Homes (Upper Class Homes 2)\ 582 | 7A: Luxury Homes (Upper Class Homes 3)\ 583 | 7B: Luxury Homes (Upper Class Homes 4) 584 | 585 | **Commercial 1x1:**\ 586 | 7C: Gas Station (Gas Station 1)\ 587 | 7D: Bed & Breakfast Inn (Bed and Breakfast Inn)\ 588 | 7E: Convenience store (Convenience Store)\ 589 | 7F: Gas Station (Gas Station 2)\ 590 | 80: Small office building (Small Office Building 1)\ 591 | 81: Office Building (Small Office Building 2)\ 592 | 82: Warehouse (Warehouse)\ 593 | 83: Cassidy’s Toy Store (Cassidy’s Toy Store) 594 | 595 | **Industrial 1x1:**\ 596 | 84: Warehouse (Small WareHouse 1)\ 597 | 85: Chemical Storage (Chemical Storage)\ 598 | 86: Warehouse (Small WareHouse 1)\ 599 | 87: Industrial substation (Industral Substation) 600 | 601 | **Misc 1x1:**\ 602 | 88: Construction (Construction 7)\ 603 | 89: Construction (Construction 8)\ 604 | 8A: Abandoned building (Abandoned Building 1)\ 605 | 8B: Abandoned building (Abandoned Building 2) 606 | 607 | **Residential 2x2:**\ 608 | 8C: Cheap apartments (Small Apartments 1)\ 609 | 8D: Apartments (Small Apartments 2)\ 610 | 8E: Apartments (Small Apartments 3)\ 611 | 8F: Nice Apartments (Medium Apartments 1)\ 612 | 90: Nice Apartments (Medium Apartments 2)\ 613 | 91: Condominium (Medium Condominiums 1)\ 614 | 92: Condominium (Medium Condominiums 2)\ 615 | 93: Condominium (Medium Condominiums 3) 616 | 617 | **Commercial 2x2:**\ 618 | 94: Shopping center (Shopping Center)\ 619 | 95: Grocery store (Grocery Store)\ 620 | 96: Office Building (Medium Office Building 1)\ 621 | 97: Resort hotel\ 622 | 98: Office Building (Medium Office Building 2)\ 623 | 99: Office/Retail (Office/Retail)\ 624 | 9A: Office Building (Medium Office Building 3)\ 625 | 9B: Office Building (Medium Office Building 4)\ 626 | 9C: Office Building (Medium Office Building 5)\ 627 | 9D: Office Building (Medium Office Building 6) 628 | 629 | **Industrial 2x2:**\ 630 | 9E: Warehouse (Medium Warehouse)\ 631 | 9F: Chemical Processing (Chemical Processing 2)\ 632 | A0: Factory (Small Factory 1)\ 633 | A1: Factory (Small Factory 2)\ 634 | A2: Factory (Small Factory 3)\ 635 | A3: Factory (Small Factory 4)\ 636 | A4: Factory (Small Factory 5)\ 637 | A5: Factory (Small Factory 6) 638 | 639 | **Misc 2x2:**\ 640 | A6: Construction (Construction 3)\ 641 | A7: Construction (Construction 4)\ 642 | A8: Construction (Construction 5)\ 643 | A9: Construction (Construction 6)\ 644 | AA: Abandoned building (Abandoned Building 7)\ 645 | AB: Abandoned building (Abandoned Building 7)\ 646 | AC: Abandoned building (Abandoned Building 7)\ 647 | AD: Abandoned building (Abandoned Building 7) 648 | 649 | **Residential 3x3:**\ 650 | AE: Large apartment building (Large Apartments 1)\ 651 | AF: Large apartment building (Large Apartments 2)\ 652 | B0: Condominium (Large Condominiums 1)\ 653 | B1: Condominium (Large Condominiums 2) 654 | 655 | **Commercial 3x3:**\ 656 | B2: Office park (Office Park)\ 657 | B3: Office tower (Office Tower 1)\ 658 | B4: Mini-mall (Mini Mall)\ 659 | B5: Theater square (Theatre)\ 660 | B6: Drive-in theater (Drive In)\ 661 | B7: Office tower (Office Tower 2)\ 662 | B8: Office tower (Office Tower 3)\ 663 | B9: Parking lot (Parking Lot)\ 664 | BA: Historic office building (Historic Office)\ 665 | BB: Corporate headquarters (Corporate Headquarters) 666 | 667 | **Industrial 3x3:**\ 668 | BC: Chemical processing (Chemical Processing 1)\ 669 | BD: Large factory (Large Factory)\ 670 | BE: Industrial thingamajig (Industrial Thingamajig)\ 671 | BF: Factory (Medium Factory)\ 672 | C0: Large warehouse (Large Warehouse 1)\ 673 | C1: Warehouse (Large Warehouse 2) 674 | 675 | **Misc 3x3:**\ 676 | C2: Construction (Construction 1)\ 677 | C3: Construction (Construction 2)\ 678 | C4: Abandoned building (Abandoned Building 7)\ 679 | C5: Abandoned building (Abandoned Building 8) 680 | 681 | **Power Plants:**\ 682 | C6: Hydro Power (Hydroelectric Power Plant 1)\ 683 | C7: Hydro Power (Hydroelectric Power Plant 2)\ 684 | C8: Wind Power (Wind Power Plant)\ 685 | C9: Gas Power (Gas Power Plant)\ 686 | CA: Oil Power (Oil Power Plant)\ 687 | CB: Nuclear Power (Nuclear Power Plant)\ 688 | CC: Solar Power (Solar Power Plant)\ 689 | CD: Microwave Power (Microwave PowerPlant)\ 690 | CE: Fusion Power (Fusion Power Plant)\ 691 | CF: Coal Power (Coal Power Plant) 692 | 693 | **Services:**\ 694 | D0: City Hall\ 695 | D1: Hospital\ 696 | D2: Police Station (Police Dept)\ 697 | D3: Fire Station (Fire Dept)\ 698 | D4: Museum\ 699 | D5: SimPark System (Big Park)\ 700 | D6: School\ 701 | D7: Stadium\ 702 | D8: Prison\ 703 | D9: College\ 704 | DA: Zoo\ 705 | DB: Statue 706 | 707 | **Infrastructure (not power plants):**\ 708 | DC: Water Pump\ 709 | DD: runway (straight)\ 710 | DE: Runway intersection\ 711 | DF: Pier (Game appears to rotate the pier based on the direction the crane is facing.)\ 712 | E0: Crane\ 713 | E1: Control Tower (Civilian Control Tower)\ 714 | E2: Control Tower (Military Control Tower)\ 715 | E3: Warehouse\ 716 | E4: Building (Building 1)\ 717 | E5: Building (Building 2)\ 718 | E6: Tarmac\ 719 | E7: F-15b\ 720 | E8: Hanger (Hangar 1)\ 721 | E9: SimSubway (Subway Station)\ 722 | EA: Radar (Tarmac)\ 723 | EB: Water Tower\ 724 | EC: Bus Station\ 725 | ED: SimRail System (Rail Station)\ 726 | EE: Parking lot (Civilian Parking Lot)\ 727 | EF: Parking lot (Military Parking Lot)\ 728 | F0: Loading bay (Loading Bay)\ 729 | F1: Top Secret\ 730 | F2: Cargo yard (Cargo Yard)\ 731 | F3: Mayor’s House\ 732 | F4: Water Treatment\ 733 | F5: Library System (Library)\ 734 | F6: Hangar (Hangar 2)\ 735 | F7: Church\ 736 | F8: Marina\ 737 | F9: Missile silo (Missile Silo)\ 738 | FA: Desalinization (Desalinization Plant) 739 | 740 | **Arcos:**\ 741 | FB: Plymouth Arco (Plymouth Arcology)\ 742 | FC: Forest Arco (Forest Arcology)\ 743 | FD: Darco (Darco Arcology)\ 744 | FE: Launch Arco (Launch Arcology) 745 | 746 | **Other:**\ 747 | FF: Llama Dome (Braun Llama Dome) 748 | 749 | ## XZON 750 | 751 | 1 byte per tile, encodes zone information and also if the tile is the corner of a building. 752 | 753 | First 4 bits: encode corners of a building.\ 754 | 1000: TR\ 755 | 0100: TL\ 756 | 0010: BR\ 757 | 0001: BL 758 | 759 | Second 4 bits: encode the following zone information.\ 760 | 0: none (0000)\ 761 | 1: Light Residential (0001)\ 762 | 2: Dense Residential (0010)\ 763 | 3: Light Commercial (0011)\ 764 | 4: Dense Commercial (0100)\ 765 | 5: Light Industrial (0101)\ 766 | 6: Dense Industrial (0110)\ 767 | 7: Military (0111)\ 768 | 8: Airport (1000)\ 769 | 9: Seaport (1001)\ 770 | 10 .. 15: Appear to be unused. 771 | 772 | _Notes:_\ 773 | No city appears to have anything with a hex byte ending in A .. F, so probably unused or saved for future expansion.\ 774 | Small park is 1111 0000, no zone but all four corners in one (1x1). 775 | 776 | ## XUND 777 | 778 | Store the underground part of a tile.\ 779 | 00: None\ 780 | 01 .. 0F: Subway, indexes as power lines in XBLD.\ 781 | 10 .. 1E: Pipes, indexes as per power lines in XBLD.\ 782 | 1F: Crossover, Pipe-TB, Subway-LR\ 783 | 20: Crossover, Pipe-LR, Subway-TB\ 784 | 21: unknown, none in 1114 cities.\ 785 | 22: Missile silo\ 786 | 23: Sub/rail or Subway Station Underground portion.\ 787 | 24 .. FF: unknown, none in 1114 cities. 788 | 789 | ## XTXT 790 | 791 | 1B per tile. Stores the text overlay for that tile. Note that this overlay is used to store not just signs, but also whether or not a microsim is applied to that tile and neighbour connections. 792 | 793 | The "Label?" column indicates if this is an index to the actual text in [XLAB](#xlab) or not. 794 | 795 | |Offset|Use|Label?| 796 | |---|---|---| 797 | | 0x00 | No sign | No | 798 | | 0x01 .. 0x32 | 50 user defined sign. | Yes | 799 | | 0x33 | Unused | N/A | 800 | | 0x34 | Bus | Yes | 801 | | 0x35 | Rail | Yes | 802 | | 0x36 | Subway | Yes | 803 | | 0x37 | Wind Power | Yes | 804 | | 0x38 | Hydro Power | Yes | 805 | | 0x39 | Parks | Yes | 806 | | 0x3A | Museum | Yes | 807 | | 0x3B | Library | Yes | 808 | | 0x3C | Marina | Yes | 809 | | 0x3D .. 0xC8 | 139 Microsim labels. See Notes 1 and 2 below. | Yes | 810 | | 0xC9 .. 0xF0 | 39 things treated like signs. Index to [XTHG](#xthg), probably. See Note 3 below. | No | 811 | | 0xF1 .. 0xF9 | Unknown, but seemingly unused. | N/A | 812 | | 0xFA | Neighbour connection | No | 813 | | 0xFB | Toxic Cloud | No | 814 | | 0xFC | Flood | No | 815 | | 0xFD | Rioters | No | 816 | | 0xFE | Rioters (mass riots, maybe?) | No | 817 | | 0xFF | Fire | No | 818 | 819 | For `0xFA`, this means that the tile is a neighbour connection, and should have an auto-generated sign on it. These sign values are not user changeable and do not count against the user sign limit of 50. 820 | 821 | For `0xFB` and up, these indicate that the tile has the specified disaster tile on it. 822 | 823 | **Note 1:** Used for: police, fire, hospitals, schools, stadiums, zoos, prisons, colleges, power plants, water treatment, desalination, mayor’s house, city hall, llama dome, statue, arcos. (Anything that when you click on it, you can change it’s name that isn’t included above.) 824 | 825 | **Note 2:** There only appear to be 139 labels here, even if there are 140 user facing microsims. It is unknown what causes this discrepancy. 826 | 827 | **Note 3:** Various police/fire/military emergency deploys here, sailboats/nessie, helicopters, maxis man, ships, planes, trains (each train car counts as one). 39 total positions, 33 fire/police/military total. If there are lots of trains and other stuff on the map, this will limit the number of emergency deploys, for example.\ 828 | The tornado, monster, crashing airplane as well. Explosions might also appear in here, but may not be saved in the city file. 829 | 830 | ## XLAB 831 | 832 | Labels pointed to by the pointers from [XTXT](#xtxt), except for cases like the disasters, which don't have a text label. 256 total entries. 833 | 834 | Labels aren't just signs, but also things like the names for microsims that can have names given to them. 835 | 836 | ### Label Data Structure 837 | 838 | Each entry is a fixed 25 bytes. The first byte is the length of the ASCII data, then up to 23 bytes of ASCII text and finally a null (`/x00`) termination. If the termination is not the 25th byte, the rest is padded out by null data (or, due to a bug in some versions of the game, garbage data). 839 | 840 | ### Label Indices 841 | 842 | Values in quotes are the default in the city file, and they apply to all buildings sharing that microsim. They also apply to all microsims if they are explicitly changed. 843 | 844 | |Offset|Label Use| 845 | |---|---| 846 | | 0x00 | Mayor's Name | 847 | | 0x01 .. 0x32 | 50 User Defined Signs | 848 | | 0x33 | Unused label | 849 | | 0x34 | "SimBus System" | 850 | | 0x35 | "SimRail System" | 851 | | 0x36 | "SimSubway" | 852 | | 0x37 | Wind Power | 853 | | 0x38 | Hydro Power | 854 | | 0x39 | "SimPark System" | 855 | | 0x3A | "Museum" | 856 | | 0x3B | "Library System" | 857 | | 0x3C | "Marina" | 858 | | 0x3D .. 0xC8 | 139 [Microsim](#xmic) labels. See Note 2 in [XTXT](#xtxt) section. | 859 | | 0xC9 .. 0xF9 | 48 unused labels | 860 | | 0xFA | Text for the last connection sign, if it exists. | 861 | | 0xFB | Sports team: Football | 862 | | 0xFC | Sports team: Baseball | 863 | | 0xFD | Sports team: Soccer | 864 | | 0xFE | Sports team: Cricket | 865 | | 0xFF | Sports team: Rugby | 866 | 867 | Note: Sometimes the unused labels contain garbage data. This can be safely ignored. 868 | 869 | ## XMIC 870 | 871 | 150 x 8B microsims\ 872 | Probably the first 10 are for the built in microsims, and the next 140 for the rest. 873 | 874 | Given there only appear to be 139 microsims pointed to by XLAB, there could be only 139 here as well. More testing is needed to confirm this number. 875 | 876 | |Offset|Usage| 877 | |---|---| 878 | | 00 | Index to building type. | 879 | | 01 | Single byte microsim value. | 880 | | 02 | Two byte microsim value. | 881 | | 04 | Two byte microsim value. | 882 | | 06 | Two byte microsim value. | 883 | 884 | 885 | Example: "EC 00 00 18 00 60 0C B3" 886 | Bus Line, stats 24 (0x0018), 96 (0x0060), 3251 (0x0cb3) 887 | For a mayor’s mansion: F3 28 08 4A 00 5E 00 00 888 | F3 = mansion, 28 = 4th stat, 08 4A = 2nd stat, 00=(maybe third stat), 5e = first stat, 00 00 could be padding or employees. 889 | Llama Dome example: FF 8B 07 C1 01 07 00 80 890 | 8B=first stat, 07C1=2nd, 0107=3rd, 00=?, 80=4th, but 5th in game (# of weddings) is 139 (0x8B) 891 | 892 | ## XTHG 893 | 894 | _Note:_ This section is mostly incomplete and is presently more structured as notes. 895 | 896 | 00 .. 01: Changes when going from terrain to city mode. 897 | 898 | 0x0000->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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | `