Wizardry V: Heart of the Maelstrom/Save State Hacking

I've been hex editing everything from emulation save states, to PC save games for a while now, but mostly for personal use. Basically, I've had all the offset locations for the stats and stuff. All I needed was a few more things and it was complete.

How to use this guide

 * Things you need to know to understand this guide
 * 1) What Save state hacking means when the guide refers to it.
 * 2) What a hex offset is.
 * 3) What a Hex Editor is.
 * 4) You will also need a Hex Editor.
 * 5) You can use the Windows calculator/Hex Editor's built-in tools to convert decimal-to-hex and vice versa.
 * 6) You can actually edit hex locations within the editor without screwing up the surrounding code.

...And you can follow a couple of simple guidelines:
 * 1) Unless you are experienced with hex editing, or you don't really care how bad you mess something up, backup any file you edit. In the case of emulation save states... Load the game, switch save slots and then save it. There's your backup :)
 * 2) Document everything you change, just in case. This includes the location and the previous value.

Also, the SNES emulator I was using was ZSNES 1.35. I am not sure if all emulators save states the exact same way. If you aren't sure, download ZSNES and take a simple save state (of anything) and compare the *DOS* file sizes to see if they are the same size. The reason I say to use DOS, is that Windows (which I assume you are using) displays file sizes in Kilobytes, and rounds out. DOS displays file sizes in bytes and, therefore, is more accurate. Even if the files are only a few bytes apart, I would still try. Some emulators might add a few extra info, like the emulator version. An alternative method is to open up the save state file, look at offset 1C15, and see if the first letter of the first character's name is there. If not, you can still look around for your characters' names and then just add or subtract that many (in hex) from the values I give in section [5].

Now that we've gotten that our of the way, the best way to go about using this guide would be this:

Look through section [4] to see what you want to edit. Each element in the game that is covered in this guide will have a description, as well as the format used to edit it. How many bytes long and what the values mean, for example. Then, go to section [5] to see where exactly you want to apply it to.

Let's say, for example, you want change the 4th character's amount of gold. You look up the description to see exactly how to change the amount of gold (from section [4]) and then you go onto section [5] to see what hex offset stores the value of the 4th character's amount of gold. Let's get started.

Things that can be edited
Here, I will describe everything that can be edited with the help of this guide, as well as try to give some insight on what you are editing the values for. Bear with me, as I haven't played this game in awhile.

Basically, each character is exactly 128 bytes apart from the start of the next character. This is perfect, as all (or at least they should) hex editors display characters 16 bytes wide which, in turn, means all the characters' data will be perfectly aligned. This is useful because you can just scroll down 8 lines in order to edit the next character, in the same offset. That probably didn't make much sense but you'll see what I mean when you start editing for all characters at once.

The 128 block of data for each character looks something like this: Byte Position  | from start of  | character. | What is stored in the value. 1-8 | Character Name 9 | Alignment/Class/Race (compressed) 10 | Strength 11 | IQ            12 | Devotion 13 | Vitality 14 | Agility 15 | Luck 16-21 | Gold 22-27 | E.P (Experience Points) 28-29 | Current Hit Points 30-31 | Maximum Hit Points 32-33 | Level 34 | Status 35 | Age 36 | ???            37 | AC (Armor Class) 38-44 | Mage spell points 45-51 | Cleric spell points 52-58 | Mage spells 59-65 | Cleric spells 66-73 | Inventory status indicator 74-81 | Inventory slots 1-8 82 | Max inventory indicator 83 | Poison strength? 84-86 | ???            87 | Symbol next to name? 88-97 | ???        98-103 | Marks (Kills) 104-105 | RIPs (Deaths) 106-128 | ??? There are a few gaps within the majority of the data block, and a large one at the end until you reach the next character. I don't know what these do exactly, and I don't think I want to experiment around. They might be objective flags, but I'm not too sure.

And now, for the breakdown of each specific variable you can modify.

Character name

 * 8 bytes
 * Alphanumeric string (using in-game character set)
 * Range: 00 00 00 00 00 00 00 00-99 99 99 99 99 99 99 99

Probably a useless value to change, since you can always modify your name in the game normally, You can, however, use some other special symbols that are within the game's character set, like Japanese symbols and others (probably left in when it was imported). For fun, try some values in the E0-F0 hex range. Because it is an alphanumeric string, it shares some of the ASCII values that we use. This is why you can look in the file and see your name in plain English, and not a lot of hex gibberish :)

Alignment/Class/Race

 * 1 byte
 * Hex value
 * Range: 00-9F (untested results after 9F)

As noted from the table above, the A/C/R value has been compressed. Sort of. Instead of a value for each, it can represent every possible combination of character's alignment, class and race into 1 value. Although it seems impossible it works quite well. Basically, every time you change this value by one, you change the alignment. For every 4 steps, you change the class type (Fighter, Thief, Mage, etc.) and end up with the same alignment. For every 32 steps, you change the race, but the alignment and class remains the same. With the above information we can use this procedure to completely change a character's a/c/r (we will be using decimal for this example, just add along the numbers): First, determine the Race-

Human  - Add 0 Elf    - Add 32 Dwarf  - Add 64 Gnome  - Add 96 Hobbit - Add 128

Second, determine the Class-

Fighter - Add 0 Mage   - Add 4 Cleric - Add 8 Thief  - Add 12 Wizard - Add 16 Samurai - Add 20 Lord   - Add 24 Ninja  - Add 28

Finally, determine the alignment-

Good   - Add 0 Neutral - Add 1 Evil   - Add 2 ?      - Add 3

Then, all you have to do, is convert the finally decimal value into hex and use that value. Example: We want an Elf (32) Lord (24) who is Neutral (1). 32 + 24 + 1 = 57. Convert it into hex and we get 39. So, if we wanted to change character 1, we slap the value 39 in offset address 1C1D and boom. We now have a neutral Elf Lord. At level 1 :) The '?' alignment I decided to keep in even though I didn't experiment with it any. My guess is that it's kind of like Type-O blood. It can hang around other people with a '?' alignment, as well as G-N-E characters. I could be wrong, though.

Also, You probably would only want to change someone's alignment, so you can mix good/evil characters in one party (unless you have patience enough to do that one trick that does the same job). In that case, just use the third table above and +/- the hex value accordingly. Have a good character that needs a touch of evil? Increase the value by 2. How about a neutral character that wants to be good? Decrease it by 1. It is the same with races and classes. Just add/subtract 32 or 4 from the value, respectively. Remember to use hex when just changing the a/c/r.

Strength, IQ, Devotion, Vitality, Agility and Luck

 * 1 byte each, 6 total
 * Hex values
 * Range: 00-5F (unpredictable results after 5F)

I've decided to group these together because it seems logical to. Basically, just change the value to whatever you want it to be. Naturally, one's stats increase as it's level increases until it hits a maximum, pre-determined by the race. Of course, what's stopping us from having godly stats? :) The highest the game seems to be able to handle correctly, in terms of display, is 95 (5F hex). Any higher and the numbers turn into symbols. At a value of FF, the game still displays 95 but, whether or not that actually has an impact on the game, remains to be seen. I've tested this only once so I am not sure but having a value of 5E seems to be more effective than FF.

Gold

 * 6 bytes
 * Decimal value
 * Range: 000000000000-999999999999

Unlike most of the other values, which are in hex, the gold value is a straight decimal representation. You want 500,000 gold? It would be... 500000 and not 20A107. The game reads the decimal from left to right and takes all values into consideration, so it would actually be something like 000000500000. The only explanation I can give you is that the game doesn't use standard arithmetic to count your gold. Instead, it uses some sort of slot-calculation. Explaining how this works is beyond this guide. This is probably the only way the game can keep track of huge numbers that it wouldn't normally be able to. I don't know how high the SNES is capable of counting to, but my guess is probably a 4-byte unsigned integer (4,294,967,295) much less than what the game, using this method, can handle (999,999,999,999). I haven't tried letter values.

E.P (Experience points)

 * 6 bytes
 * Decimal value
 * Range: 000000000000-999999999999

Same deal as above, but for EP. At first I thought it was a bit overkill having over 999 billion EP but then I saw that levels went in the triple digits. Have fun with this one.

Current/maximum hit points

 * 2 bytes each
 * Hex values
 * Range: 0000-FFFF

Seems simple enough. Change the amount of HP you have and how much you can handle.

Level

 * 2 bytes
 * Hex value
 * Range: 0000-E703 or FFFF?

From the range seen above, it can either go to level 999 (E703) or it can go to the maximum of 65,535 (FFFF), but only the last three digits will show. In this case, you would have the level of 535.

Status

 * 1 byte
 * Hex value
 * Range: 00-08
 * Note: The results are unpredictable if the range is above 08.

This is the status shown on your character, which usually replaces a number in the 'hits' column, in the party window. Normal is the default status.

Age

 * Age
 * 1 byte
 * Hex value
 * Range: 00-FF

Be young or be old, basically.

AC (Armor Class)

 * 1 byte
 * Hex value
 * Range: 00-FF (some restrictions)

This value starts at 0 (00) and then increases to 99 at 63 hex. Afterwards, there is some untested and undocumented stuff until 9F hex which starts at AC -99. After each increase, the AC drops by one (A0 =-98, A1= -97, etc.), eventually it gets to FF and -1 AC.

It's easy to get a positive AC: Just enter the value in hex. To get a negative value: Take the negative number you want (but make it positive), subtract 1 and then convert it to hex. Then, using hex arithmetic, subtract that from FF to get your AC value. EXAMPLE: You want a -65 AC. 65 - 1 =64=40 hex. FF - 40= BF hex. BF would be the value you use for a -65 AC value. Oh, and I think the lower, the better. So a -99 (9F) value is probably what you want, anyway.

Mage/Cleric spell points

 * 7 bytes each (representing each spell level)
 * Decimal values
 * Range: 00 00 00 00 00 00 00-99 99 99 99 99 99 99

Just like gold and EP, this value is in decimal. Only that each byte represents the number of spell points for each spell level. Also, for some strange reason I can't figure out yet...


 * 99 value = 9 spell points
 * 90 value = 9 spell points
 * 09 value = 0 spell points

The game seems to want to use double digits for the spell levels and I don't know why. If it seems that the game only wants to read the first digit, it should just be 90, 80, 70, and so on. So, a hex value of 99 88 55 99 00 22 00 would give you 9 level one spell points, 8 level two spell points, 5 level three spell points, etc... I'm not sure if using letters would give you higher/infinite/negative spell point values.

Mage/Cleric spells

 * 7 bytes each
 * Hex values
 * Range: 00-0F or FF?

Everything in between 02 and 0E I'm not sure. I got mixed results. FF seems to do the same thing as 0F, but sometimes I get no spells when I try different high-ranged values. Just use 0F if you want all the spells for that level.

Inventory status indicators

 * 8 bytes
 * Hex values
 * Range: 00 00 00 00 00 00 00 00-A0 A0 A0 A0 A0 A0 A0 A0

Each 'slot' has a code that will determine the status of the item in you inventory. They are listed to the side of this section.

As you can guess, the first byte will determine the status of the first item in your inventory and so on. The only one you will probably be interested in, is 00, which leaves the item unequipped and identified. It would be handy to use the value 80 for the items that characters wouldn't be able to normally use, but I don't think your AC changes when you try to equip armor. I think it only calculates your AC when you equip or un-equip.

Max inventory indicator

 * 1 byte
 * Hex value
 * Range: 00-08

If you notice the table in the beginning of this section, the max inventory indicator comes after the inventory slots, and there is a good reason I put this before it. When you buy items in the game, and your inventory increases, so does this value. As you sell or drop items, this value decreases. Basically, you set this value to however many items you have in your inventory. If you have eight items, and this value is set to 6, then you will only see the first 6.

Inventory slots

 * 8 bytes
 * Hex values
 * Range: 00 00 00 00 00 00 00 00-87 78 87 87 87 87 87 87

🇨🇴
 * These values will determine what's in your inventory. Everything from hard to find weapons, to quest items can be added with save state hacking.

🇨🇴

🇨🇴

🇨🇴

Everything after 87 hex is just random garbage and, in the game, Love of Abriel is actually a heart symbol, of Abriel.

Poison strength

 * 1 byte
 * Hex value
 * Range: 00-FF?

This value, I am not too sure of. Whenever it's set to anything but 00,it changes your characters' status to Poison. As stated above, there is a separate value for the characters' status. Right now I think, if no matter what you change it to (other than 00) makes you become poisoned, it must have some sort of impact on poison. This is why I called it "poison strength". I haven't tested it extensively, however, but a value of 01 or FF doesn't seem to do any damage. Feel free to experiment.

Symbol next to name

 * 1 byte
 * Hex value
 * Range: 00-FF?

This is another value I'm not too sure about. All I know is that it produces a symbol next to your name when you are inspecting someone. It could be a blessing/enchantment/curse or whatever. I was too lazy to find any real effects.

Marks (Kills)

 * 6 bytes
 * Decimal value
 * Range: 000000000000-999999999999

Not totally sure if it's the number of kills you have, but it's next to the death count, and it has a very large maximum. The marks value has the same principles as gold and E.P.

RIPs (deaths)

 * 2 bytes
 * Hex value
 * Range: 0000-FFFF

Don't like that little blemish on you permanent record? This is how to alter it to a differing total.

Other things to consider
A lot of the values are still not known and they could do anything. I could probably look into what, if anything, they do but I have to leave a little to the imagination, right? :D

Hex offset locations
Here are all the hex address locations for everything that was explained in section [4], for each of the six characters. Remember: Because each character is a perfect 128 bytes away, you can go down 8 lines to reach the exact same spot for the next character, if you decided to edit the same stat for each person.

The numbers in parentheses, "", are how many bytes long a stat is, for quick reference.

🇨🇴

🇨🇴

🇨🇴

🇨🇴

🇨🇴

🇨🇴

🇨🇴

🇨🇴

FAQ
Since this is only the first version of this guide there hasn't been any questions sent in to me, but I figure I should add a few questions that might pop into your head. A. Before I answer this question I would like to get one thing out of the way. In hex (if you don't know), 2 hex digits =1 byte. so 0F=1 byte, EF20= 2 bytes, etc.
 * Q. In the gold example, you stated that 500,000 in hex was 20A107, but using Window's scientific-mode calculator the value turns out to be 7A120. Any explanation?

When programs record a non-string value (numerical, for example) they record it from right-to left. This seems logical to do, since programs also read it from right-to-left. Therefore, when searching or editing hex values, we reverse the hex digits. When I say reverse, I mean splitting the entire hex value into 2-digit chunks, and reversing the chunk positions, so: FE 30 2B CC becomes... CC 2B 30 FE

or...

2E 66 9B 0F 0E becomes... 0E 0F 9B 66 2E In the case of an odd number of digits, add a zero to the front of the hex value: 7D0 becomes... 07D0 (07 D0) and then... D0 07 I hope this explains a bit.

A. Sure. The one I am currently using, and am very pleased with, is WinHex by X-Ways Software (http://www.x-ways.com). It's got a ton of features and it's easy to use. If you are looking for something else, just look around www.cnet.com or www.zdnet.com.
 * Q. Can you recommend a good hex editor?

A. Well, a general search on google will bring up good results. I didn't learn on the internet so I can't suggest a good site.
 * Q. I would like to learn more about hex/hex editing. Can you direct me to a good site?

A. For some examples I used the xx xx format, for sake of example only. When I was explaining the ranges for certain stats within the game, it was either because the value wasn't a numerical value (continuous 'xxxx' format) or it was because the value was non-numerical like a text string, or each value within the range has it's own 'slot', like inventory or spell points (separated 'xx xx' format). Other than that, there really is no difference.
 * Q. I've noticed, in many instances, that you would use 00 00 instead of 0000 and vice-versa. Any particular reason?