Advanced player behavior
Refine player behavior so crafting choices respond to collection progress and item rarity. Warning Our modeled player doesn’t change in response to the system.
In the last section, we introduced simple player behavior to improve the accuracy of our model. However, when we run a Forecast…


… we observe that some of the rarity lines exceed 100%. This is because the player is still trying to craft cards of those rarities, even though they already own them all.
Our modeled player doesn’t change in response to the system, whereas real players should.
In reality, as the player collects more cards of a certain rarity, they should be less inclined to craft more cards of that rarity. This is because there are fewer uncollected ones left to choose from.
In technical terms, this means the probability of choosing to craft a card of rarity x is a function of how many cards of rarity x they already own. For example, if the player had no preference at all for what card to craft, but they owned 90% of the Epics and only 10% of the Legendaries, we would expect them to be 9x more likely to want a Legendary than an Epic.
To model this, we will use a similar technique to the one used in Part 4 to calculate the chance of a card being a Duplicate:
Currently, the relative odds of choosing a certain rarity is simply:
weight = p
where weight is what we define on the Gate output, and p is the fixed value we chose originally
In reality, the odds should be defined as:
weight = p * pcntCardsUncollected/100
where pcntCardsUncollected is the percentage of cards of the given rarity that the player hasn’t collected yet
Since we already have a Register calculating the percentage of cards that have been collected, we can use it to calculate the opposite. This gives us the final equation:
weight = p * (1-pcntCardsCollected/100)
With this, we can create a new Register which calculates the dynamic weight. For example, for Rares, we’ve chosen a base weight (i.e. p value) of 10:


In the picture, the register New Weight (Rare) has the formula 10 * (1 - share / 100), where share is the value of the % Collected Rare register, passed in by the state connection. This formula means that when the player has no cards of that rarity (i.e. when pcntCardsCollected=0), the weight is equal to the original value we gave it (p). But as more cards are collected, the weight decreases, down to 0 when all cards are collected.
The fact that we still have a p value in the formula (i.e. an inherent preference) means that, even when the player has no cards whatsoever, they are still more likely to craft higher-rarity cards.
After overwriting each weight with the Registers’ values, we can observe in Play mode how the weights change over time.
As expected, the player will always be unlikely to craft Commons, and much more likely to craft the others. Over time, the weights become disproportionately in favor of Epics and Legendaries, because the player completes the Common and Rare card pools much faster.
Using Forecasts, we can observe the result this has had on the time to complete the collection:


We’ve now prevented the player from crafting cards they don’t need, while also bringing their decision-making process closer to those of actual players. For this particular case, this is all the intelligence our player needs.
Remember: the goal of modeling a system is to be correct enough, not to recreate it perfectly. The more detail we add, the more time we might waste, and the more likely we are to make bad assumptions about players.