Skip to content

feat: optional components, added/changed filters and disjoint queries - #651

Open
makspll wants to merge 5 commits into
agent/script-systems-schedulingfrom
agent/script-systems-queries
Open

makspll wants to merge 5 commits into
agent/script-systems-schedulingfrom
agent/script-systems-queries

Conversation

@makspll

@makspll makspll commented Oct 22, 2026

Copy link
Copy Markdown
Owner

Stacked on #650. Fourth of the script system PRs.

Queries

  • :optional(C) / :optional_read(C) retrieve C from entities that have it; for entities that don't, it is nil in result:components(). ScriptQueryResult::components is now Vec<Option<ReflectReference>>.
  • :added(C) / :changed(C) are filters like with.
    • Bevy's QueryBuilder can't express change filters dynamically. So the query declares a read of C (ref_id, which also requires C, the same as Changed<T>), and ScriptQueryBuilder::result_for checks the ticks of each matched entity.
    • Inside systems they're relative to the system's last run. Outside, in world.query():build(), they're relative to the world's last change tick, like World::query.
  • world.query() and script systems now build results through the same result_for.

Disjoint queries

  • The old rule rejected any component shared between params ("Non-disjoint query"). It's replaced by Bevy's get_conflicts_single, so component(A):with(B) + component(A):without(B) is allowed. Conflicting params are reported once, and the system doesn't run.
  • Soundness: queries can now write C on some archetypes and only read it on others, so ArchetypeFilter keeps separate read and write bitsets per component. Without that, the write permission (per component) would let the script write C on entities that Bevy thinks this system only reads. The Lua test checks that the write through the read-only query fails.

Fix

DynamicScriptSystem::run_unsafe incremented the change tick but never stored last_run, so "since last run" meant "ever". last_run is now updated whenever the callback runs.

Tests

  • Rust: changed relative to last_change_tick (only the modified entity matches), and absent optionals are None.
  • Lua:
    • optional nils
    • a disjoint pair of queries runs, and a conflicting pair doesn't
    • the read/write split rejects the bad write
  • cargo check --workspace --all-targets is clean. The ecs bindings' Name lookup used components, and is adapted.

🤖 Generated with Claude Code

@semanticdiff-com

semanticdiff-com Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

@makspll
makspll added this pull request to stack #649 October 22, 2026 16:19
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

🐰 Bencher Report

ProjectBevy Scripting
Branchagent/script-systems-queries
Testbedlinux-gha

⚠️ WARNING: Truncated view!

The full continuous benchmarking report exceeds the maximum length allowed on this platform.

🐰 View full continuous benchmarking report in Bencher

- `optional` / `optional_read` retrieve components entities don't need to
  have (nil when absent), `added` / `changed` filter by ticks since the
  system's last run (outside systems: since the last update)
- queries of a system may share components when bevy considers their
  accesses disjoint, the archetype filter restricts reads and writes
  separately so a component written by one query and read by another can't
  be written on the reading query's entities
- fix: script systems never stored their last run tick
@makspll
makspll force-pushed the agent/script-systems-queries branch from 0badd32 to 45f13ec Compare October 23, 2026 12:07
…ems-queries

# Conflicts:
#	crates/bevy_mod_scripting_bindings/src/query.rs
#	crates/bevy_mod_scripting_bindings/src/world_extensions.rs
#	crates/bevy_mod_scripting_core/src/script_system.rs
#	crates/bevy_mod_scripting_world/src/archetype_filter.rs
…ems-queries

# Conflicts:
#	crates/bevy_mod_scripting_world/src/archetype_filter.rs
…ems-queries

# Conflicts:
#	docs/src/ReleaseNotes/0.23-to-0.24.md

This branch has not been deployed

No deployments
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.

1 participant