Previous week was simulation of level progression of NPC adventurers. The logical continuation is to pit such generated characters against dungeons, and run simulations for the outcome.

Dungeons: A Series of Challenges

The Tomb Of Horrors.

The Haunted Graveyard.

The Forgotten Crypt.

The Lair of the Werewolf King.

All these are locations where adventures take place, and typically adventurers slay lots of monsters and acquire treasure and artifacts. Since we're still at a high level of abstraction, instead of creating dungeons and placing monsters, we can simulate the outcome in a simpler way, as a series of challenges:

Adventurer walks in, faces a skill test (e.g. how good is the two-handed skill) or a skill category test (e.g. how good are the combat skills on average), takes damage based on the test result (which is a scalar rather than a bool) and heals a bit. If the test passes, adventurer gains XP and proceeds to next challenge.

A dungeon is configured for a such coarse simulations as follows:

  • Number of challenges: How many challenges should adventurers succeed in to complete the dungeon.
  • Challenge rating:  The difficulty of the dungeon, in terms of character level.
  • Skill Challenge Pool: The skills that can be tested against, if the challenge is skill-based.
  • Skill Category Challenge Pool: The skill categories that can be tested against, if the challenge is category-based.
  • Skill Challenge Chance: The chance of encountering a skill-based challenge rather than a category-based one.

The two challenge pools (skill and skill category) contain subsets of skills/categories, each with a specified DC (difficulty class) modifier as compared to the average for the CR (challenge rating) of the dungeon.  So for example a dungeon could have particularly hard lockpicking tests, or very easy combat.

Adventurers can have their personal "retreat threshold" (aka bravery), so some will flee if their health is below 20%, others when it's below 5%, others never.

The simulation goes as follows in pseudocode:

for each encounter:
    calculate challenge rating # progressively harder
    calculate test mastery level base
    
    test_type = weighted select skill or category
    if test_type == category:
        sample category # from the list of categories that we can test for this dungeon
        adjust test mastery level 
        run skill check against adventurer's average skill level
        calculate success and apply damage
    elif test_type == skill:
        sample skill # from the list of skills that we can test for this dungeon
        adjust test mastery level 
        run skill check against adventurer's skill level
        calculate success and apply damage
    
    if adventurer.dead():
        return status::Death
    else:
        if success:
            adventurer.awardxp( challenge_rating )
        else:
            flag encounter for retry
        adventurer.heal_some()

        if adventurer.health_critical():
            return status::Retreat

return status::Success

For simulation purposes, mana acts as a "mana shield"; when mana is available it can be utilized to block off damage at half effectiveness, e.g. at 100 damage, 48 mana left => 24 damage absorbed, mana goes to zero, adventurer takes 76 damage.

I developed two tests to see the simulation in action, single-delve and lifetime-delve

Single-delve tests

These tests take single adventurers and put them against a single dungeon. Run enough tests at all potential character levels, and we can get an idea of survivability rates at different levels. All characters are generated using the level-up strategies from the previous post.  Below are a few graphs that show the success/retreat/death per adventurer level by varying the general cautiousness of adventurers (CR mod), the number of challenges of the dungeon and their retreat threshold.

Here is a GIF with all graphs, to avoid flooding the page, as there are many many combinations (first retreat value varies, then challenges, then CR mod):

Lifetime-delve tests

These tests take single adventurers, starting from level 1 and put them continuously against dungeons until they die or reach level 30. The adventurers pick a dungeon level compared to their level, using a CR modifier (-5 is easier dungeons, up to 0, as above is suicide given the previous graphs). Here is a GIF again with all graphs, much less data this time, so easier to follow: ( retreat varies first, then challenges)

Next time, party time

Clearly the survivability rates are not great, especially at higher levels. So, as it is natural, parties can and will form, as there is strength in unity. The party simulation will not be too complicated, and should give a reasonable boost to survivability esp. at higher levels.

Finally there's another wild idea. These simulation results can be exported to JSON, so that when AI has to make choices about which dungeons to tackle, it will use the graph results. The more the AI knows about a dungeon (CR, encounter num, etc), the more accurate the survivability percentage it will be, utilizing rumors, dungeon lore skills, etc. So, it can make a more informed decision.

Another fun idea is to try to use something like tracery (or a home-brewed adaptation) to generate "adventure stories".