Technocyte Stabby Simulation

Author

ViciousTeletuby28

Published

March 23, 2025

Introduction

The goal of this code is to simulate the process of acquiring the Coda weapons in the game Warframe.

This process has random elements in them, and it is of interest to determine the distribution of the number of missions required to complete a vanquishing cycle. Given further inputs, the time distribution required can also be determined. Once the distributions are determined, it is straightforward to summarise it into understood quantities such as expected values and quantiles.

The basic points to note are than every mission run grants 5% progress regardless of success, and that to ‘win’ one must reach at least 100% progress and complete a final mission after that.

Potency mods can increase progress gain, but to apply potency mods one must have encounters. Encounters have a base 25% chance of occurring in a mission. However, every mission completed without an encounter increases the probability of an encounter on the next mission by 25%.

Optimal strategy

For this exercise we will assume the use of optimal strategy. Using sub-optimal strategies will extend the process slightly, but might be worthwhile in special cases.

The optimal strategy is to first test 3 antivirus mods, then if not successful another 3, if still not successful the last 2 and a 15% potency mod. At any point after first success the optimal strategy is to equip the correct antivirus mod and 2 15% potency mods (unless so close to 100% such that lower potency is needed and could provide benefits, but this does not affect the calculations at first).

Code
find_encounter <- function() {
  cnt <- 1
  while (runif(1) > (cnt*0.25)) {
    cnt <- cnt + 1
  }
  cnt
}

run_optimal_strat <- function(potency = c(15, 15)) {
  runs <- find_encounter()
  progress <- runs*5
  found_mod <- runif(1) <= 3/8
  if (!found_mod) {
    try2 <- find_encounter()
    runs <- runs + try2
    progress <- progress + try2*5
    found_mod <- runif(1) <= 3/5
    if (!found_mod) {
      try3 <- find_encounter()
      runs <- runs + try3
      progress <- progress + try3*5 + potency[2]
    }
  }
  while (progress < 100) {
    normal_run <- find_encounter()
    runs <- runs + normal_run
    progress <- progress + sum(potency) + normal_run*5
  }
  runs
}

Simulation study

Now we run the process a large number of times and summarise the results.

The results here are reported without the final encounter. Remember to add the time of the final encounter to calculations.

Code
n_sims <- prod(9:13)*10
sims <- replicate(n_sims, run_optimal_strat())

The expected number of missions is 9.2721491 and 95% of acquisitions will take 12 or less missions.

Time per acquisition

Let us assume that 95% of missions typically take 4.5 to 6.5 minutes (including travel time), plus 15 minutes for the final dance and other necessary interactions. This is the most subjective and debatable aspect of this document, everything else is objective. Changing this assumption will impact the results a bit.

Code
time_sims <- sims*rnorm(length(sims), 5.5, 0.5) + 15

The proportion of acquisitions in the 50 to 80 minutes bracket is 0.849, with an average of 66 minutes.

Total acquisition

With 13 items in total to collect, assuming 1 of each is bought at a cost of 10, and a uniform(10, 15) reward per full acquisition, we can calculate the total time expected to collect them all.

First we calculate the cumulative probability of achieving a full collection in 9 to 13 full runs:

Code
possible_total_runs <- 9:13
acq_dist <- sapply(possible_total_runs, \(r) {
  replicate(n_sims, sum(ceiling(runif(r, 9, 15))) >= 130) |> mean()
})
acq_mass <- diff(c(0, acq_dist))
Total_runs Cumulative_Probability Probability_Mass
9 0.00019 0.00019
10 0.20456 0.20437
11 0.92071 0.71615
12 0.99988 0.07918
13 1.00000 0.00012

The total time is then obtained by taking a weighted average of the time distributions given the total runs, using the probability mass as weight.

Code
acq_total_time <- lapply(possible_total_runs, \(r) {
  time_sims |> matrix(r) |> colSums()
})
acq_total_time_comb <- (seq_len(5) |> sapply(\(i) {
  sample(acq_total_time[[i]], ceiling(acq_mass[i]*100000))
}) |> unlist())/60

Thus the expected total time (in hours) spent acquiring a full set of coda weapons under the mission time assumption is 12, and the full distribution is:

Adding time to get initial set of mods

As long as trading is an option then obtaining the necessary mods is a deterministic process of doing about 9 bounties. Given the same mission time distribution, and adding this to the previous results gives:

Code
n_times <- length(acq_total_time_comb)
final_comb_time <- acq_total_time_comb + 
  (rnorm(n_times*9, 5.5, 0.5)/60) |> matrix(9) |> colSums()

So the bulk of players will complete their collections in the 12 to 16 hours range, proportion: 0.835.

This time can be brought down slightly by micromanaging potency mod selection when approaching 100% each time; however, this micromanagement itself takes time, partially cancelling out the benefits.

Alternative visualisations of final result: