Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[p5.js 2.0 RFC Proposal]: RNG algorithm change #7017

Open
2 of 21 tasks
limzykenneth opened this issue May 4, 2024 · 2 comments
Open
2 of 21 tasks

[p5.js 2.0 RFC Proposal]: RNG algorithm change #7017

limzykenneth opened this issue May 4, 2024 · 2 comments

Comments

@limzykenneth
Copy link
Member

Increasing access

xorshift128+ have a better overall randomness and speed as compared to the currently used LCG, although the speed aspect has been mostly observed in RNG implemented in other languages so it is harder to determine how well it will translate to JavaScript. This change can help avoid some of the potential pitfalls with LCG that some users has observed before.

Which types of changes would be made?

  • Breaking change (Add-on libraries or sketches will work differently even if their code stays the same.)
  • Systemic change (Many features or contributor workflows will be affected.)
  • Overdue change (Modifications will be made that have been desirable for a long time.)
  • Unsure (The community can help to determine the type of change.)

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

What's the problem?

There is not a significant problem to solve with this proposal, the main aim is to use the same RNG algorithm as the browser's own Math.random() implementation.

What's the solution?

Seeded random number generator (RNG) will use xorshift128+. The current algorithm for RNG used in p5.js is an version of a Linear Congruential Generator (LCG).

The main reasoning for this change is for performance. xorshift128+ performs better than LCG and it is the internal implementation of most of the current major browsers for Math.random(). The random property of xorshift128+ is similar if not better than LCG.

This will be a breaking change as existing seeded RNG will not give the same random number sequence once the algoritm has switched to use xorshift128+. Consideration can be made to create a compatibility addon library that patch seeded RNG to use the old LCG RNG if necessary.

Example implementation of a xorshift128+ backed RNG with compatible API to p5.js can be found here.

Pros (updated based on community comments)

  • Potentially better randomness and performance for seeded RNG

Cons (updated based on community comments)

This is a fairly minor change although still in effect a breaking change since it will change the sequence of numbers returned by a seeded random number generator as well as seeded noise. This will only affect seeded RNG, unseeded ones uses Math.random() which is not seeded.

Proposal status

Under review

@mattdesl
Copy link
Contributor

mattdesl commented May 15, 2024

Another implementation (much smaller and perhaps faster), MIT license.
https://gist.github.com/mattdesl/43893dec295d4d2cba75438c0027830a

I think a change to PRNG should ideally be considered with how the seed is set as well. In my case I chose djb2 to hash the seed string into 128 bits. For some projects I have even exposed the raw 128 bit seed getter/setter to my gen art programs, for example when I want to encode the random state in as few bits as possible into a file.

@limzykenneth
Copy link
Member Author

@mattdesl Thanks for sharing. The current implementation of randomSeed() only accepts a number, I can see hashing can be a good way to enable string to be used as seed as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Proposal
Development

No branches or pull requests

2 participants