SAV
Jump to navigation
Jump to search

This is the documentation for the old save format. The current format is RSAV
A SAV file consists of binary records of 30000 16-bit INTs (60000 bytes). The number of records varies, but is typically 4 for the for normal save games, or 32 when the F2/F3 quicksave has been used. The records from 5 thru 31 are only accessible via plotscripting,
Integer Offset | Data Size | Name | in-memory storage | Notes |
---|---|---|---|---|
0 | INT | SAV version | Always 3 for current games | |
1 | INT | current map | map | |
2 | INT | hero X | catx(0) | This is relative to the SAV offset in the MAP lump for the current map |
3 | INT | hero Y | caty(0) | This is relative to the SAV offset in the MAP lump for the current map |
4 | INT | hero direction | catd(0) | |
5 | INT | random battle counter | foep | Decremented when you walk, random battle occurs when it reaches zero |
6 | INT | Unused | Used to be leader (and I don't remember what that means) | |
7 | INT | camera x position | mapx | Not relative to SAV offset in MAP, but maybe it should be? |
8 | INT | camera y position | mapy | Not relative to SAV offset in MAP, but maybe it should be? |
9-33 | INT*25 | Money | gold& | Money converted to a string, and stored as ascii digits, one per INT, with zero-padding on the end (profound shame) |
34-138 | INT*105 | General data | gen() | Element 0-104 of the global gen() array. (a few elements of this are ignored when loading. See GEN) |
139-535 | INT*396 | Unused | Used to contain additional elements of gen() | |
536-2634 | INT*300 | NPC x | npc().x | Current locations and state of NPC instances. see SerNPCL code |
INT*300 | NPC y | npc().y | ||
INT*300 | NPC ID | npc().id | ||
INT*300 | NPC direction | npc().dir | ||
INT*300 | NPC frame | npc().frame | ||
INT*300 | NPC x move | npc().xgo | ||
INT*300 | NPC y move | npc().ygo | ||
2635 | INT | Unused | ||
2636-2762 | BIT*2048 | tags | tag() | bit 0 and 1 always zero. Bit 2-999 are tags Bit 1000-1999 are one-time-use bits Bits 2000-2047 are unused |
2763-2803 | INT*41 | hero ID | hero() | hero ID numbers + 1, or 0 for empty party slots |
2804-3304 | INT*501 | Unused? | used to contain an array named a() and danged if I can remember what that was | |
3305-4452 | INT*41*2*14 | Hero stats | stat() | Hero stats. 41 groups of 28 ints for each hero. Current stats 0-13 first, max stats 0-13 next. See stat() for details |
4453-4698 | INT*41*6 | battle menus | bmenu() | Hero battle menus. 41 groups of 6 ints for each hero |
4699-8798 | INT*41*4*25 | spell lists | spell() | Hero spell lists. 41 groups of 4 spell lists for each hero. Each spell list contains 24 ints of attack ID numbers and one wasted int at the end of each list. |
8799-9126 | INT*41*8 | level mp | lmp() | Hero level-MP. 41 groups of 8 ints |
9127-11258 | INT*41*2*26 | Experience | exlev&() | Hero experience levels stored in the same shameful format as the gold. 41 groups of 2 badly stored numbers of 26 ints each, first current experience then next-level experience. Each number is stored as a string with one ascii char per int, zero padded at the end |
11259-11955 | INT*41*17 | her names | name$() | Hero names. 41 badly stored strings of 17 ints each. One ascii char per int, zero padded at the end. |
11956-14594 | INT | 8/16 bit inventory magic | 0 if the inventory is stored here in 8-bit format. 1 if the inventory is stored at 14800 in 16-bit format | |
INT*2 | Unused | (great exploding snakes on toast! Who designed this format! ... or yeah... I did) | ||
INT*198 | Inventory 8-bit | inventory().num inventory().id |
198 ints with item ID in the low 8 bits and item count in the high 8 bits | |
INT*38 | Unused | |||
INT*198*12 | useless item names | inventory().text | Item names, one ascii char per int. It is a mystery to me why we ever stored these here, since they can be easily re-generated from the other data. | |
INT*24 | Unused | |||
14595-14799 | INT*205 | Equipment | eqstuf() | Hero equipment. 41 groups of 5 ints |
14800-14999 | INT*100*2 | Inventory 16-bit first 100 | inventory() | 100 pairs of 2 ints for the first 100 inventory slots. First item id, second item count. Ther rest of the inventory is stored later. |
15000-19999 | INT*100*50 | Shop stock | stock() | Shop stock. 50 ints per shop for 100 shops. |
20000-20003 | BIT*64 | Hero locks | hmask() | Bits 0-40 are locks to prevent swapin/swapout of heroes. bits 41-63 are wasted |
20004-20012 | INT*9 | Caterpillar hero positions | catx() caty() catd() |
3 sets of 3 ints for the other three heroes in the caterpillar party. x,y,direction |
20013-21037 | INT*1025 | script globals 0-1024 (low 16 bits) | global() | Low 16 bits of script globals |
21038-21059 | INT * 22 | Vehicle data | veh() | Current vehicle data (see VEH#Implementation Note) |
21060 | INT | Pic+Pal+Def magic | 4444 if the following picture and palette and default weapon data is stored | |
21061-21306 | INT*41*2*3 | hero pic, pal, and default weapon | stat() | Extended hero data. 41 sets of 6 ints, from stat() elements (,,14) thru (,,16) See stat() for details |
21307 | INT | Hbits magic | 4444 if the following hero bits data is stored | |
21308-21512 | BIT*41*80 | Hero bits | nativehbits() | Hero bitsets. 41 sets of 80 bits. See DT0 |
21513-22537 | INT*1025 | script globals 0-1024 (high 16 bits) | global() | High 16 bits of script globals |
22538-28679 | INT*2*3071 | script globals 1025-4095 low 16, high 16 pairs in that order | global() | more globals |
28680-29679 | INT*500*2 | Inventory 16-bit remainder | inventory() | 500 pairs of 2 ints for the inventory slots 100-599. First item id, second item count. |
29680-29999 | INT*320 | Unused | Unused |