Skip to content

This contains an Rproject consisting of a D&D Death Saving simulation study for OSU's ST 541 course.

Notifications You must be signed in to change notification settings

amyly2145/OSU_2022_PCS_DeathSaves

Repository files navigation

---
output: github_document
---

<!-- README.md is generated from README.Rmd. Please edit that file -->

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(tidyverse)
library(miceadds)
```

# PCS Project

<!-- badges: start -->
<!-- badges: end -->

## Background:

Dungeons and Dragons (D&D) is a popular roleplaying game where players utilize dice to help make decisions in battles and completing skill checks. Die rolls comes in various forms, from 2 sided to 100-sided dice. 

When characters reaches 0 health points (HP), they fall unconscious and become incapacitated. In addition, they must make death saves, which is a special kind of roll to determine if you character will die. 

On their turns, players must roll a 20-sided die (d20) for the death save against a Difficulty Class (DC) of 10. 

The original rules for death saving throws are as followed: 

* If a roll is 10 or higher (and not a 20), it is considered a success
* If a roll is less than 10 (and not 1), it is considered a failure.

If players succeed 3 times, the character is stabilized with 0 HP but stays unconscious. If players failed 3 times, the character dies. Additionally, the following rolls are special:

* If a natural 20 is rolled, the character stabilizes, gains 1 HP, and regains consciousness. 
* If a natural 1 is rolled, it is considered as failed 2 death saves. 

Successes and failure do not need to be consecutive. At most, players would roll a maximum of 5 times. 

## Problem Scenario

Now what happens if players gain advantage when rolling death saving throws? 

An advantage allows you to roll 2x20-sided die (2d20) and then the player accepts the higher roll result. Conversely, a disadvantage forces the player to take the lower roll result.

If the gamemaster running the D&D campaign wants to customize the rules and let players have advantage or disadvantage when they perform death saving throws, will this break the balance of the game? 

With the original rules, players have about 59.5% chance of survival. 

What are chances of survival in the following scenarios:

* Allowed an advantage after at least 1 success
* Allowed an advantage after at least 1 failure
* Allowed an advantage after at least X number of successes
* Allowed an advantage after at least X number of failures
* Allowed an advantage for the entirety
* Given a disadvantage after at least 1 failure
* Given a disadvantage after at least X number of failures
* What happens if you increase the number of rolls given in advantage and disadvantage?

# Using the Functions

There are several functions used in this project to calculate the probability of survival.

## `mod_roll()`

This function will modify the roll based on the chosen rule, listed below:

* Original: Roll only once
* Advantage: Roll a number of times and choose the higher of the rolls
* Disadvantage: Roll a number of times and choose the lesser of the rolls

Inputs:

* rule [char]: "original", "advantage", or "disadvantage"
* roll_time [int]: number of times that players can roll before choosing the higher or lesser of the rolls when playing with custom rules

Output: 

* roll [int]: a number

## `roll()`

This function will simulate the roll based on several inputs. 

Inputs:

* saves [int]: the number of successes or fails required before survival result is evaluated
* rule [char]: "original", "advantage", or "disadvantage"
* status [int]: a threshold number of success or fails before players can gain advantage or disadvantage.
* reason [char]: set "success" or "fail" to be the threshold for judging status
* roll_time [int]: number of times that players can roll before choosing the higher or lesser of the rolls when playing with custom rules 

Output:

* survive [int]: 1 if the player has the required number of successes first or 0 if the player has the required number of fails first. 

## `result()`

This function assess whether the current roll is a success or fail (and how many successes or fails) based on the following thresholds. 

* Roll a 1: 2 fails
* Roll 2 - 9: 1 fail
* Roll 10 - 19: success
* Roll 20: 3 successes

Input:

* roll [int]: a number randomly generated by a 20-sided die

Possible outputs [char]: 

* success
* fail
* c(success, success, success)
* c(fail, fail)


## `survival_prob()`

This function will simulate B number of rolls and return the estimated survival probability and its standard deviation. 

Inputs:

* saves [int]: the number of successes or fails required before survival result is evaluated
* B [int]: the desired number of simulated die rolls to make
* rule [char]: "original", "advantage", or "disadvantage"
* status [int]: a threshold number of success or fails before players can gain advantage or disadvantage.
* reason [char]: set "success" or "fail" to be the threshold for judging status
* roll_time [int]: number of times that players can roll before choosing the higher or lesser of the rolls when playing with custom rules

Output [list]: 

* prob [num]: estimated survival probability
* sd [num]: standard deviation for the estimated survival probability


The source folder contains several R scripts that were used to generate examples and perform the simulation study. 

## Example

The scenario of interest is: 

* 3 successful death saves are required for a character to survive.
* The death save dice roll will be simulated 1000 times.
* Play with original rules, where there is no advantage or disadvantage.
* Since original rules are being played with, there is no threshold based on success or fail before the gamemaster can give out advantage/disadvantage
* Since original rules are being played with, players can only ever roll at most once. 

```{r}
# source all files within the Function folder containing the string '.R'
library(miceadds) 
source.all("./R", ".R" )

set.seed(123)

survival_prob <- function(saves, B, rule, status, reason, roll_time){
  
  samp <- rerun(B, roll(saves, rule, status, reason, roll_time))
  prob <- mean(unlist(samp))
  sd <- sd(unlist(samp))
  return(list(prob = prob, sd = sd))
}


survival_prob(3, 1000, "original", 0, "fail", 1)

```

Users should expect to see the following results: 

$prob
[1] 0.606

$sd
[1] 0.4888793

# Source

Users will see several scripts that were created for the simulation study. Each script was created for specific scenarios. For example: 

* Advantage_Plots evaluates what happens when you vary the status and saves variables when you change the reason for threshold to "success" or "fail" for giving players advantage.
* Advantage_Rolltimes_Plots evaluates what happens when you vary the status, saves, and roll_time variables when you change the reason for threshold to "success" or "fail" for giving players advantage.
* Disadvantage_Plots evaluates what happens when you vary the status and saves variables when you change the reason for threshold to "success" or "fail" for giving players disadvantage.
* Disadvantage_Rolltimes_Plots evaluates what happens when you vary the status, saves, and roll_time variables when you change the reason for threshold to "success" or "fail" for giving players disadvantage.
* Original_Compare_Plot compares what happens between rules as you vary the number of saves. 
* Dice_Distribution compares the histogram of dice numbers between different rules. 

All plot results are saved in the Results/Plots folder. 


About

This contains an Rproject consisting of a D&D Death Saving simulation study for OSU's ST 541 course.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages