Skip to content

New extension: Pseudo random #1645

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Apr 5, 2025

Description

Set seed to generate pseudo-random numbers in sub-events.

This extension will be useful for:

  • Re-creating a randomly generated level.
  • Debugging everything related to randomness in your game.
  • Use in multiplayer so that all players have the same random event without having to synchronize its components.

How to use the extension

How to use:

  • Put the action "Set seed" with a specific seed in the form of a number, for example "1", then all expressions and conditions of randomness in subevents will give the same result (each expression and condition separately) until you change the seed, meaning the expressions Random(), RandomInRange, RandomFloat() etc. and the condition "Pick a random instance".

Example:

  1. Create a new event with the condition "At the beginning of the scene" and the action "Set seed" and the seed equal to "1".
  2. Create a sub-event with the action "Log message" and the message "ToString(Random(100))+";"+ToString(Random(100))+";"+ToString(Random(100))".
  3. Look in the console and you will see that the result at each restart will be equal to "17;21;53" until you change the seed.

Checklist

  • I've followed all of the best practices.
  • I confirm that this extension can be integrated to this GitHub repository, distributed and MIT licensed.
  • I am aware that the extension may be updated by anyone, and do not need my explicit consent to do so.

What tier of review do you aim for your extension?

Community (Unreviewed)

Example file

PseudoRandomExample.zip

Extension file

PseudoRandomExtension.zip


Extension by @Jurfix

You can update the extension on this "Pull Request" by commenting the update command: in the comment field, type !update, then drag and drop a zip file with your extension file in the commenting field, like how you initially submitted the extension. It should look like this:

!update [MyExtension.zip](https://github.com/GDevelopApp/GDevelop-extensions/files/12709661/MyExtension.zip)

It can take a few seconds for the file to fully upload and show as the above. Once it is like shown above, click "Comment" and let the bot do the rest!

@github-actions github-actions bot requested a review from a team as a code owner April 5, 2025 22:32
@github-actions github-actions bot added the ✨ New extension A new extension label Apr 5, 2025
@D8H
Copy link
Contributor

D8H commented Apr 6, 2025

Thank you for submitting an extension.

Extensions are meant to be editable by anyone. This means that:

  • JavasScript code must not be minified (unless there is a technical reason)
  • A link to the repository or topic must be included if any

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

github-actions bot commented Apr 6, 2025

✅ Successfully updated the extension.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

Hi Davy @D8H, I replaced the minified library code with the non-minified one and added the repository link to the extension description, thanks.

@D8H
Copy link
Contributor

D8H commented Apr 6, 2025

  • The link to the repository should be in a JS or event comment not in the description.
  • Overriding Math function may lead to unexpected side effects. For instance, particle emitters or pitch randomization may use Math.rand. If VFX and SFX are disabled, could it mess with the reproducibility of the game run?

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

  • Overriding function may lead to unexpected side effects. For instance, particle emitters or pitch randomization may use . If VFX and SFX are disabled, could it mess with the reproducibility of the game run?Math``Math.rand

The Math.random() function is overridden only in the visibility zone after calling seedrandom(), that is, in the event where it is called and in subevents, in the rest of the game Math.random() works as before (randomly), usually I use it only once when starting a scene to build a level and the rest of the game works as before.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

If VFX and SFX are disabled, could it mess with the reproducibility of the game run?

I didn't quite understand the question, but neither the sound reproduction nor the creation of particle emitters affected the game's reproductive ability.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

github-actions bot commented Apr 6, 2025

❗ No updates found. Please check your file.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

github-actions bot commented Apr 6, 2025

❗ No updates found. Please check your file.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

github-actions bot commented Apr 6, 2025

✅ Successfully updated the extension.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 6, 2025

I moved the repository link from the description to the js comment

@Jurfix
Copy link
Contributor

Jurfix commented Apr 7, 2025

Hi Davy @D8H, I updated the example by adding random value generation next to pseudo random values, this can also be combined into one event if necessary, but then it will be unclear when which sound plays
PseudoRandomExample.zip

@Jurfix
Copy link
Contributor

Jurfix commented Apr 7, 2025

Yes, it can break certain processes in your game if you call "set seed" for the whole scene or the whole game, but you can easily control it by calling it only in one event (for example when starting a scene), that's why I set the extension category to "advanced", maybe a warning should be added, what do you think?

@D8H
Copy link
Contributor

D8H commented Apr 21, 2025

What do you do to enable it only for 1 event and its sub-events?

@Jurfix
Copy link
Contributor

Jurfix commented Apr 21, 2025

Just call the set seed function, in the event where it is called there will be a pseudo random, in all other events there will be a regular random

@D8H
Copy link
Contributor

D8H commented Apr 21, 2025

How does the extension make it works?

@Jurfix
Copy link
Contributor

Jurfix commented Apr 21, 2025

!update PseudoRandom.zip

Copy link
Contributor Author

Can't update the extension, as it doesn't pass automatic tests:


❌ 4 Errors found in extension 'PseudoRandom':

  ⟶ ❌ [Filled out names and descriptions]: Required field 'fullName' of the function 'BackRandom' is not filled out!
  ⟶ ❌ [Filled out names and descriptions]: Required field 'description' of the function 'BackRandom' is not filled out!
  ⟶ ❌ [Filled out names and descriptions]: Required field 'sentence' of the function 'BackRandom' is not filled out!
  ⟶ ❌ [JavaScript disallowed properties]: Found disallowed properties in extension 'PseudoRandom':
{
  allowedProperties: [
    'makeUuid',           'rgbToHex',
    'rgbOrHexToRGBColor', 'rgbToHexNumber',
    'hexNumberToRGB',     'hexToRGBColor',
    'copyArray',          'staticArray',
    'staticArray2',       'staticObject',
    'toDegrees',          'toRad',
    'random',             'randomFloat',
    'randomFloatInRange', 'randomInRange',
    'randomWithStep',     'evtTools',
    'Variable',           'RuntimeObject',
    'Logger'
  ],
  disallowedProperty: '__PseudoRandomExtensionOriginalRandomFunction',
  objectName: 'gdjs'
}


❌ 4 Errors found in extensions - please fix them before generating the registry.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 21, 2025

I was wrong, it overrides the Math.random() function globally, not just in the event and sub-event, it seemed to me that this is because gdevelop itself returns the Math.random() function to its original form after some time (about a second).
I added an action that overrides Math.random() to its original form forcibly, which must be called when the generation of values ​​is complete, I have not spent time on the design of all this yet, I just want to know if this is a normal solution and whether it solves your concerns before I design it as needed, thanks.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 21, 2025

To make this work only on one event and its sub-events, it should look like this:
image

@D8H
Copy link
Contributor

D8H commented Apr 21, 2025

I have not spent time on the design of all this yet, I just want to know if this is a normal solution and whether it solves your concerns before I design it as needed, thanks.

I would be more at ease with functions like NumberGenerator::Random() that don't have any side effect on standard libraries.

@Jurfix
Copy link
Contributor

Jurfix commented Apr 21, 2025

NumberGenerator::Random()

Then it won't be so clean, for each generation of one number you will need to have a unique seed, that is, each time after calling the generation you will have to add 1 to the seed, in my opinion this is extra work, if you use it as I showed in the last message, then there should be no side effects, since Math.random returns to its original form in the same frame

@D8H D8H added the ⌨ JavaScript Uses JavaScript code, and thereby needs a reviewer who knows JavaScript. label May 3, 2025
@Jurfix
Copy link
Contributor

Jurfix commented Jun 23, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

Can't update the extension, as it doesn't pass automatic tests:


❌ 1 Error found in extension 'PseudoRandom':

  ⟶ ❌ [JavaScript disallowed properties]: Found disallowed properties in extension 'PseudoRandom':
{
  allowedProperties: [
    'makeUuid',           'rgbToHex',
    'rgbOrHexToRGBColor', 'rgbToHexNumber',
    'hexNumberToRGB',     'hexToRGBColor',
    'copyArray',          'staticArray',
    'staticArray2',       'staticObject',
    'toDegrees',          'toRad',
    'random',             'randomFloat',
    'randomFloatInRange', 'randomInRange',
    'randomWithStep',     'evtTools',
    'Variable',           'RuntimeObject',
    'Logger'
  ],
  disallowedProperty: '_PseudoRandom',
  objectName: 'gdjs'
}


❌ 1 Error found in extensions - please fix it before generating the registry.

@Jurfix
Copy link
Contributor

Jurfix commented Jun 23, 2025

Hi @D8H , I updated the extension by removing the global override of Math.random() and replacing it with a local copy, and also added 5 expressions identical to the built-in random, only with pseudo random.
It works identically to the previous version, except that now you need to call expressions from the extension PseudoRandom::Random(), ... instead of the built-in ones.
I think this is a very useful and widely used thing, so I still expect to see it in this repository, thanks.

@Jurfix
Copy link
Contributor

Jurfix commented Jun 28, 2025

Updated example if needed, but everything should be intuitive, you don't even have to call "Set seed" if you don't call it then the default seed will be 1, and each call to the expression will return the next step of the randomness
PseudoRandomExample.zip

@D8H D8H mentioned this pull request Jun 28, 2025
3 tasks
@D8H
Copy link
Contributor

D8H commented Jun 28, 2025

The feature from this other PR could be integrated into your extension:

It will add a new NormalRandom function that uses your pseudo Random function. I can add it at the end of the review if you want.

This Godot class has the same kind of features if you want to take some ideas from it:
https://docs.godotengine.org/en/stable/classes/class_randomnumbergenerator.html

@Jurfix
Copy link
Contributor

Jurfix commented Jun 28, 2025

Hi, it seems Godot calls all generations pseudo-random because numbers will never be truly random unless the generator depends on external factors such as nature.
This extension is made for generating pseudo-random numbers that can be reproduced, not for pseudo-random numbers like random in GDevelop.
You are right that in Godot there is a possibility to reproduce number generations, but in Gaussian distribution pseudo-random numbers are created not because they can be reproduced, but because we explicitly interfere with their generation by tweaking the probabilities.
I hope I got my point across correctly, NormalRandom is a useful function, but it should not exist only in a reproduced form.

@D8H
Copy link
Contributor

D8H commented Jun 28, 2025

You are right that in Godot there is a possibility to reproduce number generations, but in Gaussian distribution pseudo-random numbers are created not because they can be reproduced, but because we explicitly interfere with their generation by tweaking the probabilities.

I don’t see why the normal distributed random should not be made reproducible. In Godot, it’s the RandomNumberGenerator.randfn function.

@Jurfix
Copy link
Contributor

Jurfix commented Jun 28, 2025

I don't fully understand how this is implemented in Godot, but as far as I understand you have a choice to reproduce randomness or not, you want to add a normal distributed random function to this extension, does this mean that it should always be reproducible unless you use a timestamp as a seed? Will there be a non-reproducible analogue? For example, now there are 5 expressions of reproducible randomness in the extension and 5 similar expressions of non-reproducible randomness are built into the engine

@Jurfix
Copy link
Contributor

Jurfix commented Jun 29, 2025

You can add a normal distributed random function if you want, I just don't fully understand how it will look.

@D8H
Copy link
Contributor

D8H commented Jun 29, 2025

I can add it at some point, it will just add a small function that relies on your random function. If someone uses your extension without knowing that the randomness is reproducible or what it means, they won't save the seed nor the state and it will just be common randomness to them.

By the way, how can users:

  • restart a run with the exact same seed
  • load a save and generate the same numbers every time they load it back

Is the seed generated at the start to avoid users to be confused by always getting the same series (unless they set the seed of course)?

@Jurfix
Copy link
Contributor

Jurfix commented Jun 29, 2025

After calling set seed, the series will be restarted, this means that if you specify the same seed, you will get the same values ​​every restart.
The initial seed is not generated, this is easily done by setting it to timestamp for example, do you think this is necessary?

@D8H
Copy link
Contributor

D8H commented Jun 29, 2025

After calling set seed, the series will be restarted, this means that if you specify the same seed, you will get the same values ​​every restart.

What about starting back from a save where N numbers have already been generated and you want the next number without calling the random function N times to skip them?

The initial seed is not generated, this is easily done by setting it to timestamp for example, do you think this is necessary?

Yes, I think it will be more user-friendly to generate a seed.

@Jurfix
Copy link
Contributor

Jurfix commented Jun 29, 2025

What about starting back from a save where N numbers have already been generated and you want the next number without calling the random function N times to skip them?

So far this is not implemented, I see that the library has the ability to save and restore states, I can add this, it will complicate the extension a little, but nothing, what do you think is better to use the built-in ability to save / restore, which is an object with the parameters of the current random, or is it better to make your own restoration based on iterations, for example through a loop that will be called n times?

@Jurfix
Copy link
Contributor

Jurfix commented Jun 30, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

Can't update the extension, as it doesn't pass automatic tests:


❌ 4 Errors found in extension 'PseudoRandom':

  ⟶ ❌ (🔧) [Dots in sentences]: Field 'fullName' of the function 'GetSeed' has a dot, but it is forbidden there!
  ⟶ ❌ [JavaScript disallowed properties]: Found disallowed properties in extension 'PseudoRandom':
{
  allowedProperties: [
    'makeUuid',           'rgbToHex',
    'rgbOrHexToRGBColor', 'rgbToHexNumber',
    'hexNumberToRGB',     'hexToRGBColor',
    'copyArray',          'staticArray',
    'staticArray2',       'staticObject',
    'toDegrees',          'toRad',
    'random',             'randomFloat',
    'randomFloatInRange', 'randomInRange',
    'randomWithStep',     'evtTools',
    'Variable',           'RuntimeObject',
    'Logger'
  ],
  disallowedProperty: '__PseudoRandomExtension',
  objectName: 'gdjs'
}
  ⟶ ❌ [No 'Get' in expressions]: Expression 'GetStep' is using prohibited 'Get' prefix!
  ⟶ ❌ [No 'Get' in expressions]: Expression 'GetSeed' is using prohibited 'Get' prefix!


❌ 4 Errors found in extensions - please fix them before generating the registry.

@Jurfix
Copy link
Contributor

Jurfix commented Jun 30, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

Can't update the extension, as it doesn't pass automatic tests:


❌ 1 Error found in extension 'PseudoRandom':

  ⟶ ❌ [JavaScript disallowed properties]: Found disallowed properties in extension 'PseudoRandom':
{
  allowedProperties: [
    'makeUuid',           'rgbToHex',
    'rgbOrHexToRGBColor', 'rgbToHexNumber',
    'hexNumberToRGB',     'hexToRGBColor',
    'copyArray',          'staticArray',
    'staticArray2',       'staticObject',
    'toDegrees',          'toRad',
    'random',             'randomFloat',
    'randomFloatInRange', 'randomInRange',
    'randomWithStep',     'evtTools',
    'Variable',           'RuntimeObject',
    'Logger'
  ],
  disallowedProperty: '__PseudoRandomExtension',
  objectName: 'gdjs'
}


❌ 1 Error found in extensions - please fix it before generating the registry.

@Jurfix
Copy link
Contributor

Jurfix commented Jun 30, 2025

Hi, I decided to make my own implementation of saving and restoring state since the built-in solution returns a large data object that will be difficult for a regular gdevelop user to understand, I decided to call it "Step" instead of "State", I'm not sure if this is correct, and also about the wording of the descriptions, it should be pretty simple now, you can specify the step from which the generation should start in the "Set seed" action, I also added an expression that returns the last step, you can even specify this expression in the "Set seed" action to continue generation from another part of the game without having to declare a variable for this.
Also the initial seed is now generated based on the timestamp, unless you set your own of course, I also added an expression that returns the last seed.

@D8H
Copy link
Contributor

D8H commented Aug 9, 2025

Hello Jurfix, the bot has been fixed, you should now be able to update the extension. It will be easier for me to follow the changes you do.

@Jurfix
Copy link
Contributor

Jurfix commented Aug 12, 2025

!update PseudoRandomExtension.zip

Copy link
Contributor Author

Extension updated with errors:

❌ 1 Error found in extension 'PseudoRandom':

  ⟶ ❌ [JavaScript disallowed properties]: JavaScript usage of the extension 'PseudoRandom' must be checked by the reviewer:
{
  allowedProperties: [
    'makeUuid',
    'rgbToHex',
    'rgbOrHexToRGBColor',
    'rgbToHexNumber',
    'hexNumberToRGB',
    'hexToRGBColor',
    'rgbOrHexStringToNumber',
    'hexNumberToRGBArray',
    'copyArray',
    'staticArray',
    'staticArray2',
    'staticObject',
    'toDegrees',
    'toRad',
    'random',
    'randomFloat',
    'randomFloatInRange',
    'randomInRange',
    'randomWithStep',
    'evtTools',
    'Variable',
    'RuntimeObject',
    'Logger'
  ],
  disallowedProperty: '__PseudoRandomExtension',
  objectName: 'gdjs'
}


❌ 1 Error found in extensions - please fix it before generating the registry.
No fatal error found the extension can be updated but still need fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⌨ JavaScript Uses JavaScript code, and thereby needs a reviewer who knows JavaScript. ✨ New extension A new extension
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants