Talk:Seed Maker

From Stardew Valley Wiki
Revision as of 02:23, 3 September 2024 by Margotbean (talk | contribs) (Comment from User:Mr Qi caught in mass edit filter)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
This talk page is for discussing Seed Maker.
  • Sign and date your posts by typing four tildes (~~~~).
  • Put new text below old text.
  • Be polite.
  • Assume good faith.
  • Don't delete discussions.

On the seed maker probabilities and the corrections to prevent PRNG exploits

This discussion page was created in an attempt to prevent subsequent confused edits of the Seed Maker PRNG probabilities.

Seed maker probabilities

Note about the mathematical notations

 

  • A range denoted by [x, y] means "from x, included, to y, included", while a range denoted by [x, y[ means "from x, included, to y, not included". This singularity is relevant since the latter notation is used in the pseudocode, to better reflect the original code (and the way C# handles random number generation).
  • An overline over numerals is called a vinculum, and is used to denote repeating digits.

The code, from 1.5.4, translated in pseudocode (to avoid copyright infringement), with lines relevant to the Seed Maker output highlighted, is as follows:

1 Get PRNG initialized with: In-game days played, unique ID for that game, seed maker location (X), seed maker location (Y), in-game time of day. *All the random numbers in the rest of this pseudocode are from this PRNG*
2 Generate new "seeds" object of the correct seeds type (for the object initially inserted in the maker) with an integer random quantity in [1, 4[.
3 If the `performObjectDropInAction` was called with `probe == true`, return true.
4 Get a float number (in [0, 1[), if that number is in [0, 0.005[, replace the seeds object from (2) by one "Ancient Seeds".
5 If the float number from (4) is in [0.005, 1[, get a second float number (in [0, 1[), if that new number is in [0, 0.02[, replace the seeds object from (2) by "Mixed Seeds" with an integer random quantity in [1, 5[.
6 Set the action delay to 20 in-game minutes.
7 Play the sound "Ship".
8 Set the sound "DirtyHit" to be played after 250ms.
9 Return true.

As one can see from this pseudocode, there are three events:

  1. Generation of the "correct" seeds with a random quantity (step 2).
  2. Probabilistic event of replacing the seeds with "Ancient Seeds" (step 4).
  3. Probabilistic event of replacing the seeds with "Mixed Seeds" (step 5).

The first event is always happening, and is the "default outcome" should no probability-dependent event happen.

The second and third events are probabilistic events, therefore it is important to determine if they are dependent or independent, and if they are mutually exclusive.

Event dependency

Because the PRNG shall be assumed to make the random numbers as independent as possible, the values are not related in any meaningful way, and so, the probabilistic events are independent.

Event mutual exclusion

The fact that the second event only occurs depending on the outcome of the first does not make the values dependent, but it makes the events mutually exclusive (the second event cannot occur at the same time as the first).

Probabilities computation

Let P(x) be the probability of any x.

Let A be the variable name for the first probabilistic event.

Let B be the variable name for the second probabilistic event.

Let D be the variable name for the default event.

B is only evaluated if A does not happen, so B is only evaluated if ¬A (not A).

Therefore, the outcome of the Seed Maker is:

  • Ancient Seeds (A): A
  • Mixed Seeds (B): ¬A ⋂ B (not A and B)
  • Seeds of the original input (D): ¬A ⋂ ¬B (not A and not B)

Since the events are, as we have determined, independent, P(x ⋂ y) = P(x) * P(y).

Therefore:

  • P(A) = 0.0049 (from the source code)
  • P(¬A) = 1 - P(A) = 0.995
  • P(B) = 0.019 (from the source code)
  • P(¬B) = 1 - P(B) = 0.98
  • P(¬A ⋂ B) = P(¬A) * P(B) = 0.995 * 0.019 = 0.0199
  • P(¬A ⋂ ¬B) = P(¬A) * P(¬B) = 0.995 * 0.98 = 0.9751

Outcome

As we can see from the computation, here are the following probabilities:

  • Ancient Seeds (A): 0.0049
  • Mixed Seeds (B): 0.0199
  • Seeds of the original input (D): 0.9751

Corrections to prevent exploits

According to the 16:43, 22 May 2024‎ edit of the Seed Maker page:

“Seed Maker output exploits were removed in 1.6. I'm not sure if they were kept in with Legacy RNG though, that will have to be tested later.”
User314159

I do not readily have access to the source of the game for any version newer than 1.5.4, so I cannot confirm this with the source code; but I can confirm that the behavior in the game from the version 1.6.8 is inconsistent with this statement. It is indeed still very possible to reproduce the output of the Seed Maker on a given day, given location, and given time. I tried several times, it worked every single time, perfectly.

In order for the "reloading exploit" to be mitigated, the PRNG seeding would have to be done with the introduction of an externally changing variable (such as the current "real world" time, or a modulo thereof, etc).

Without this, said exploit will always consistently work. --Mr Qi (talk) 20:52, 2 September 2, 2024