Hello everyone!
My goal was to create a system, where you just need to fill in all possible encounters of a zone and the associated probabilities. The system automatically works with any number of encounters. In this tutorial, I take Pokémon as inspiration, but it also works for games in the style of older Final Fantasy titles.
Most of the information you will find in the comments of the project. It was created with C3, but the code should be fully compatible with C2. Use the free C3 Editor to view the project -> editor.construct.net
Get the .c3p:
So let’s start!
I used a Tiled Background as “EncounterZone”. As long as the player is overlapping that zone, there is a chance to meet an encounter. The chance of triggering an encounter, a list of all possible encounters and the chance for each encounter are saved in 3 instance variables.
EncounterZone.Chance
The chance to trigger an encounter. In my project I generate a random number between 0 and 100 after each step. So an EncounterZone.Chance of 20 would be synonymous with a 20% chance of triggering an encounter.
EncounterZone.EncounterID
A list of all possible encounter for this zone, separated by a separator. I used “;” as separator (see system expressions -> tokenat(), tokencount()). I suggest to give every encounter an ID and use the IDs for this list.
EncounterZone.EncounterChance
A list of all chances for each encounter in EncounterZone.EncounterID, separated by a separator. Make sure that the same number of tokens are listed here as in the EncounterID. The first value in EncounterChance is assigned to the first value in EncounterID and so on. It is not necessary to sort the values by size. It is not even necessary that the sum of all values is 10, 100 or 1000 (simplified for 100%). But I recommend using one of these values to identify all chances at a glance.
Example:
According to this example the chances to meet…
001 -> 40%
004 -> 5%
005 -> 15%
008 -> 20%
010 -> 20%
When triggering an encounter, the first step is to calculate the sum of all tokens in EncounterChance (ChanceSum) and create a list with the range of each chance (ChanceList). We also need a random number between 0 and the calculated sum (Dice). We use a ‘Repeat’-Loop to achieve this.
A fourth variable is needed to store the calculated encounter (Encounter).
ATTENTION: Make sure to use local variables and uncheck ‘Static’ and ‘Constant’. This will reset the variables after the function has finished.
ChanceSum
The calculation should be obvious. Each loop pass add the next token:
40 + 5 + 15 + 20 + 20 = 100 (100%)
ChanceList is calculated like this:
Loop 1. pass: ChanceSum = 40 -> add 40 (and “;”) to ChanceList -> 40;
Loop 2. pass: ChanceSum = 45 -> add 45 (and “;”) to ChanceList -> 40;45;
Loop 3. pass: ChanceSum = 60 -> add 60 (and “;”) to ChanceList -> 40;45;60;
Loop 4. pass: ChanceSum = 80 -> add 80 (and “;”) to ChanceList -> 40;45;60;80;
Loop 5. pass: ChanceSum = 100 -> add 100 to ChanceList -> 40;45;60;80;100
ChanceList has the value “40;45;60;80;100”. It can be interpreted as a chance-range for each encounter:
0 to 40 = Encounter 001
40 to 45 = Encounter 004
45 to 60 = Encounter 005
60 to 80 = Encounter 008
80 to 100 = Encounter 010
(because we later use ‘>=’, it is not exactly ‘0 to 40’ but ‘0 to 39,9999...’)
Which encounter appears is determined by the random value Dice.
If Dice has the value 61, encounter 008 appears because 61 is between 60 and 80. To check this we use a “While”-loop that compares each token in ChanceList with Dice until Dice is greater than the token:
(assume Dice has the value 61, Encounter starts with 0)
Loop 1. pass: 61 >= 40? Yes! Add 1 to “Encounter” (= 1)
Loop 2. pass: 61 >= 45? Yes! Add 1 to “Encounter” (= 2)
Loop 3. pass: 61 >= 60? Yes! Add 1 to “Encounter” (= 3)
Loop 4. pass: 61 >= 80? No! “Encounter” remains 3
Index number 3 in EncounterZone.EncounterID (0-based index!) is ID 008. So the encounter with the ID 008 appears! Save this value so it can be accessed globally. I used an instance variable with a dictionary.
Done! This system is super easy and, much more important, scalable! In a modified form you also can use it to generate random drops from enemies. But this is a story for another tutorial :)
Best regards and have fun
André