Skip to content

Conversation

james7132
Copy link
Member

@james7132 james7132 commented Sep 8, 2025

Objective

When going over #20901, it came across to me that the Sync bound on Plugin might be too strong. There are currently zero uses in first-party crates where we currently rely on Plugin: Sync, or in other words ,we never rely on plugins being simultaneously accessible from multiple threads. Given that most of the plugins we have are ZSTs, this might be too tight of a restriction on plugins that require more configuration (e.g. RemotePlugin).

Solution

Remove the bound on the trait. Utilize that to use Cell instead of RwLock in RemotePlugin.

Given this loosens the restrictions on a core trait, I expect this PR to be, at least, a bit contentious. I currently cannot think of a common use case inside the core App framework for plugins (and Apps that contain them) to be accessed simultaneously from multiple threads.

Testing

Local tests.

@james7132 james7132 added C-Usability A targeted quality-of-life change that makes Bevy easier to use A-App Bevy apps and plugins labels Sep 8, 2025
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see any reason why we currently need this bound, nor can I think of any reason why we might want it in the future.

@alice-i-cecile alice-i-cecile added X-Contentious There are nontrivial implications that should be thought through S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Sep 8, 2025
@maniwani
Copy link
Contributor

maniwani commented Sep 9, 2025

I don't see plugins being accessed from multiple threads either, but this change might entrench some not-so-good architectural decisions / technical debt.

What if, in the future, you want to represent plugins with entities?

Right now, the "plugin registry" is a couple of fields on SubApp, but those could quite easily be moved into the ECS. Further down that road, consider that if components, systems, and plugins were all represented by entities, components and systems could normally have ChildOf(plugin) and be cleaned up if their plugin is despawned. (Just to state a benefit of doing things this way.)

If y'all eventually decide you want to pursue that, you'd maybe want to walk back this PR. Types currently have to be Send and Sync to be components. If Plugin doesn't require Sync, components wouldn't be able to hold Plugin trait objects without wrapping them in a SyncCell.


In general, the particulars of how plugins are stored and handled actually have a lot of subtle, second-order architectural effects.

Plugins being built immediately when you call add_plugins, for example, is a big reason why it's been so hard to move the world out of the winit loop. (Plugins can create !Send data when you build them.) It's also the reason Bevy can't resolve a valid build order automatically. (Plugins are still built in a manually specified order.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-App Bevy apps and plugins C-Usability A targeted quality-of-life change that makes Bevy easier to use S-Needs-Review Needs reviewer attention (from anyone!) to move forward X-Contentious There are nontrivial implications that should be thought through
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants