Persona 3 Calculator: Analyzing Save Games (2)

After getting warmed up in the last post on this topic, now it’s time to start looking for the most important informations that are cumbersome to enter into the editor. These are:

Protagonist level (already found)
Social link levels (for fusions which require a maxed level)
Items for special fusions
List of owned Persona with level
Date (for special fusions)

If we can find all this information, the user would just have to get the Persona 3 save game from the console and load it into the editor. So let’s get to it.

Persona in the Compendium

One really good way of finding out about the way persona are saved is to compare two save games which just differ in one respect: In one, we have a more leveled up version of a target persona in our inventory than in the Compendium, and in the second the persona is saved in the Compendium. This results in very little change. See the example screenshot for the differences between a level 55 and 57 Dionysus.

p3_persona_compendium

Upper window: The second save game (Dionysus, level 57), Lower window: The first save game (Dionysus, level 55)

This leads to some speculation about the structure how a persona is saved. If we assume that the persona structure begins with a value of 1 to indicate that the persona is owned, we can then hypothesize about the following offsets starting from this 1:

Relative OffsetMeaning
0x011 indicating that the persona is owned by the player.
0x02Looks like a sort of counter. Maybe the internal number of the Persona?
0x04The level of the Persona.
0x08Educated guess: The total experience points of the Persona.
0xAThis value increased by one in between saved games. Maybe a counter of how many times the persona has been registered?
0xC - 0X1ANo idea. Probably the abilities/resistances/weaknesses of the Persona
0x1CStrength
0x1DMagic
0x1EEnergy
0x1FAgility
0x20Luck

After 52 bytes, a similar block seems to start, which we can use to verify the assumptions made so far.

Going back 52 bytes at a time, we arrive at the first block, which starts at offset 0x26C4. Looking it up using the stats and level, it turns out to be Orpheus, which is a good start, since it is the first persona in the first arcana. However, the next persona aren’t sorted by initial level nor arcana. What I did was get a save with all persona in the compendium and looking them up one at a time. The result can be found in an XML file when I release the persona calculator.

Persona in the inventory

We found out that the persona in the compendium are described by a 52 byte structure saved one after another. Looking up the stats of the Dionysus used to find this (Strength, Magic, …) as a hex string in the second save file, we find the string at one other place. Looking around, we can find again blocks of 52 bytes. These blocks repeat for 12 times: the number of persona the protagonist can have at any one time. These blocks start at offset 0x2418. This is the reason for saving the Persona number in the structure; in this way, the inventory can be handled the same way as the Compendium without having to save the compendium as a very sparse array.

Social Links levels

For finding this information, I started by looking at a save game in which all levels are maxed, and marked the value “10” for the maximum level using the “Color Mapping” tool in Hex Workshop. And we find right at the beginning this interesting pattern of 22 times the value 10.

p3_social_links

The social links in the Persona 3 FES save file

22 is a good number – the same number as social links! Now we only need to find out which number is which. The first thing to notice it that there are 8 bytes of value 0 in between the 10s. I was initially unsure of what they were doing there, but after comparing some saved games I got a first hunch that they are connected to the two teams you can choose in the game (sports team and the art club). In fact I was able to verify this using PCSX2’s patch utility in which I got lucky enough to find the locations of the social link levels in the PS2’s memory, which resulted in the finding that the social links are saved in the same structure in memory.

Address in EE RAMAddress in Save FileArcana
8385F6C6Fool
8385F7C7Magician
8385F8C8Unused?
8385F9C9Unused?
8385FACAEmperor
8385FBCBHierophant
8385FCCCLovers
8385FDCDPriestess
8385FECEEmpress
8385FFCFAeon
838600D0Strength
838601D1Justice
838602D2Chariot (Track Team)
838603D3Chariot (Kendo Team)
838604D4Chariot (Swim Team)
838605D5Unused?
838606D6Hermit
838607D7Fortune (Photography Club)
838608D8Fortune (Art Club)
838609D9Fortune (Music Club)
83860ADAUnused?
83860BDBHanged Man
83860CDCDeath
83860DDDTemperance
83860EDEDevil
83860FDFTower
838610E0Star
838611E1Moon
838612E2Sun
838613E3Judgement

Items for special fusions

This one’s tough. Two approaches came to my mind: Find the place where the inventory is saved and check for the items or find out where the requests are saved. The inventory sounded tough (think of weapons with same names and different skill modifiers, which would result in a lot of special codes), so I decided to go for the location of the requests.

The first clue I got was when I compared a save in which no requests had been taken and one in which number 62 had been taken. This resulted in the following change: The value at 0x600C changed from FF FF to 3E 00 – the number of the request. At this position there are two more blocks with FF FF in them – probably the other two blocks are for the other two slots for requests.

I got to the end of this after looking at a save game in which all requests but no. 55 had been completed. This results in the following block, starting at 0x5CC6: FE FF FF FF FF FF 7F FF FF FF FF FF 0F. The thing to note is that in the middle of this block, only one bit is set to 0. We can assume that this is the bit standing for request no. 55. If we count the number of bits set to 1 in this sequence, we count 98: 99 requests – 1 request not yet completed. The correct order to read this is to start at the least significant bit of the first byte. This is always set to 0 – requests start at 1. The order then continues up from the second-to-last-bit to the most significant bit. If we interpret the remaining bytes in that fashion, we see that the bit for #55 is the one set to 0 – we found the requests.

In-game date

The date would be nice to know since only after certain dates advanced fusions become available. Comparing the date when you first get to save with the date of the end of the game, there are 302 days in between. At offset 0x04, we find the value 301 on the last day, so the days starting at the first day of the game (April 7th) are counted.