Castles II: Siege and Conquest Save Game Format
Format type | Saved game |
---|---|
Save locations | Unknown |
Elements saved | ? |
Games |
The Castles II: Siege and Conquest Save Game Format is used to store the game details of Castles II: Siege and Conquest.
The file is of fixed length, of 11682 bytes for the floppy version and 11733 bytes for the CD version. As such, the location of each byte determines the meaning of the data stored at that location.
File format
The file is encrypted using bit-wise XOR, or bitxor. The second byte (byte 1) is the encryption bitxor value. The file is split into sections. From the 5th byte onward, the first byte of each section is bitxored with the encryption bitxor value, as well as with the length of that section (modulo 256). Every remaining byte in each section is bitxored with the immediately preceding (bitxored) byte. In this way, randomly changing the value of a given byte will likely change multiple values within the game, rendering the save game buggy or unusable. This is also further complicated by that many game fields take up 2 bytes (in little endian style), thus changing the value of a given byte will likely make that field's value too large or garbage. Thus, to correctly edit the same game file, the values need to be correctly re-encrypted.
For example, the first section (tasks) has a length of 936 bytes. 936 modulo 256 is 168. Say the encryption bitxor value was 172, and the first 5 bytes of the tasks section from the save game file were 5, 4, 4, 136, and 171. To decrypt these values, bitxor the first value (5) with the encryption bitxor value (172), to get 169. Then bitxor this value with the length of section modulo 256 (168), to get 1. For subsequent bytes, take the bitxor with the immediately preceding byte value; 5 bitxored with 4 is 1, 4 bitxored with 4 is 0, 4 bitxored with 136 is 140, and 136 bitxored with 171 is 35. So the decrypted values are 1, 1, 0, 140, and 35. The 1st byte means the task is in progress, the 2nd and 3rd bytes (little endian) are the current progress of the task (value of 1, indicating a task which just begun), and the 4th and 5th bytes (little endian) are the total progress needed to complete the task, in this case 140 + 35*256 = 9100.
In Excel, the bitxor of two values can be via the BITXOR command for newer versions, or by using the following formula for older versions (assuming the two values are in A1 and A2):
=BIN2DEC(SUBSTITUTE(DEC2BIN(A1,8)+DEC2BIN(A2),2,0))
Although the below tables gives data types as unsigned integers (UINTs), it is possible that some (or many) of them are actually signed (INTs). However, generally speaking, most of the values should be from 0 to 127, so this does not make a difference. A notable exception is that the progress to the next Adm/Mil/Pol are signed integers, but for Adm, the player needs to reach a threshold of 125 for 8 Adm and 140 for 9 Adm, making it very difficult to reach 8 Adm and impossible to reach 9 Adm through task completions alone.
Start byte | Length | Data type | First byte bitxor | Description |
---|---|---|---|---|
0 (0x0000) | 1 | UINT8 | (none) | Unknown (value is always 16 (0xA0) ) |
1 (0x0001) | 1 | UINT8 | (none) | Encryption bitxor value for rest of save file (from byte 4 onward) |
2 (0x0002) | 2 | UINT16LE | (none) | Number of sections in save file (value is always 25 (0xA9) for floppy, 29 (0xAD) for CD) |
4 (0x0004) | 936 | UINT8 | 168 | Tasks; each task uses 26 bytes of data, tasks 1 to 6 for each of the 6 factions |
940 (0x03AC) | 2 | UINT16LE | 2 | Unknown, likely number of tasks (value is always 36 (0x24) ) |
942 (0x03AE) | 858 | UINT8 | 90 | Player stats; each set uses 143 bytes of data, for each the 6 factions |
1800 (0x0708) | 2 | UINT16LE | 2 | Unknown, likely number of players (value is always 6 (0x06) ) |
1802 (0x070A) | 36 | UINT8 | 36 | Relations between factions; each set uses 6 bytes of data, for each of the 6 factions |
1838 (0x072E) | 2 | UINT16LE | 2 | Faction of the human player (0 = Valois, 1 = Anjou, 2 = Albion, 3 = Burgundy, 4 = The Pope, 5 = Aragon) |
1840 (0x0730) | 9252 | UINT8 | 36 | Territory data; each set uses 257 bytes, for each of the 36 territories |
11092 (0x2B54) | 2 | UINT16LE | 2 | Unknown, likely number of territories (value is always 36 (0x24) ) |
11094 (0x2B56) | 400 | INT16LE | 144 | Variables for plots |
11494 (0x2CE6) | 2 | UINT16LE | 2 | Unknown (to be determined) |
11496 (0x2CE8) | 88 | Unknown | 88 | Unknown (to be determined) |
11584 (0x2D40) | 2 | UINT16LE | 2 | Days left until next plot event |
11586 (0x2D42) | 72 | INT16LE | 72 | Months left before revolt for each of the 36 territories (2 bytes each) |
11658 (0x2D8A) | 2 | UINT16LE | 2 | Time of day (once it reaches 48 or 50 or so, advance to next day) |
11660 (0x2D8C) | 2 | UINT16LE | 2 | Current date (add 1, i.e. save file value of 6 is in-game date of 7) |
11662 (0x2D8E) | 2 | UINT16LE | 2 | Current month (0 = Jan, 1 = Feb, 2 = Mar, etc.) |
11664 (0x2D90) | 2 | UINT16LE | 2 | Current year |
11666 (0x2D92) | 2 | UINT16LE | 2 | Unknown (to be determined) |
11668 (0x2D94) | 2 | UINT16LE | 2 | Plots on or off (0 = off, 1 = on) |
11670 (0x2D96) | 2 | UINT16LE | 2 | Unknown (to be determined) |
11672 (0x2D98) | 2 | UINT16LE | 2 | Faction of human player (but not used? byte 1838 is what determines human player stats) |
11674 (0x2D9A) | 2 | UINT16LE | 2 | Unknown (to be determined) |
11676 (0x2D9C) | 2 | UINT16LE | 2 | Unknown (to be determined) |
11678 (0x2D9E) | 2 | UINT16LE | 2 | Battles on or off (0 = off, 1 = on) |
11680 (0x2DA0) | 2 | UINT16LE | 2 | Difficulty (0 = easy, 1 = easy, 2 = hard, 3 = impossible) |
For the CD version of the game, the last few sections are instead:
Start byte | Length | Data type | First byte bitxor | Description |
---|---|---|---|---|
11680 (0x2DA0) | 2 | UINT16LE | 2 | Music level |
11682 (0x2DA2) | 2 | UINT16LE | 2 | Speech on or off (0 = off, 1 = on) |
11684 (0x2DA4) | 2 | UINT16LE | 2 | Difficulty (0 = easy, 1 = average, 2 = hard, 3 = impossible) |
11686 (0x2DA6) | 36 | UINT8 | 36 | Territory's unique castle ID (0 = none, 1 = Beaumaris, 2 = Bodiam, etc.) |
11722 (0x2DCA) | 11 | UINT8 | 11 | If human has built unique castle (1st byte always 0, 2nd byte is Beaumaris, 3rd byte is Bodiam, etc.; 0 = not built, 1 = built) |
Tasks
Each task consists of 26 bytes of data. The tasks are stored from the first task to the sixth task for each of the factions, in the order of Valois, Anjou, Albion, Burgundy, The Pope, and Aragon.
The data for each task is:
Start byte | Length | Data type | Description |
---|---|---|---|
0 | 1 | UINT8 | Status (1 = in progress, 3 = not active (completed or cancelled), 4 = unavailable) |
1 | 2 | UINT16LE | Current progress on task |
3 | 2 | UINT16LE | Needed progress to complete task |
5 | 2 | UINT16LE | Unknown (usually 0, but sometimes 1 for computer tasks) |
7 | 1 | UINT8 | Task ID |
8 | 1 | UINT8 | Number of Adm points used on task |
9 | 1 | UINT8 | Number of Mil points used on task |
10 | 1 | UINT8 | Number of Pol points used on task |
11 | 7 | Unknown | Unknown |
18 | 1 | UINT8 | Target territory (0 if none, else 0 to 35 for the 36 possible territories) |
19 | 1 | UINT8 | Target faction (0 = none or Valois, 1 = Anjou, 2 = Albion, 3 = Burgundy, 4 = The Pope, 5 = Aragon, 7 = neutral) |
20 | 5 | Unknown | Task-dependent data |
25 | 1 | UINT8 | If task was cancelled (0 = not cancelled, 1 = cancelled) |
The list of Task IDs are:
Task ID | Name |
---|---|
0 | (blank) |
1 | Gather Food |
2 | Cut Timber |
3 | Mine Iron |
4 | Refine Gold |
5 | Build Castle |
6 | Police Realm |
7 | Infantry |
8 | Archers |
9 | Knights |
10 | Ballista |
11 | Catapult |
12 | Siege Tower |
13 | Trojan Rabbit (unavailable in game) |
14 | Attack |
15 | Saboteur |
16 | Scout |
17 | Spy |
18 | Diplomat |
19 | Merchant |
20 | Happiness |
21 | Council |
Note that TASKS.BIN has more data on the characteristics of each task.
Player stats
Each set of player stats consists of 143 bytes of data, for each faction in the order of Valois, Anjou, Albion, Burgundy, The Pope, and Aragon.
The data for each player is:
Start byte | Length | Data type | Description |
---|---|---|---|
0 | 1 | UINT8 | Maximum Adm points |
1 | 1 | UINT8 | Maximum Mil points |
2 | 1 | UINT8 | Maximum Pol points |
3 | 1 | UINT8 | Available Adm points |
4 | 1 | UINT8 | Available Mil points |
5 | 1 | UINT8 | Available Pol points |
6 | 1 | UINT8 | Happiness |
7 | 1 | UINT8 | Number of territories |
8 | 1 | UINT8 | Possible Food production |
9 | 1 | UINT8 | Possible Timber production |
10 | 1 | UINT8 | Possible Iron production |
11 | 1 | UINT8 | Possible Gold production |
12 | 1 | UINT8 | Number of completed castles |
13 | 1 | UINT8 | Current Amount of Food |
14 | 1 | UINT8 | Current Amount of Timber |
15 | 1 | UINT8 | Current Amount of Iron |
16 | 1 | UINT8 | Current Amount of Gold |
17 | 1 | UINT8 | Current Amount of Infantry |
18 | 1 | UINT8 | Current Amount of Archers |
19 | 1 | UINT8 | Current Amount of Knights |
20 | 1 | UINT8 | Current Amount of Ballista |
21 | 1 | UINT8 | Current Amount of Catapult |
22 | 1 | UINT8 | Current Amount of Siege Tower |
23 | 1 | UINT8 | Current Amount of Trojan Rabbit (unavailable in game) |
24 | 1 | UINT8 | Current Amount of Infantry (repeat, value used by game is above value not this one) |
25 | 1 | UINT8 | Current Amount of Archers (repeat, value used by game is above value not this one) |
26 | 1 | UINT8 | Current Amount of Knights (repeat, value used by game is above value not this one) |
27 | 1 | UINT8 | Current Amount of Ballista (repeat, value used by game is above value not this one) |
28 | 1 | UINT8 | Current Amount of Catapult (repeat, value used by game is above value not this one) |
29 | 1 | UINT8 | Current Amount of Siege Tower (repeat, value used by game is above value not this one) |
30 | 1 | UINT8 | Current Amount of Trojan Rabbit (repeat, value used by game is above value not this one) |
31 | 1 | UINT8 | Church standing (0 = excommunicated, 1 = not excommunicated) |
32 | 1 | UINT8 | Unknown (always 6?) |
33 | 1 | UINT8 | Unknown (always 0?) |
34 | 1 | UINT8 | Unknown, but probably related to attack effectiveness (is based on Mil points, army size and happiness) |
35 | 1 | UINT8 | Unknown, but probably related to defense effectiveness (is based on Mil points, army size and happiness) |
36 | 1 | UINT8 | Rank (based on score), updated at beginning of each month |
37 | 1 | UINT8 | If claimed the throne (0 = haven't claimed, 1 = have claimed the throne) |
38 | 1 | UINT8 | Unknown (0 if computer, 1 if human) |
39 | 3 | Unknown | Unknown (seems to always be 0) |
42 | 8 | ASCII | Name (in ASCII) |
50 | 22 | Unknown | Unknown (seems to always be 0) |
72 | 2 | UINT16LE | Current score |
74 | 1 | INT8 | Progress toward next Adm point (since is signed, difficult to advance to 8 Adm, impossible to advance to 9 Adm) |
75 | 1 | INT8 | Progress toward next Mil point |
76 | 1 | INT8 | Progress toward next Pol point |
77 | 1 | UINT8 | Number of possible concurrent tasks |
78 | 1 | UINT8 | Unknown (0 if computer, 1 if human) |
79 | 1 | UINT8 | Starting territory |
80 | 6 | UINT8 | Opinion of each of the factions (Valois, Anjou, Albion, Burgundy, The Pope, Aragon), minimum of 1, maximum of 9 |
86 | 6 | INT8 | Months since was last attacked/saboteured by each faction (-1 means never) |
92 | 6 | INT8 | Months since last successful diplomacy with each faction (-1 means never) |
98 | 1 | Unknown | Unknown |
99 | 1 | UINT8 | Church standing message (if different from byte 31, give appropriate message) |
100 | 1 | UINT8 | Resource type needed to pay troops (0 = food, 3 = gold) |
101 | 1 | UINT8 | Amount of food/gold needed to pay troops |
102 | 1 | UINT8 | If human player didn't pay troops |
103 | 1 | UINT8 | Number of troop units |
104 | 1 | INT8 | Days left before checking to pay troops (-1 = don't need to pay troops) |
105 | 1 | UINT8 | If computer player didn't pay troops |
106 | 1 | UINT8 | After claim, days left before Pope decides on claim |
107 | 36 | UINT8 | Apparent map to player for each of 36 territories (6 = unexplored, 8 = Valois, 9 = Anjou, 10 = Albion, 11 = Burgundy, 12 = The Pope, 13 = Aragon, 15 = neutral; add 16 if partial castle, 32 if small castle, 48 if large castle; add 64 if player owns territory; add 128 if player is computer) |
Relations between factions
Each set of relations is 6 bytes long, storing each faction's relations with each of the 6 factions (including themselves). The order is Valois, Anjou, Albion, Burgundy, The Pope, and Aragon, for both each set of 6 bytes and the 6 bytes within each set. The relations are as shown in the "relations" screens, with values from 1 to 9. Though probably not important, it should be noted that a player's relation with himself is 9 if he's a computer, and 8 if he's the human.
Territory data
The data for each territory is 257 bytes long. After an initial set of data containing basic information about the territory, the rest pertains to the castle on the territory (if it exists), such as the ID, location, hitpoints, etc. of each piece.
Start byte | Length | Data type | Description |
---|---|---|---|
0 | 1 | UINT8 | Owner (0 = Valois, 1 = Anjou, 2 = Albion, 3 = Burgundy, 4 = The Pope, 5 = Aragon, 7 = neutral) |
1 | 1 | UINT8 | Resource (0 = Food, 1 = Timber, 2 = Iron, 3 = Gold) |
2 | 240 | UINT8 | Data for each castle piece, in sets of 3 bytes for each of 80 allowed pieces |
242 | 2 | UINT16LE | Number of castle pieces in data |
244 | 2 | UINT16LE | Number of castle pieces to be built (i.e. actual castle) |
246 | 2 | UINT16LE | Total built castle points, excluding moat (in tenths of a point) |
248 | 2 | UINT16LE | Total possible castle points, excluding moat (in tenths of a point) |
250 | 2 | UINT16LE | Percentage completed (including moat if applicable) |
252 | 2 | UINT16LE | Whether or not moat will be built (0 = no moat, 1 = moat) |
254 | 2 | UINT16LE | Moat points completed, max 500 (in tenths of a point, so value of 500 means 50 points) |
256 | 1 | UINT8 | Castle build priority (0 = uniform, 1 = outward, 2 = inward, 3 = tower) |
Each castle piece is composed of 3 bytes, in little endian form. The first 6 bits (the "small" 6 bits of the first byte) are the horizontal coordinate of the castle piece, with 0 being at the left. The next 6 bits (the "large" 2 bits of the first byte being the smaller bits, and the "small" 4 bits of the second byte being the large bits) are the vertical coordinate of the castle piece, with 0 being at the top. The next 4 bits (the "large" 4 bits of the second byte) are the type of castle piece. For the last byte, the first bit (the "small" bit) is if the piece is a small piece (0) or a tall piece (1). The next 5 bits are the points value of the piece, which is up to 19 for all small pieces except the keep and is up to 31 for all tall pieces and the small keep. Note that this includes the door. The next bit (representing 64) is 1 if the piece has been modified since the last time it was viewed by the human player, 0 if no change since the last time. The practical use of this bit is unknown. The last bit (representing 128) is unused.
The pieces are:
Value | Name |
---|---|
0 | Square tower |
1 | Round tower |
2 | (Unused) |
3 | Keep |
4 | Low wall (east-west) |
5 | Low wall (northwest-southeast) |
6 | Low wall (north-south) |
7 | Low wall (northeast-southwest) |
8 | High wall (east-west) |
9 | High wall (northwest-southeast) |
10 | High wall (north-south) |
11 | High wall (northeast-southwest) |
12 | door (east-west) |
13 | door (north-south) |
14 | (Unused) |
15 | (Unused) |
Note that the castle file, *.LYT, is simply the first 246 bytes of this territory data, in unencrypted form.
The territories are:
Territory ID | Name |
---|---|
0 | Brittany |
1 | Normandy |
2 | Rouen |
3 | Amiens |
4 | Calais |
5 | Flanders |
6 | Vannes |
7 | Chartres |
8 | Reims |
9 | Nantes |
10 | Maine |
11 | Orleans |
12 | Dijon |
13 | Poitou |
14 | Tours |
15 | La Marche |
16 | Blois |
17 | Nevers |
18 | Bourbon |
19 | Angouleme |
20 | Limoges |
21 | Rochefort |
22 | Bergerac |
23 | Auvergne |
24 | Bordeaux |
25 | La Tour |
26 | Quercy |
27 | Loire |
28 | Lyon |
29 | Valence |
30 | Gascony |
31 | Toulouse |
32 | Albi |
33 | Narbonne |
34 | Nimes |
35 | Provence |
Variables for plots
These are mostly related to data used in the plots in a given game. They are used to store plot details such as the player's choices (plot progress -- such as where in the plotline the player is -- is stored elsewhere). Each variable is two bytes long, signed. They are referred to in lib.clu as variable 1000 to variable 1199, and thus will be referred to in the same way here; these are stored as variables 0 to 199 in this section, each two bytes long. Though they can be used to store different things, a number of these variables are used in the same way and stored across different plots. Known variables are below.
For the fractional values, once they reach 100, they increment the related field. For example, if the fractional human player relations with The Pope reaches 106, then it will be changed to 6 and the human player's relations with The Pope will increase by 1.
Variable | Length | Data type | Description |
---|---|---|---|
1088 | 2 | INT16LE | Fractional human player relations with The Pope (out of 100) |
1089 | 2 | INT16LE | Fractional human player relations with Aragon (out of 100) |
1090 | 2 | INT16LE | Fractional human player relations with Anjou (out of 100) |
1091 | 2 | INT16LE | Fractional human player relations with Burgundy (out of 100) |
1092 | 2 | INT16LE | Fractional human player relations with Valois (out of 100) |
1093 | 2 | INT16LE | Fractional human player relations with Albion (out of 100) |
1099 | 2 | INT16LE | Fractional human player happiness (out of 100) |
1197 | 2 | INT16LE | Faction of human player (0 = Valois, 1 = Anjou, 2 = Albion, 3 = Burgundy, 5 = Aragon) |
Months left before revolt
This gives the months left before each territory will revolt, in 2-byte signed integers for each of the 36 territories (for a total of 72 bytes). It decreases by 1 on the 1st of each month. Once the territory is at 5 months or less, it'll start warning that a revolt is likely. Once the territory is at 1 month, on the 1st of the following month it will revolt. If the value is 0xFFFF then it is not counting down months to revolt (because it is neutral or because a Large Castle is nearby.)
Credits
This format was reverse engineered by Vanshilar. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)