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, , with the number of persona being
. The set of Persona the user has in his/her possession at the moment will be denoted by
. If we define
to be an invalid result in a fusion, we can define a function
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 to form the next set,
. When the number of Persona in the sets doesn’t increase, we have found the maximal set of fusable Persona:
. The figure below illustrates this.
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.