Skip to content
This repository was archived by the owner on Sep 23, 2025. It is now read-only.
This repository was archived by the owner on Sep 23, 2025. It is now read-only.

Random increment math #114

@JesseBuesking

Description

@JesseBuesking

I was just looking through the code and saw your comments for the random incrementing logic where you say you'd like to "do this mathematically...".

A Linear formula:

If you want to follow a similar formula going forward, I think that a simple application of the slope-intercept to decrease the increment linearly would probably be fine. Given you want to start with a maximum increment of 6.0% and end up with an increment of 0.5%, you could use the following:

function maxIncrement(stat) {
  var x1=0,
      y1=6.0,
      x2=99,
      y2=0.5,
      b=0, // intercept
      m=0; // slope
  m = (y1-y2)/(x1-x2);
  b = y1-(m*x1);
  // return the y-value from the formula y = m * x + b
  return m*stat+b;
}

Which gives the following values:

maxIncrement(0)
> 6
maxIncrement(1)
> 5.944444444444445
maxIncrement(2)
> 5.888888888888889
...
maxIncrement(97)
> 0.6111111111111116
maxIncrement(98)
> 0.5555555555555562
maxIncrement(99)
> 0.5

That function is a bit verbose when we leave all the math inside, but you could simplify it as follows:

function maxIncrement(stat) {
  return (5.5/-99)*stat+(6.0);
}

Now, your code actually uses the value we're finding above as the maximum threshold, where you choose a random value between 0 and the maximum. To re-enable this logic, we can create another method to handle it as follows:

function incrementer(stat) {
  var m = maxIncrement(stat);
  return (Math.random() * m) / 100;
}

Last, we still need to handle the case greater than or equal to 99%. Here's what it would be in it's final form:

if (stat >= 0.99) {
  rnd = 0;
} else {
  rnd = incrementer(stat);
}

To visualize all of this a bit better, check out what it looks like on Wolfram Alpha.

linear

Using the image above, we're picking an x value (stat) and finding the y value represented by the blue sloping line. This value becomes our upper bound. We then choose a random value between [0, 1) using Math.random(), and multiply to get a new value somewhere between 0 and our upper bound.

Everything together:

function maxIncrement(stat) {
  return (5.5/-99)*stat+(6.0);
}
function incrementer(stat) {
  var m = maxIncrement(stat);
  return (Math.random() * m) / 100;
}
if (stat >= 0.99) {
  rnd = 0;
} else {
  rnd = incrementer(stat);
}

Obviously there's no need to keep those all as method calls, so feel free to inline things as you see fit.

Note: I deviated from your logic slightly in that you don't choose a random multiplier when stat >= 0.9 && stat < 0.99, whereas I do.

A Non-Linear formula:

If you're looking for something non-linear like an exponential decay, take a look at this Wolfram Alpha. The only adjustment to the formula above would be:

function maxIncrement(stat) {
  return 6.0*Math.exp(-5.0*(stat/100));
}

Which gives the following values:

maxIncrement(0)
> 6
maxIncrement(1)
> 5.707376547004284
maxIncrement(2)
> 5.4290245082157575
...
maxIncrement(97)
> 0.046970265295354655
maxIncrement(98)
> 0.04467949842554603
maxIncrement(99)
> 0.042500453574312716

You can see that compared to the linear formula this slows down much more rapidly and has a longer tail.

non-linear

Sorry for the long post, this ended up growing more rapidly than I had originally anticipated.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions