Skip to content

[p5.js 2.0+ Bug Report]: randomGaussian() leaks its spare value across p5 instances, breaking seeded determinism #9130

Description

@rajanpanth

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions