Repository navigation
Conversation
- script systems are identified by (attachment, callback label): adding one again replaces it, and they are removed when their script unloads or reloads - system sets hold recycled slots, bounding the interning leak; sets are never removed from schedules (bevy 0.20 panics when a removed set is reused) - changes to running schedules (i.e. PreUpdate) are queued and applied in First/Last; removed systems stop running immediately - script system errors are sent as ScriptErrorMessages, invalid parameters are reported once instead of being skipped silently - no panics: uninitialized/cross-world runs are skipped, scope_schedule keeps the schedule on errors, the contexts lock is released before callbacks - soundness: non-exclusive guards restrict component access to the archetypes matched by the declaring queries (ArchetypeFilter), bevy runs filtered queries in parallel with disjoint ones
Contributor
|
| Project | Bevy Scripting |
| Branch | agent/script-systems-stabilise |
| Testbed | linux-gha |
🐰 View full continuous benchmarking report in Bencher
⚠️ WARNING: Truncated view!The full continuous benchmarking report exceeds the maximum length allowed on this platform.
makspll
added this pull request to stack #649
October 22, 2026 13:33
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First of the stacked script system PRs (stabilise → access → scheduling → queries → perf).
Lifecycle
(attachment, callback label). Adding it again replaces the old one, with awarn!.remove_script_systems_when_unloadedobservers, which always run, independent of the unload callback setting.ScriptSystemSet(u32)holds a slot in the newScriptSystemsresource. Slots are recycled, so the interning leak (one per distinct set value) is bounded by the peak number of live script systems.RemoveSystemsOnlyAllowBreakages). In Bevy 0.20,SystemSets::removekeeps the set in itsidsmap, so adding to a removed set panics. A slot that a live script system orders against is not recycled.PreUpdate, where the pipeline runs) are queued, together with later changes to the same schedule, and applied byapply_script_system_changesinFirstandLast. Removed systems stop running right away through analiveflag. When the add is deferred,world.add_systemreturns aReflectSystemwithout a node id.Robustness
ScriptErrorMessages (collected inScriptSystems, sent by the same system). Invalid params are reported once, after which the system no longer runs; previously the init errors were popped once per frame and the system then ran anyway.Skippedscope_schedule'sassert!is now an error, and the schedule is re-inserted even ifScheduleswas removedScriptContextsread lock is released beforeP::handle. Previously a callback that loaded or unloaded a script could deadlock.Soundness
Bevy schedules a script system by its
FilteredAccess, soquery(C):with(A)runs in parallel withQuery<&mut C, Without<A>>. The guard used to grantCon every entity, soworld.get_component(e_without_a, C)gave aliased mutable access.The new
ArchetypeFilter(inbevy_mod_scripting_world) restricts each component to the archetypes matched by the queries that declare it. The check happens inreflect_(mut_)unsafe. Its module docs cover why archetypes and not tables, why it is sound for every filter, and why the filter can't go stale.The new test
system_cannot_access_component_outside_query_archetypes.luafails with the check disabled. Benches (field get/set,component/resourceaccess/get,query/100) stay within noise against main, but they run in exclusive contexts, so the filtered path isn't benched.Tests
system_with_parameters.luanow recordsfinished: its assertions only got logged before, and its_1tuple-field access had never worked.🤖 Generated with Claude Code