Most appropriate sub-area of p5.js?
Math
p5.js version
2.x main (4b096e2)
Actual vs expected behavior
The randomSeed() reference promises that a constant seed "makes these functions produce the same results each time a sketch is run", explicitly naming randomGaussian(). That breaks as soon as two p5 instances exist on a page.
randomGaussian() uses the Marsaglia polar method, which produces values in pairs. The flag that says "a spare value is cached" lives on the instance (this._gaussian_previous), but the spare value itself lives in module scope (let y2 = 0; in src/math/random.js). With two instances, B's spare overwrites A's, and A's next call returns B's value.
Executed repro (both instances seeded, one interleaved call on instance B):
A alone : -0.2050, -0.3410, 0.3986, -1.4309
A interleaved: -0.2050, -0.9404, 0.3986, -1.4309
Same seed, different sequence. The existing test suite even contains a skipped "instance mode / should be independent" block asserting exactly this independence. PR #1681 (2015) made _gaussian_previous per-instance but left y2 module-scoped, which is the remaining half of that fix.
Steps to reproduce
Outputs above are from executed runs against main, two instances sharing the prototype as in instance mode.
Note
I have a fix ready (store the spare as this._gaussian_y2) with a regression test, mutation-tested against main. Filing for approval first per the contributing guide; will open the PR once approved.
Most appropriate sub-area of p5.js?
Math
p5.js version
2.x main (4b096e2)
Actual vs expected behavior
The
randomSeed()reference promises that a constant seed "makes these functions produce the same results each time a sketch is run", explicitly namingrandomGaussian(). That breaks as soon as two p5 instances exist on a page.randomGaussian()uses the Marsaglia polar method, which produces values in pairs. The flag that says "a spare value is cached" lives on the instance (this._gaussian_previous), but the spare value itself lives in module scope (let y2 = 0;insrc/math/random.js). With two instances, B's spare overwrites A's, and A's next call returns B's value.Executed repro (both instances seeded, one interleaved call on instance B):
Same seed, different sequence. The existing test suite even contains a skipped "instance mode / should be independent" block asserting exactly this independence. PR #1681 (2015) made
_gaussian_previousper-instance but lefty2module-scoped, which is the remaining half of that fix.Steps to reproduce
Outputs above are from executed runs against main, two instances sharing the prototype as in instance mode.
Note
I have a fix ready (store the spare as
this._gaussian_y2) with a regression test, mutation-tested against main. Filing for approval first per the contributing guide; will open the PR once approved.