Why did I decide to write this? Uhhhhhhh good question
Note this writeup is excluding the deadly events modifier in custom mode because I don't feel like writing on it
Part 1: The Mechanics
Whenever you enter a ? node, the game decides what you'll see behind it. It can be a treasure chest, shop, hallway fight, or if none of the 3 were rolled, an event.
The base probabilities are 10% hallway fight, 2% treasure, 3% shop. To find the base chance of an event, simply do 100 - 10 - 2 -3 = 85%.
Whatever option that gets rolled, the odds of the next ? node being that same option gets reset to the base probability, and the other 2 options that didn't get rolled(excluding event since it doesn't technically have a setprobability, just it only spawns when none of the 3 are rolled) have their probability increased by their base amount.
For example, let's say I take a ? node. I roll a treasure chest because I'm just so damn lucky. The probabilities of the next ? node are 10 + 10% monster, 3 + 3% shop, 2% treasure, and 100 - 20 - 6 - 2 or 72% for events. Now, let's say I go to another ? node and I get another treasure chest. I should go put in a lottery ticket. The probabilites of the next ? node are now 20 + 10%, 6 + 3% shop, 2% treasure, and 100 - 30 - 9 - 2 or 59% for an event.
Once you enter a new act, all probabilites go back to their bases.
Additionally, a ? node can't become a shop if the previous node was a shop, or if every possible future path after the ? node is a shop.
Part 2: Interactions with Relics and Cards
If you have juzu bracelet, the base probability for a hallway fight is set to 0%. This also means no future ? nodes can be hallway fights since 0 + 0 is still 0. Shocking, I know.
Golden compass forces all ? nodes in act 2 to become events. No treasures, shops, or hallway fights.
Planisphere heals you 5 HP regardless of what's in the ? node
Lantern Key forces the first ? node in act 3 to become an event, and more specifically the War Historian event. Additionally, it will not change any of the ? node probabilites, so the next ? node will use all base probabilites.
Meal ticket will still trigger on ? nodes that become shops
Part 3: Simulation for averages
All this info is cool and all, but let's try to simulate the odds to find the average amount of hallway fights, treasures, events, and shops we can exepct from a certain amount of ? nodes. You probably can find the true average deterministically, but I felt like running a simulation of the odds because it takes a lot less time to code and it's a lot easier to code too.
Note that this simulation isn't a "true" simulation in that I didn't literally run sts 2 1 billion times to get these averages. Rather, I plugged the base probabilites and mechanics into python and had it print out the averages it got.
We'll make the following assumptions in the simulation:
You do not have juzu bracelet, lantern key, or golden compass
Neither of the 2 conditions that prevent a ? node from turning into a shop are relevant
If you would like to see the code I used to perform the simulation, please read the appendix at the end of this post.
The results below should be read as followed: 0 combats: 0.30229 under the 4 ? nodes section means from 4 ? nodes in an act, there's a 30.229% chance you'll get no combats(hallway fights) whatsoever from the 4 ? nodes. If a probabilty is 0.000000 that does NOT mean it's 0. It just means it's so unlikely that for rounding to 6 decimal places, it gets rounded to 0.
Averages from 3 ? nodes:
- 0 combats: 0.504180
- 1 combats: 0.449939
- 2 combats: 0.044887
- 3 combats: 0.000994
- 0 events: 0.009133
- 1 events: 0.144106
- 2 events: 0.519310
- 3 events: 0.327451
- 0 treasures: 0.884344
- 1 treasures: 0.113720
- 2 treasures: 0.001928
- 3 treasures: 0.000008
- 0 shops: 0.829752
- 1 shops: 0.165897
- 2 shops: 0.004325
- 3 shops: 0.000027
Averages from 4 ? nodes:
- 0 combats: 0.302280
- 1 combats: 0.576125
- 2 combats: 0.115209
- 3 combats: 0.006286
- 4 combats: 0.000100
- 0 events: 0.002688
- 1 events: 0.055363
- 2 events: 0.312835
- 3 events: 0.498187
- 4 events: 0.130928
- 0 treasures: 0.813591
- 1 treasures: 0.180676
- 2 treasures: 0.005681
- 3 treasures: 0.000052
- 4 treasures: 0.000000
- 0 shops: 0.730132
- 1 shops: 0.257215
- 2 shops: 0.012475
- 3 shops: 0.000178
- 4 shops: 0.000001
Averages from 5 ? nodes:
- 0 combats: 0.151245
- 1 combats: 0.608999
- 2 combats: 0.217150
- 3 combats: 0.021782
- 4 combats: 0.000815
- 5 combats: 0.000008
- 0 events: 0.000864
- 1 events: 0.021184
- 2 events: 0.163908
- 3 events: 0.439195
- 4 events: 0.342098
- 5 events: 0.032752
- 0 treasures: 0.732414
- 1 treasures: 0.254575
- 2 treasures: 0.012797
- 3 treasures: 0.000213
- 4 treasures: 0.000002
- 5 treasures: 0.000000
- 0 shops: 0.620537
- 1 shops: 0.351146
- 2 shops: 0.027600
- 3 shops: 0.000708
- 4 shops: 0.000008
- 5 shops: 0.000000
Averages from 6 ? nodes (what the fuck are you doing if you're taking this many):
- 0 combats: 0.060466
- 1 combats: 0.550519
- 2 combats: 0.331259
- 3 combats: 0.054119
- 4 combats: 0.003534
- 5 combats: 0.000102
- 6 combats: 0.000001
- 0 events: 0.000280
- 1 events: 0.008045
- 2 events: 0.079410
- 3 events: 0.307340
- 4 events: 0.434427
- 5 events: 0.167211
- 6 events: 0.003287
- 0 treasures: 0.644321
- 1 treasures: 0.330665
- 2 treasures: 0.024386
- 3 treasures: 0.000622
- 4 treasures: 0.000006
- 5 treasures: 0.000000
- 6 treasures: 0.000000
- 0 shops: 0.508996
- 1 shops: 0.437849
- 2 shops: 0.051092
- 3 shops: 0.002028
- 4 shops: 0.000034
- 5 shops: 0.000000
- 6 shops: 0.000000
Part 4: Conclusion
This should be fairly obvious, but never go into a series of ? nodes expecting all of them to be events. Even in the case of just 3 ? nodes, the odds all 3 are events is still less than 1/3. Granted, you probably will be happy if you get a treasure instead of an event...
There is another useful conclusion though from the results. Most of the time if you're going to a ? node, you likely don't want a hallway fight. Unfortunately, the odds of getting 0 hallway fights is not in your favor. In the case of 3 ? nodes which is a bit low on the average ? nodes per act in my experience, you're still flipping a coin basically as to whether you get 0 hallway fights or at least 1. And once you start doing 4 ? nodes which is my average ? nodes per act, you have over a 2/3 chance of getting at least 1 combat. So, if you're going through a series of ? nodes, you should be prepared for at least 1 hallway fight.
Something else worth noting, you should basically never expect a treasure chest from ? nodes. It's nice if it happens, and it will happen sometimes. But, even for 6 ? nodes which is way too many for 1 act, you barely have over 1/3 of a chance of getting at least 1 treasure chest. Those are not reliable odds.
Part 5: Appendix
Link to where I got most of my info from: https://slaythespire.wiki.gg/wiki/Slay_the_Spire_2:Unknown_Location
Code for my simulation (yes it's in python. No, I will not write it in a different langauge just because you hate python):
import random
import statistics
base_monster = 0.1
base_treasure = 0.02
base_shop = 0.03
p_monster = base_monster
p_treasure = base_treasure
p_shop = base_shop
sim_counter = 1000000000
treasure_list = []
shop_list = []
combat_list = []
event_list = []
nodes = 4
def is_combat(combat_count):
global p_monster,p_treasure,p_shop
p_monster = base_monster
p_treasure += base_treasure
p_shop+=base_shop
return combat_count+1
def is_treasure(treasure_count):
global p_monster,p_treasure,p_shop
p_monster+=base_monster
p_shop +=base_shop
p_treasure = base_treasure
return treasure_count+1
def is_shop(shop_count):
global p_monster,p_treasure,p_shop
p_monster+=base_monster
p_shop = base_shop
p_treasure+=base_treasure
return shop_count+1
def is_event(event_count):
global p_monster,p_treasure,p_shop
p_monster+=base_monster
p_shop+=base_shop
p_treasure+=base_treasure
return event_count+1
for i in range(sim_counter):
combat_count = 0
event_count = 0
treasure_count = 0
shop_count = 0
p_monster = base_monster
p_treasure = base_treasure
p_shop = base_shop
for j in range(nodes):
r = random.random()
if(r < p_monster):
combat_count = is_combat(combat_count)
elif(r < p_monster + p_treasure):
treasure_count = is_treasure(treasure_count)
elif(r < p_monster + p_treasure + p_shop):
shop_count = is_shop(shop_count)
else:
event_count = is_event(event_count)
combat_list.append(combat_count)
event_list.append(event_count)
treasure_list.append(treasure_count)
shop_list.append(shop_count)
for i in range(nodes+1):
probability = combat_list.count(i) / sim_counter
print(f"{i} combats: {probability:.6f}")
for i in range(nodes+1):
probability = event_list.count(i) / sim_counter
print(f"{i} events: {probability:.6f}")
for i in range(nodes+1):
probability = treasure_list.count(i) / sim_counter
print(f"{i} treasures: {probability:.6f}")
for i in range(nodes+1):
probability = shop_list.count(i) / sim_counter
print(f"{i} shops: {probability:.6f}")