Skip to content

New extension: Nature Elements#2059

Open
github-actions[bot] wants to merge 1 commit intomainfrom
extension/baldieandbaldie-commits/2058
Open

New extension: Nature Elements#2059
github-actions[bot] wants to merge 1 commit intomainfrom
extension/baldieandbaldie-commits/2058

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Mar 6, 2026

Description

This extension adds wind swaying ability and optional GPU instancing to 3D objects (trees, grass, bushes) with frustum and distance culling.

Image

How to use the extension

How to use:

  1. Import your 3D object (tree, bush, grass...) and add the Foliage swaying behavior to it.

  2. Choose from various object settings and parameters, then add the object to your scene.
    Foliage swaying behavior

  3. Add the Update foliage sway action, choose its parameters, and run it every frame.
    Update foliage sway action

  4. Optionally use the Set wind gust action at the beginning of the scene.
    Set wind gust action

  5. Play your scene.

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.

Example file

NatureElementsDemo.zip

Extension file

NatureElements 1.0.2


Extension by @baldieandbaldie-commits

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 March 6, 2026 20:02
@github-actions github-actions bot added the ✨ New extension A new extension label Mar 6, 2026
@D8H
Copy link
Copy Markdown
Contributor

D8H commented Mar 9, 2026

Thank you for submitting an extension. The result looks impressive.

The code is quite big. Does it come from a library or did you wrote it specifically for this extension?

  • If it comes from a library, you can add a link to its repository to help maintainers update it in the future.
  • If you wrote it specifically for this extension, it would be great to add type annotations ("JSDoc", using notes like @typedef, @param or @type) to at least functions and global variables (or make it a lib if it's more convenient).
    • The editor doesn't remember type declarations set in one JS-event in other JS events, so you may find it easier to have the whole code in one place (for instance the 3D particle emitter extension has a library + dedicated code inside the DefineHelperClasses function)

A few suggestions from a quick look:

  • gdjs should be use as the global scope instead of window or even runtimeScene if it makes sense to reset the state at scene changes.
  • You don't need to surround your code with a function, this is already part of JS-events.
(function (runtimeScene, eventsFunctionContext) {
})(runtimeScene, eventsFunctionContext);

Let me know if this makes sense and if you can make these changes or part of it. This will help update the extension when new GDevelop versions are released.

@4ian
Copy link
Copy Markdown
Collaborator

4ian commented Mar 9, 2026

Tried it and it looks very very cool. It's a big extension but let's see if we can get it inside the experimental extensions!

@baldieandbaldie-commits
Copy link
Copy Markdown

@D8H @4ian Thanks folks. The code was specifically created for this extension. Your comments make a lot of sense. Give me some time and I'll update as much as possible with your comments in mind.

@baldieandbaldie-commits
Copy link
Copy Markdown

!update NatureElements.zip

@github-actions
Copy link
Copy Markdown
Contributor Author

Extension updated with errors:

❌ 1 Error found in extension 'NatureElements':

  ⟶ ❌ [JavaScript disallowed properties]: JavaScript usage of the extension 'NatureElements' 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: '__foliageSway',
  objectName: 'gdjs'
}
{
  allowedProperties: [
    'getVariables',
    'getLayer',
    'getGame',
    'getBackgroundColor',
    'getName',
    'createObject',
    'createObjectsFrom',
    'setBackgroundColor',
    'sceneJustResumed',
    'requestChange',
    'hasLayer',
    'enableDebugDraw'
  ],
  disallowedProperty: 'getTimeManager',
  objectName: 'runtimeScene'
}


❌ 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.

@github-actions github-actions bot force-pushed the extension/baldieandbaldie-commits/2058 branch from 40b91ca to 3133e84 Compare March 21, 2026 16:46
@D8H
Copy link
Copy Markdown
Contributor

D8H commented Mar 28, 2026

Hello, just to make sure, are you waiting for feedback or are you still working on the extension?

@baldieandbaldie-commits
Copy link
Copy Markdown

Hello, just to make sure, are you waiting for feedback or are you still working on the extension?

I've done the refactoring per your comments. Tried updating a few days ago but got an error (again). See here

Currently traveling, but I'll give it another go later today. Got a nice new demo as well.

@D8H
Copy link
Copy Markdown
Contributor

D8H commented Mar 28, 2026

Actually, this is not an error, your update came though, you can see the commit above.
The reviewer will update a file to list which engine features the extension uses.

image

@baldieandbaldie-commits
Copy link
Copy Markdown

baldieandbaldie-commits commented Mar 28, 2026

@D8H awesome! I'll update the demo as well in a bit. It uses the incorrect extension version anyways.

@github-actions github-actions bot force-pushed the extension/baldieandbaldie-commits/2058 branch from 3133e84 to fea1ee3 Compare April 1, 2026 21:32
@4ian
Copy link
Copy Markdown
Collaborator

4ian commented Apr 1, 2026

Again, looks awesome. Give us a few days to see how we can get this in the experimental extensions :)

@baldieandbaldie-commits
Copy link
Copy Markdown

Again, looks awesome. Give us a few days to see how we can get this in the experimental extensions :)

Thanks, @4ian ! I'm in no rush :) Altho I'd love to swap in a better, more custom-tailored demo (example file).

@D8H
Copy link
Copy Markdown
Contributor

D8H commented Apr 2, 2026

This preference has been added recently and it might help you:
image

@baldieandbaldie-commits
Copy link
Copy Markdown

This preference has been added recently and it might help you: image

@D8H Thanks!

@github-actions github-actions bot force-pushed the extension/baldieandbaldie-commits/2058 branch from fea1ee3 to 0d78ceb Compare April 3, 2026 00:14
@baldieandbaldie-commits
Copy link
Copy Markdown

@D8H JS type errors fixed. Updated the extension file.

@4ian
Copy link
Copy Markdown
Collaborator

4ian commented Apr 3, 2026

Is the demo/example file up to date on your first message, or are you working on it separately?

@baldieandbaldie-commits
Copy link
Copy Markdown

baldieandbaldie-commits commented Apr 3, 2026

Is the demo/example file up to date on your first message, or are you working on it separately?

@4ian File was too large to upload via GitHub. I’ll clean it up in the next few days. For now, I updated the demo with a Dropbox link.

EDIT: Got the Demo down to 40 MB but was unable to replace it, getting "failed to upload" error. Dropbox link updated with the smaller file.

@D8H
Copy link
Copy Markdown
Contributor

D8H commented Apr 5, 2026

Some of the variables are typed with Object or any. This won't really help avoiding mistakes or for the autocompletion.
This documentation section should help you to attach your features to gdjs. As you can see in the code block from the doc, class and function are declared locally and added to gdjs at the end. This allows you to get a bit of autocompletion directly and improve it by adding type annotations on the classes and functions declarations.

THREE.TextureLoader shouldn't be used directly because it won't work if the resource name is not a valid path. You can get the Texture of a resource like this:

runtimeScene.getGame().getImageManager().getThreeTexture(resourceName);

Feel free to ask if something is unclear.

@4ian
Copy link
Copy Markdown
Collaborator

4ian commented Apr 5, 2026

For the demo keep it on Dropbox and we'll import it in the GDevelop-examples repository when the time is good.

"Time is good" is a bit vague, but in my mind we should aim for:

  • As much types as possible (though I understand sometimes it feels complicated for nothing... let's try our best).
  • Using runtimeScene.getGame().getImageManager().getThreeTexture (this seems like an important step otherwise we'll get issue with people using this and the object/extension breaking when they rename a resource or change it).

For type annotations, I'm wondering though if we should really do something to allow extension to have "extension wide" types (so that you would get autocompletions in every single code block in the extension). We'll have to think about it...

@baldieandbaldie-commits
Copy link
Copy Markdown

@D8H @4ian Easter feedback... that takes some real dedication 😅 I'll get to it!

@github-actions github-actions bot force-pushed the extension/baldieandbaldie-commits/2058 branch from 0d78ceb to 822dc27 Compare April 6, 2026 17:37
@baldieandbaldie-commits
Copy link
Copy Markdown

@D8H @4ian Extension updated, based on your guidance.

  • Moved the shared helper/runtime code to a gdjs namespace and kept mutable state on runtimeScene, following the extension pattern from the docs
  • Removed the previous direct THREE.TextureLoader path for gust textures and now resolve project textures through GDevelop’s image manager
  • Tightened the JSDoc typing across the shared runtime/state boundaries and replaced broad typing with narrower bridge types where the runtime is dynamic
  • Also cleaned up comments so they match the current architecture
  • And updated JSON and Dropbox Demo

Let me know if this is what you had in mind, and if there's anything else to tackle.

@D8H
Copy link
Copy Markdown
Contributor

D8H commented Apr 7, 2026

I didn’t have much time to check so I just have a few questions:

  • About getBehaviorSafe, what kind of issues lead you to these try-catch?
  • Why do use the unknown type?
  • Is there any reason for not declaring any class in the code?
  • Why do you start the code with ;(function() {?
  • About FoliageRuntimeObjectBridge type, I guess that gdjs.RuntimeObject3D will be easier to understand for maintainers.
  • If you want, you can click on the sentence on top click here to choose objects to pass object to JavaScript instead of eventsFunctionContext.getObjects("Object")

It’s probably not worth sending an updating. I can continue checking the current version.

@baldieandbaldie-commits
Copy link
Copy Markdown

The try-catch was defensive, mostly because the behavior identifier changed during refactors. This can be simplified now.

  • Why do use the unknown type?

Can you let me know if once a behavior property type is defined in the editor, is its runtime JS type guaranteed to match it exactly? If so, I can tighten several unknown types. Used it just as a stricter boundary type while replacing broader any / Object typing.

  • Is there any reason for not declaring any class in the code?

No particular architectural reason. If there is a preferred GDevelop-side convention for classes, I can adapt to it. Let me know.

  • Why do you start the code with ;(function() {?

Simply as a defensive IIFE wrapper. Not strictly required, but felt like a safe pattern. I'll remove it.

  • About FoliageRuntimeObjectBridge type, I guess that gdjs.RuntimeObject3D will be easier to understand for maintainers.

Agreed.

  • If you want, you can click on the sentence on top click here to choose objects to pass object to JavaScript instead of eventsFunctionContext.getObjects("Object")

Somehow I have completely missed this 🙈 Perhaps a call for a UI upgrade? 🙃

It’s probably not worth sending an updating. I can continue checking the current version.

Let me know what else you find, and I'll revise it all at once.

@D8H
Copy link
Copy Markdown
Contributor

D8H commented Apr 8, 2026

To give you a view of what we're trying to do:

  • the first step and my main priority is to make the code easier to navigate for reviewers and maintainers (hence why a lot of my comments related to this)
  • and then we can discuss ways to improve user-friendlyness

This is not necessarily a long process, just explaining my reasoning. I might be able to help doing some changes at some point.

Simply as a defensive IIFE wrapper. Not strictly required, but felt like a safe pattern. I'll remove it.

If you look at the top and the bottom of an empty JS event, you will notice that the code is inside a JS function, it's not the global scope.

Somehow I have completely missed this 🙈 Perhaps a call for a UI upgrade? 🙃

Indeed, it would be better to have a button that actually look like one. It may take a while before we have the time to improve it. On that note, I added 2 sections about object and resource parameters in the doc.

No particular architectural reason. If there is a preferred GDevelop-side convention for classes, I can adapt to it. Let me know.

If you can define classes, it will help me understand which part of the code it related to which data.

Can you let me know if once a behavior property type is defined in the editor, is its runtime JS type guaranteed to match it exactly? If so, I can tighten several unknown types. Used it just as a stricter boundary type while replacing broader any / Object typing.

Most property types are either numbers or strings. Acessing _behaviorData directly may work, but there are getters like _getMyProperty that are more futur proof. Sadly, property names are case sensitive so you may have to rename them to have more readable getter names. You can learn more about them in this section of the documentation.

When I can, I try not to use these getters either. If you take a look at the 3D particle emitter extension, for each property, there are 1 action and 1 expression to access them from the main events. Their skeletons can be generated by the editor as explained at the end of this section.

In this extensions, these couples of functions are used for several purposes:

  • Let extension users change the property values on the fly
  • Initialize the object at creation (by passing the new value to the JS code)
  • Update the object at hot-reload

The good part is that:

  • If the object or behavior initialize correctly, you can expect the actions and hot-reload to also work since they rely on the same thing
  • The property value is passed by the events as a parameter so if one day we need to change how property code is generated, it will continue to work

But, sometimes it's just more convenient to use _getMyProperty(). So it's not a strong rule.

@baldieandbaldie-commits
Copy link
Copy Markdown

@D8H Alright, all of this makes sense. Thanks for sharing the links also. Let me know when it's ok to do a revision - maybe befor you dive in deeper?

@D8H
Copy link
Copy Markdown
Contributor

D8H commented Apr 9, 2026

Yes, if you want to do a good part of the suggestions, I guess it's already quite a lot so I will indeed take a look after your next version.

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

Labels

✨ New extension A new extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants