[Experimental] [3D foliage swaying] Sway foliage of 3D objects according to wind#2059
Conversation
|
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?
A few suggestions from a quick look:
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. |
|
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! |
|
!update NatureElements.zip |
|
Extension updated with errors: |
40b91ca to
3133e84
Compare
|
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 awesome! I'll update the demo as well in a bit. It uses the incorrect extension version anyways. |
3133e84 to
fea1ee3
Compare
|
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 Thanks! |
fea1ee3 to
0d78ceb
Compare
|
@D8H JS type errors fixed. Updated the extension file. |
|
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. |
|
Some of the variables are typed with
runtimeScene.getGame().getImageManager().getThreeTexture(resourceName);Feel free to ask if something is unclear. |
|
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:
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... |
0d78ceb to
822dc27
Compare
|
@D8H @4ian Extension updated, based on your guidance.
Let me know if this is what you had in mind, and if there's anything else to tackle. |
|
I didn’t have much time to check so I just have a few questions:
It’s probably not worth sending an updating. I can continue checking the current version. |
The try-catch was defensive, mostly because the behavior identifier changed during refactors. This can be simplified now.
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.
No particular architectural reason. If there is a preferred GDevelop-side convention for classes, I can adapt to it. Let me know.
Simply as a defensive IIFE wrapper. Not strictly required, but felt like a safe pattern. I'll remove it.
Agreed.
Somehow I have completely missed this 🙈 Perhaps a call for a UI upgrade? 🙃
Let me know what else you find, and I'll revise it all at once. |
|
To give you a view of what we're trying to do:
This is not necessarily a long process, just explaining my reasoning. I might be able to help doing some changes at some point.
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.
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.
If you can define classes, it will help me understand which part of the code it related to which data.
Most property types are either numbers or strings. Acessing 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:
The good part is that:
But, sometimes it's just more convenient to use |
|
@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? |
6a3e9b8 to
a452db3
Compare
|
@D8H sorted hot reload and nitpicks from one of your previous messages. Hot reload now works for non-instanced and instaned objects (to do that, we're keeping one of the original objects that is being instanced in the scene, so the behavior lifecycle can keep reading the updated property values and pass them to the instanced groups). Everything works per my previous message. Did not get to your "Use a life-cycle function to step" comment yet. Updated the extension so you can have a look if something is not to GDevelop standards. |
|
Hello, I didn't look at your changes yet since I wanted to give you back a version as soon as possible. This is the changes I've made:
I hope I didn't break anything. Feel free to improve my changes. I only attached the project file since I haven't change any resource.
|
a452db3 to
0ef65c3
Compare
|
@D8H @4ian
Updating the demo tomorrow... Let me know if there's something else that needs to get done. |
|
I think we're closing in on a first release. I wrote a lot, but this is because I tried to be exhaustive this time.
I have a few questions about the descriptions:
Thanks for your patience and good work. |
|
@D8H Let me first answer some of your questions quickly, and gonna get to everything else in a bit...
|
0d5bd4b to
7ed9c0d
Compare
|
@D8H did a revision per your comments - no more prefixes or abrevations. Fingers crossed that property and group ordering arrives soon 🤞🏻 I also changed internal naming convention to align with your comments. And although it's not user-facing, you mentioned previously that it's important for maintainers to be able to get around, so there it is. As I changed the property names, everything was updated clearly except for the property options (in my case sway types and culling mode values). Not sure if that's a limitation or a bug, soI tweaked it in the original JSON file. Tested it, albeit not as thoroughly, and updated the extension. Will update the demo shortly. Let me know what's next. EDIT: Demo updated as well. |
|
I think the extension is good to go. Congrats for making this great extension!
I made some description changes:
Modified extension: NatureElements.zip |
7ed9c0d to
8252054
Compare
8252054 to
3ad2633
Compare
|
Great stuff! We should be good to ship this, we will mention it in the next update changelog (with some beautiful screenshots) and we should probably think about a lightweight example once this is shipped so more people can discover it from GDevelop itself! :) |
@4ian That's awesome! Let me know if you need help with that. I'd love to assist. |
|
The extension should be in the extension store in a few minutes. Thanks again! |
Let me check that off my bucket list ✅🎉 |
|
The extension looks promising. I tried using it, but I have a few questions. I made this video below showing the behavior on a bush.
2026-05-20.10-55-52.mp4I think you’re quite aware of usability concerns, and it’s really important to have those “How To” guides because, with the current presentation of the extension, I need another resource (this GitHub page) to understand how to use it. The worst part is having to search inside the app without understanding what’s going on. |
|
Don't worry about @Bouh message. We'll discuss it internally and improve some property descriptions if needed on our end. |



Description
This extension adds wind swaying ability and optional GPU instancing to 3D objects (trees, grass, bushes) with frustum and distance culling.
Features:
strength,speed, andwind directionComes with:
How to use the extension:
Import your 3D object (tree, bush, grass...) and add the Foliage swaying behavior to it.
Choose from various object settings and parameters, then add the object to your scene.

Optionally set general wind and gust parameters at the beginning of the scene. If not, default values will be used.

Play your scene.
Current limitations, issues, and guidelins:
Collision is not yet supported for GPU instanced objects but is planned.
The mesh complexity auto-detection (
Polyscaleparameter) is not perfect and can produce inconsistent sway intensity across assets. If you encounter overly strong or weak sways, experiment with thePolyscalevalue to make your asset's sway consistent. Use the debug option to find the auto-selected value, then increase or decrease it.Foliage material auto-detection works well and can usually be left empty, but there are edge cases with multi-material objects. If you don't have access to the source file of your 3D object, you can find your object's material name using the debug option in object's Foliage swaying behavior.
The optional wind gust texture can create natural-looking gusts and is worth creating. If not, one will be automatically created. To make one yourself, use only black and red colors (black will be ignored and red will be the actual gust map). For the best results, create a tileable 512x512 image or download one of the examples below. 01 / 02 / 03 / 04

Hot reload supports all basic behavior property changes, excluding Sway settings (
Material to sway,Sway type,Enable uniform sway toggle) andDistance culling,Debug output,GPU instancing, andCustom PBR settingstoggles. However, if PBR settings are enabled as you start the preview, changes to specific PBR values will be updated on hot-reload.Future nice-to-haves:
PolyScalecompletelyChecklist
Example file
FoliageSwaying3D.zip (1.0.6)
Extension file
FoliageSwaying3D.zip (1.0.6)
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: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!