Persona 3 Calculator: Approach

This post will show the basic, unoptimized approach I took to the Persona calculator. The basic idea behind it is to try to combine all Persona in the repertoire of the user and repeat this until no more new Persona can be constructed. At the same time, for each fusion, the Persona used are saved along with the result to be able to figure out in the end how to get to the required Persona.

Checking if and how a certain Persona (like my Horus) can be created from the Personas currently in the user’s possession then amounts to checking if the Persona is included in the list of Persona which have been created via the fusions. If it is present, then one needs to recursively resolve all ingredient Persona used for the target Persona until all ingredients are already in the player’s possession. If it is not present, the Persona can’t be created, for example due to the player not having the required Persona in the first place or (possibly) the fusion formulas being off…

More mathematically speaking, we have the full set of Persona possible in the game, \mathbb{P}, with the number of persona being |\mathbb{P}| = 169. The set of Persona the user has in his/her possession at the moment will be denoted by \mathbb{P}_{0} \subseteq \mathbb{P}. If we define 0 to be an invalid result in a fusion, we can define a function f_{\mbox{normal}}: \mathbb{P} \times \mathbb{P} \rightarrow \mathbb{P} \cup \{ 0 \} which maps tuples of persona to their fusion result (either another persona or the invalid persona), based on the rules of normal spread fusion.

The approach is now to combine all Persona in a set \mathbb{P}_{k-1} to form the next set, \mathbb{P}_{k} = \{x : x = f_{\mbox{normal}}(p_{a}, p_{b}) \mbox{for all} p_{a}, p_{b} \in \mathbb{P}_{k-1} \}. When the number of Persona in the sets doesn’t increase, we have found the maximal set of fusable Persona: |\mathbb{P}_{k-1}| = |\mathbb{P}_{k}|\Rightarrow \mathbb{P}_{k} = \mathbb{P}_{\mbox{max}} . The figure below illustrates this.

personasets2

Here is the the corresponding source code from the unoptimized version:

List<FusedPersonaList> lists = new List<FusedPersonaList>();

// Initialize from the user's currently owned Persona
lists.Add(UserDB.GetList());

while (true) {
    int lastCount = lists.Last().Count;
    // Create the set of Persona which can be created from the list from
    // the last step.
    FusedPersonaList newList = lists.Last().CreateNewList(Database, UserDB);
    int currentCount = newList.Count;

    // If the number of Persona has not increased, stop looping.
    if (lastCount == currentCount) {
        break;
    } else {
        lists.Add(newList);
    }
}

After the loop, the last item of the list is the list with all Persona which can be fused. The implementation of the fusions themselves is straightforward when following the rules for fusions.

This is the main way how persona are created by the tool. There are some more restrictions which are checked, among them if the items for some special fusions are owned by the player or if the corresponding social link has been maxed. Also there are special persona which have to be fused from more than 3 other persona. They are just checked each time the set of persona is combined with itself to check if the ingredient persona can be found.