Skip to content

Add support for ordering For Each by an expression, with optional limit #8319

Merged
4ian merged 13 commits intomasterfrom
claude/for-each-ordering-xeMPO
Feb 25, 2026
Merged

Add support for ordering For Each by an expression, with optional limit #8319
4ian merged 13 commits intomasterfrom
claude/for-each-ordering-xeMPO

Conversation

@4ian
Copy link
Owner

@4ian 4ian commented Feb 24, 2026

This can look a bit complex but very useful for picking instances in a specific order (and without relying on unique identifiers).
By default, a For Each will stay in "any order".

Todo:

  • Change the expression which is 0 by default?
  • Probably (another PR?) ensure the Diagnostic Manager is also checking expressions from events (not just parameters like now)
  • Ensure the UI is as streamlined and understandable as possible
  • Fix the icon button to remove the limit
image image image

claude and others added 12 commits February 24, 2026 12:31
Adds optional ordering and limiting to ForEach events:
- orderBy: an expression evaluated for each instance to determine sort order
- order: "asc" (default) or "desc" direction for iteration
- limit: optional expression for max iterations (e.g., limit=1 picks highest/lowest)

Changes:
- Core C++ (ForEachEvent.h/.cpp): new fields with serialization
- GDevelop.js bindings: expose getters/setters for orderBy, order, limit
- GDJS codegen: sorting phase evaluates expression per instance, sorts indices,
  applies limit, then iterates in order. Unordered path unchanged.
- UI (ForEachEvent.js): select between "(any order)" and "ordered by" with
  expression field, asc/desc selector, and optional limit
- TextRenderer: display ordering info in text representation
- Tests: 12 integration tests covering simple/nested ForEach, orderBy with
  asc/desc, limits (1, 2, none), local variables, loop index, and groups

https://claude.ai/code/session_01LXTeNz7ehNS5TqFYSU6aw5
Replace numeric accumulation (ModVarScene) with string concatenation
(ModVarSceneTxt) in all orderBy/limit tests to make the exact iteration
order and values visible in the assertion. This makes test failures much
easier to diagnose since the full trace is a readable string like
"10;20;30;50;" rather than a single sum.

Also add gdjs.evtTools.common.toString to the GDJS mock so that
ToString() expressions work in code-generation integration tests.

https://claude.ai/code/session_01LXTeNz7ehNS5TqFYSU6aw5
…povers

- Replace the single monolithic ordering popover with a cleaner design:
  - "ordered by" / "(any order)" is now an inline <select> styled as
    text with a subtle grey dropdown arrow
  - "ascending" / "descending" is also an inline <select> with the same
    style
  - The orderBy expression opens its own dedicated popover with an
    ExpressionField
  - The limit opens its own dedicated popover with an ExpressionField
    and a cross icon button to remove it
- Put limit inside the parenthesis next to the direction:
  "(ascending, no limit)" or "(ascending, limit: 3)"
- Add "Add Ordering" / "Remove Ordering" context menu items for
  ForEach events, next to "Remove the Loop Counter Variable"
- Also add "Ordering" to the "Add" submenu for ForEach events

https://claude.ai/code/session_01LXTeNz7ehNS5TqFYSU6aw5
- Add orderBy and limit expressions (type "number") to
  ForEachEvent::GetAllExpressionsWithMetadata so refactoring propagates
  to them.
- Expose GetOrderByExpression/GetLimitExpression in C++ header, IDL
  bindings, and JS types for expression validation.
- Show red underlines (instructionInvalidParameter) on invalid orderBy
  and limit expressions in the ForEachEvent renderer, matching the
  RepeatEvent pattern. Empty limit is treated as valid.
- Replace cursor:pointer on inline selects with the "selectable" CSS
  class for consistent styling.

https://claude.ai/code/session_01LXTeNz7ehNS5TqFYSU6aw5
@4ian 4ian changed the title Add support for ordering For Each by an expression, with optional limit and Add support for ordering For Each by an expression, with optional limit Feb 25, 2026
@4ian 4ian merged commit dc62aea into master Feb 25, 2026
6 checks passed
NBForgeLab added a commit to NBForgeLab/GDevelop that referenced this pull request Feb 28, 2026
* Send context of the conversation to improve AI asset search

* Add a short description for all extensions and dimension field (2D, 3D, 2D/3D or n/a) (4ian#8303)

Only show in developer changelog

* Add missing support for short description/dimension

Don't show in changelog

* Fix being able to rename a layer with shortcut (4ian#8309)

* Fix opening the 3D editor not working after launching a preview first on the web (4ian#8310)

* Fix property group wrongly set when dragging a folder to the root (4ian#8312)

* Fix handling of instance/locked variables (4ian#8311)

- Removed the + button that was wrongly shown to add an instance variable (instance variables can only "override" the values of the variables defined in the object)
- Fix paste/delete a child of structure/array of a variable that is re-defined in instances variables. Previously it was not possible to paste a variable as a child of a instance variable that was a structure/array. This is now possible (and fully supported - you can't add new variables at the root, but items inside structures/arrays can be changed).

* Fix properties sometimes missing or duplicated when grouped in columns (4ian#8313)

* Fix keyboard shortcuts (copy/cut/paste/delete/undo/redo) not working when editing variables

* Replace old search bar by compact search bar in scene editor panels (4ian#8317)

* Improve robustness of AI events generation and asset swapping

* [Auto PR] Update translations (4ian#8304)

This updates the translations by downloading them from Crowdin and
compiling them for usage by the app.

Please double check the values in
`newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are
sensible.

Co-authored-by: 4ian <[email protected]>

* Add support for ordering For Each by an expression, with optional limit  (4ian#8319)

- For advanced use cases where it's important to run events on each instance of an object with an ordering, the For Each can now have an ordering: an expression can be written and will be evaluated for each instance separately. The For Each will then execute for each instance in the order of the result of the expression.
- It's possible to change the direction (ascending or descending)
- It's also possible to give a limit (for example, 1 will allow to pick just the instance with the highest/lowest value for the expression).
- Examples are provided in the UI for common use cases (maximum value of a variable, health points, ammo, distance to another object...)

* Update cordova config for new xcode/ios versions (4ian#8321)

Only show in developer changelog

* Fix tileset scrollbar area changing selection (4ian#8324)

Fix 4ian#8316

* Improve details of center/origin when an object is created by the AI (4ian#8322)

* Add a simplified version of the Anchor behavior editor (4ian#8325)

* [Auto PR] Update translations (4ian#8323)

* Bump newIDE version

* Fix size calculation for variants

Don't show in changelog

* [Auto PR] Update translations (4ian#8328)

* Fix new group name to ensure no usage of forbidden characters (4ian#8329)

* Add storybook stories for Anchor behavior editors (4ian#8330)

Do not show in changelog

* Fix brackets showing in the top right corner of the scene editor (4ian#8332)

Don't show in changelog

* Fix Scene Editor panels not resizing as small as possible (4ian#8331)

* Allow to import asset pack files (GDO) (4ian#8296)

* Explain the difference between built-in and external extensions in the documentation (4ian#8335)

- Don't show in changelog

* Fix to avoid objects to move when the gizmo dragging point is clicked (4ian#8334)

* Tweak the delay before moving an object with gizmo in the 3D editor

* Fix event generation errors not properly reported

* Allow multiple deletions in a single operation for generated events

* Persist properties panel scroll position for instances and objects (4ian#8337)

---------

Co-authored-by: Florian Rival <[email protected]>
Co-authored-by: Florian Rival <[email protected]>
Co-authored-by: Clément Pasteau <[email protected]>
Co-authored-by: D8H <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: 4ian <[email protected]>
Co-authored-by: LuniMoon <[email protected]>
NBForgeLab added a commit to NBForgeLab/GDevelop that referenced this pull request Mar 2, 2026
* Send context of the conversation to improve AI asset search

* Add a short description for all extensions and dimension field (2D, 3D, 2D/3D or n/a) (4ian#8303)

Only show in developer changelog

* Add missing support for short description/dimension

Don't show in changelog

* Fix being able to rename a layer with shortcut (4ian#8309)

* Fix opening the 3D editor not working after launching a preview first on the web (4ian#8310)

* Fix property group wrongly set when dragging a folder to the root (4ian#8312)

* Fix handling of instance/locked variables (4ian#8311)

- Removed the + button that was wrongly shown to add an instance variable (instance variables can only "override" the values of the variables defined in the object)
- Fix paste/delete a child of structure/array of a variable that is re-defined in instances variables. Previously it was not possible to paste a variable as a child of a instance variable that was a structure/array. This is now possible (and fully supported - you can't add new variables at the root, but items inside structures/arrays can be changed).

* Fix properties sometimes missing or duplicated when grouped in columns (4ian#8313)

* Fix keyboard shortcuts (copy/cut/paste/delete/undo/redo) not working when editing variables

* Replace old search bar by compact search bar in scene editor panels (4ian#8317)

* Improve robustness of AI events generation and asset swapping

* [Auto PR] Update translations (4ian#8304)

This updates the translations by downloading them from Crowdin and
compiling them for usage by the app.

Please double check the values in
`newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are
sensible.

Co-authored-by: 4ian <[email protected]>

* Add support for ordering For Each by an expression, with optional limit  (4ian#8319)

- For advanced use cases where it's important to run events on each instance of an object with an ordering, the For Each can now have an ordering: an expression can be written and will be evaluated for each instance separately. The For Each will then execute for each instance in the order of the result of the expression.
- It's possible to change the direction (ascending or descending)
- It's also possible to give a limit (for example, 1 will allow to pick just the instance with the highest/lowest value for the expression).
- Examples are provided in the UI for common use cases (maximum value of a variable, health points, ammo, distance to another object...)

* Update cordova config for new xcode/ios versions (4ian#8321)

Only show in developer changelog

* Fix tileset scrollbar area changing selection (4ian#8324)

Fix 4ian#8316

* Improve details of center/origin when an object is created by the AI (4ian#8322)

* Add a simplified version of the Anchor behavior editor (4ian#8325)

* [Auto PR] Update translations (4ian#8323)

* Bump newIDE version

* Fix size calculation for variants

Don't show in changelog

* [Auto PR] Update translations (4ian#8328)

* Fix new group name to ensure no usage of forbidden characters (4ian#8329)

* Add storybook stories for Anchor behavior editors (4ian#8330)

Do not show in changelog

* Fix brackets showing in the top right corner of the scene editor (4ian#8332)

Don't show in changelog

* Fix Scene Editor panels not resizing as small as possible (4ian#8331)

* Allow to import asset pack files (GDO) (4ian#8296)

* Explain the difference between built-in and external extensions in the documentation (4ian#8335)

- Don't show in changelog

* Fix to avoid objects to move when the gizmo dragging point is clicked (4ian#8334)

* Tweak the delay before moving an object with gizmo in the 3D editor

* Fix event generation errors not properly reported

* Allow multiple deletions in a single operation for generated events

* Persist properties panel scroll position for instances and objects (4ian#8337)

* Fix For Each rendering when disabled and default values

* Rename "any order" to "default order" for For Each events

* Fix npm commands not working with projects on a different disk on Windows (4ian#8345)

* Improve events search UI with Match Case/Filters icon

---------

Co-authored-by: Florian Rival <[email protected]>
Co-authored-by: Florian Rival <[email protected]>
Co-authored-by: Clément Pasteau <[email protected]>
Co-authored-by: D8H <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: 4ian <[email protected]>
Co-authored-by: LuniMoon <[email protected]>
Co-authored-by: opaldi <[email protected]>
NBForgeLab added a commit to NBForgeLab/GDevelop that referenced this pull request Mar 16, 2026
* Send context of the conversation to improve AI asset search

* Add a short description for all extensions and dimension field (2D, 3D, 2D/3D or n/a) (4ian#8303)

Only show in developer changelog

* Add missing support for short description/dimension

Don't show in changelog

* Fix being able to rename a layer with shortcut (4ian#8309)

* Fix opening the 3D editor not working after launching a preview first on the web (4ian#8310)

* Fix property group wrongly set when dragging a folder to the root (4ian#8312)

* Fix handling of instance/locked variables (4ian#8311)

- Removed the + button that was wrongly shown to add an instance variable (instance variables can only "override" the values of the variables defined in the object)
- Fix paste/delete a child of structure/array of a variable that is re-defined in instances variables. Previously it was not possible to paste a variable as a child of a instance variable that was a structure/array. This is now possible (and fully supported - you can't add new variables at the root, but items inside structures/arrays can be changed).

* Fix properties sometimes missing or duplicated when grouped in columns (4ian#8313)

* Fix keyboard shortcuts (copy/cut/paste/delete/undo/redo) not working when editing variables

* Replace old search bar by compact search bar in scene editor panels (4ian#8317)

* Improve robustness of AI events generation and asset swapping

* [Auto PR] Update translations (4ian#8304)

This updates the translations by downloading them from Crowdin and
compiling them for usage by the app.

Please double check the values in
`newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are
sensible.

Co-authored-by: 4ian <[email protected]>

* Add support for ordering For Each by an expression, with optional limit  (4ian#8319)

- For advanced use cases where it's important to run events on each instance of an object with an ordering, the For Each can now have an ordering: an expression can be written and will be evaluated for each instance separately. The For Each will then execute for each instance in the order of the result of the expression.
- It's possible to change the direction (ascending or descending)
- It's also possible to give a limit (for example, 1 will allow to pick just the instance with the highest/lowest value for the expression).
- Examples are provided in the UI for common use cases (maximum value of a variable, health points, ammo, distance to another object...)

* Update cordova config for new xcode/ios versions (4ian#8321)

Only show in developer changelog

* Fix tileset scrollbar area changing selection (4ian#8324)

Fix 4ian#8316

* Improve details of center/origin when an object is created by the AI (4ian#8322)

* Add a simplified version of the Anchor behavior editor (4ian#8325)

* [Auto PR] Update translations (4ian#8323)

* Bump newIDE version

* Fix size calculation for variants

Don't show in changelog

* [Auto PR] Update translations (4ian#8328)

* Fix new group name to ensure no usage of forbidden characters (4ian#8329)

* Add storybook stories for Anchor behavior editors (4ian#8330)

Do not show in changelog

* Fix brackets showing in the top right corner of the scene editor (4ian#8332)

Don't show in changelog

* Fix Scene Editor panels not resizing as small as possible (4ian#8331)

* Allow to import asset pack files (GDO) (4ian#8296)

* Explain the difference between built-in and external extensions in the documentation (4ian#8335)

- Don't show in changelog

* Fix to avoid objects to move when the gizmo dragging point is clicked (4ian#8334)

* Tweak the delay before moving an object with gizmo in the 3D editor

* Fix event generation errors not properly reported

* Allow multiple deletions in a single operation for generated events

* Persist properties panel scroll position for instances and objects (4ian#8337)

* Fix For Each rendering when disabled and default values

* Rename "any order" to "default order" for For Each events

* Fix npm commands not working with projects on a different disk on Windows (4ian#8345)

* Improve events search UI with Match Case/Filters icon

* Pass estimated complexity to events generation

Don't show in changelog

* Fix overflow in sidebar with leaderboard fields

* Fix crashes in Events Sheet

* [Auto PR] Update translations (4ian#8333)

* Bump newIDE version (4ian#8353)

* Fix variable of objects used in events broken after opening the object editor

* Bump newIDE version

* Add Global Search, allowing to search in all Events Sheets (including extensions) (4ian#8292)

- Global Search can be opened using Ctrl+Shift+F (or Cmd+Shift+F). The shortcut works from any editor, even if the Global Search is already opened, allowing to quickly launch a new search.
- Click on any search result to open the corresponding events sheet with the result(s) highlighted.
- By default, extensions from the store are excluded from results. You can change this in the filters.

* Improve current Build mode for the AI, with planning capabilities (4ian#8294)

* Also give the ability to stop an ongoing conversation

* [Auto PR] Update translations (4ian#8355)

* Add "internal instruction name" search criterion in Events Sheet search panel (4ian#8356)

Only show in developer changelog

* Add support for folders to organize functions in the extension editor (4ian#8357)

* Extract instruction name parsing into reusable utility method (4ian#8362)

Don't show in changelog

* [Auto PR] Update translations [ci skip] (4ian#8360)

* Add "MemoryTracked" classes and "UseAfterFreeError" (4ian#8359)

- This will track alive/dead instances of some C++ classes and will throw a JS error in case of usage of a already destroyed object from JavaScript. This should avoid crashing/corrupting the wasm/C++ side by calling a method on an object already destroyed. Instead the exception stays on JS side, without reaching the C++ implementation.

Only show in developer changelog

* Fix test

Don't show in changelog

* Fix mapVector and Array declarations flow errors (4ian#8364)

Only show in developer changelog

* Fix flow import-type-as-value errors (4ian#8361)

Only show in developer changelog

* Forbid to use `/` in folder names (4ian#8366)

Don't show in changelog

* Add a button to open the community list in a browser (4ian#8367)

* Add a new center mode "Centered on Z only" for 3D model objects (4ian#8338)

* Fix number formatting to use 16 digits instead of 17 (4ian#8373)

* Fix missing extension dependencies in GDO files (4ian#8372)

Also fix an exception when importing a GDO file with an extension without a valid version number

* Upgrade to React 18 (4ian#8368)

Only show in developer changelog

* Fix null reference error in Material-UI ButtonBase ripple effect (4ian#8374)

Only show in developer changelog

* Fix potential crashes (4ian#8375)

* Fix crash when pinching in image preview on mobile (4ian#8379)

* Fix formatting

* Education plan now supports inviting existing accounts (useful for SSO requirements) (4ian#8371)

* [Auto PR] Update translations (4ian#8363)

This updates the translations by downloading them from Crowdin and
compiling them for usage by the app.

Please double check the values in
`newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are
sensible.

Co-authored-by: ClementPasteau <[email protected]>

* Fix to try to prevent crashes at project switch (4ian#8380)

* Fix tentatively more crashes when switching/closing projects (4ian#8383)

* Fix tentatively crashes when deleting an object from the objects list

* Fix regression when importing assets on newly created local project (4ian#8384)

* Fix resource sub-folders when imported GDO file on Windows (4ian#8381)

* Fix crash when using invalid BBCode color values in BBText (4ian#8386)

* Make Steamworks extension accessible from the web-app

* Add memory tracking to additional container classes (4ian#8392)

Only show in developer changelog

* Fix the displayed group of functions that are not in any folders (4ian#8395)

* Fix wrong error on iOS certificate upload (4ian#8397)

* Fix tooltip text not visible on light theme (4ian#8396)

* Redesign the function property editor to use compact fields (4ian#8394)

* Fix typo (4ian#8398)

Do not show in changelog

* Add ability to use an expression for the 'Set skin' action for Spine (4ian#8389)

* Fix setters being put in the root folder (4ian#8399)

- Don't show in changelog

* Fix parameter placeholder overflowing (4ian#8400)

- Don't show in changelog

* Update package-lock.json

---------

Co-authored-by: Florian Rival <[email protected]>
Co-authored-by: Florian Rival <[email protected]>
Co-authored-by: Clément Pasteau <[email protected]>
Co-authored-by: D8H <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: 4ian <[email protected]>
Co-authored-by: LuniMoon <[email protected]>
Co-authored-by: opaldi <[email protected]>
Co-authored-by: ViktorVovk <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants