# Calculator:Perks

## Contents

## How to use[edit source]

Click on components from the right panel to add them to the slots inside the gizmo shell in the same order as in-game: middle, top, left, right, bottom (additionally, top-left, top-right, bottom-left, bottom-right if using an ancient gizmo). Alternatively, you can drag them into specific spots in the gizmo shell. You can also drag and drop components between slots inside the gizmo. Drag & drop functionality is available on supported modern browsers. You cannot use ancient gizmo exclusive components in a normal gizmo shell.

Clicking on a slot inside the gizmo shell removes the component from that slot. After filling the slots, enter your Invention level and the type of gizmo shell to use (weapon, armour, or tool), whether you're using an ancient gizmo, and optionally a potion (you could also manually enter your boosted level instead, including above 120). Press Submit to generate the results. The results displayed are the probabilities of getting a perk combination in the gizmo shell with the components you selected.

By default the displayed probabilities are "per gizmo consumed". By enabling the 'show no effect' checkbox, it will also display probabilities "per make gizmo click", where the chance of failing to make a gizmo is displayed. When you fail to make a gizmo the shell and materials are not consumed.

You can quickly clear all of the slots on the gizmo shell by pressing the "Reset slots" button.

If you notice anything wrong, let us know on our Discord server and we'll sort it out ASAP.

## Calculator[edit source]

## FAQs[edit source]

### Does position of components matter?[edit source]

Yes, because of the sorting algorithm that is used. If there are ties in the "value" of ranked perks, then the order of materials can influence how those ties are broken, and sometimes what the top available perks are.

### Why do some chances of getting a perk become lower at higher Invention levels?[edit source]

Essentially, this is because you roll high enough values (see #Perk generation section) that you have a lower chance of getting a specific perk/perk rank. However, in most cases you'll have a higher chance of getting a specific perk with another perk at a higher Invention level, compared to just getting the perk on its own. For example, Scavenging 3 by itself is more common at level 120 than 137 (boosted from 120 with an extreme invention), but getting any perk combo with Scavenging 3 is more common at 137.

In some cases, having a high Invention level can even prevent you from getting certain perks.

### The in-game interface says I can get a perk from a set of components, but it isn't shown in the calculator. Is it broken?[edit source]

In most cases, you're probably using the wrong gizmo type in our calculator.

For specific perk ranks, it is known that the game can overestimate the maximum rank that you can get from a set of components. For example, using 2 connector parts, 2 smooth parts, and 1 precious component in a gizmo shell shows that you can get Scavenging 1-3, but you can only actually get up to Scavenging 2 with that combination.

Another possible reason is that in some cases, as mentioned above, the positioning of components can impact what perks you get. Try switching component placement around in the calculator to see if your desired perk appears for a specific combination.

## Perk generation[edit source]

Perks are generated in a fairly complex manner.

*In the following code,*`random(x, y)`

generates an integer between x and y-1, inclusive of both.`floor(x)`

rounds down x to the nearest integer.

First, some background data. Each material has a selection of perks it can give, and each of those perks have two associated numbers - a fixed part (`base`

) and a random part (`roll`

). These numbers differ between materials for the same perks, for example for the Precise perk, Precise components have a base of 9 and a roll of 32; Armadyl components have a base of 44 and a roll of 8. Ancient components are exclusive to ancient gizmos and cannot be used in normal gizmo shells (these have the value of `_isAncient`

set to `true`

in our code). When we use a material other than ancient components inside of an ancient gizmo, the aforementioned `base`

and `roll`

values for that material's possible perks are multiplied by 80%.

Additionally, each perk has a number of ranks, and each rank has two associated numbers - a rank threshold (`threshold`

), and a rank value (`cost`

). For example, the Precise perk has thresholds 50, 80, 130, 170, 210, and values 35, 65, 120, 160, 195, corresponding to each of the 5 ranks.

- Generate the
`invent budget`

. This is calculated by summing 5 rolls of`random(0, floor(invention level / 2) + 20)`

(that means 5 separate random rolls; includes boosts to Invention level). If using an ancient gizmo, an additional roll (a total of 6) is performed.- If
`invent budget`

is below your Invention level, set it to your Invention level.

- If
- Calculate the
`perk values`

for each perk that can be generated by the input materials. Keep track of perks available in an array; add this to the array in order of the materials, iterating the slots in order middle, top, left, right, bottom (along with top-left, top-right, bottom-left, and bottom-right if using an ancient gizmo). This is done by calculating`base + random(0, roll)`

for each material and each perk, summing the values if multiple materials use the same perk. - Calculate the rank generated by finding the largest
`rank threshold`

that the corresponding`perk value`

is greater than or equal to. If the`perk value`

is less than the lowest`rank threshold`

for a given perk, then set the rank to 0 with a cost of 0. These perks cannot be generated, however must still be included at this point as it affects the operation of the following sorting algorithm. - Sort the perks in ascending order of
`rank cost`

(lowest value first) using a modified quicksort algorithm (see below). - For each perk in the sorted
`perk values`

, in reverse order:- If the current
`invent budget`

is less than or equal to the`rank cost`

, move on to the next perk. - If
`invent budget`

is strictly greater than the`rank cost`

, this perk-rank combination is generated. Subtract the`rank cost`

from`invent budget`

and continue to the next perk with the new`invent budget`

.

- If the current
- Once you have generated 2 perks, or ran out of perks to check, we are done.
- If either one of the perks generated was a two-slot perk (Enhanced Devoted or Enhanced Efficient), set the second perk generated to nothing.
- If you generated no perks, the gizmo shell and the materials are not consumed.

- Sorting

Sorting of the perk array by `rank cost`

is done by a modified quicksort algorithm. How this sort breaks ties is extremely important and slight differences in the method can make massive differences in what perks are generated. This is also why the array is sorted into ascending order then iterated backwards, rather than sorted into descending order and iterated forwards.

It is easier to provide an implementation of the sort than describe it - since it is mostly quicksort, you can see the above linked wikipedia page for it. Here is a javascript implementation of the sort, as is used by the above calculator.

Show sorting code |
---|

```
/**
* Sorts an array in-place
* compare(x,y) should be a function that returns a positive number if x>y, a negative number if x<y, and 0 if x=y - the easiest way to do that is return x-y
*/
function quicksort(low, high, arr, compare) {
var pivot_index = (~~((low + high)/2)); // floor division
var pivot_value = arr[pivot_index];
arr[pivot_index] = arr[high];
arr[high] = pivot_value;
var counter = low;
var loop_index = low;
while (loop_index < high) {
if (compare(arr[loop_index], pivot_value) < (loop_index & 1)) {
var tmp = arr[loop_index];
arr[loop_index] = arr[counter];
arr[counter] = tmp;
counter = counter + 1;
}
loop_index = loop_index + 1;
}
arr[high] = arr[counter];
arr[counter] = pivot_value;
if (low < (counter - 1)) {
quicksort(low, counter - 1, arr, compare);
}
if ((counter + 1) < high) {
quicksort(counter + 1, high, arr, compare);
}
}
// example use
var perkArr = [
{'perk': 'Cautious', 'cost': 0, 'probability': 0.0019369834710743802, 'rank': 0},
{'perk': 'Blunted', 'cost': 0, 'probability': 0.00021947873799725651, 'rank': 0},
{'perk': 'Equilibrium', 'cost': 0, 'probability': 0.11297548487631127, 'rank': 0},
{'perk': 'Precise', 'cost': 65, 'probability': 0.00510406494140625, 'rank': 2},
{'perk': 'Flanking', 'cost': 0, 'probability': 0.013885498046875, 'rank': 0}
];
quicksort(0, (perkArr.length - 1), perkArr, function (x, y) { return x.cost - y.cost });
// sorts into order Blunted, Equilibrium, Flanking, Cautious, Precise
``` |

The most notable line is the comparison - `compare(arr[loop_index], pivot_value) < (loop_index & 1)`

. In the game code, the comparison alternates with loop_index between `< 0`

and `<= 0`

, which we emulate by the bitwise AND (`loop_index % 2`

has the same effect) to make the comparison `< 0`

and `< 1`

.

- Calculator code

The full code of this calculator is available at MediaWiki:Gadget-perkcalc-core.js. For the full material and perk data (thresholds, ranks, etc), see MediaWiki:Gadget-perkcalc-data.js.