Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid triggering Added and Changed queries on all rollbacks? #39

Open
johanhelsing opened this issue Dec 11, 2022 · 5 comments
Open

Avoid triggering Added and Changed queries on all rollbacks? #39

johanhelsing opened this issue Dec 11, 2022 · 5 comments
Labels
enhancement New feature or request

Comments

@johanhelsing
Copy link
Collaborator

When a rollback is triggered, bevy_ggrs restores a saved world snapshot. It updates components by first removing them, and then adding them again. This triggers all queries with Added<Component> or Changed<Component> in it, regardless of whether the component was already there and whether it changed.

reflect_component.remove(world, entity);

Sometimes systems have queries that react to other components being added or changed, triggering changes on every rollback. Sometimes, this just causes a small performance hit, other times, it leads to buggy behavior because setup code runs multiple times.

Describe the solution you'd like
Perhaps it's possible to only update the component if it's different?

Additional context
In regular game code, this is usually quite easy to fix or work around, but sometimes the affected code belongs to 3rd party crates, which are a lot harder to solve.

@zicklag
Copy link
Contributor

zicklag commented Dec 11, 2022

This one could be quite tricky, and maybe infeasible.

This is a similar issue to using Local<T> parameters in your systems, because the local system state is what stores the last change tick if I remember correctly, so we'd essentially have to have a way to solve snapshot and restore for local state.


Here's one idea. We'd have to make a trait that adds a .rollback_system() method that you could call when adding systems to the app, and this would wrap around a normal system implementation, and it would use a snapshotted resource to store the SystemState for all rollback systems.

I think that could fix the Local<T> and other local state parameters, and it could even fix event readers ( if you custom register the events and make sure you only flush the event buffer on confirmed frames ).

But we'd also have to have a way to revert the latest change tick on a component ( which is not a part of local state ) when we restore an older snapshot. I don't know if Bevy has a publicly exposed way to mutate those component change ticks, though.

@johanhelsing
Copy link
Collaborator Author

johanhelsing commented Jan 8, 2023

I looked into this issue and wanted to understand exactly what was wrong with doing ReflectComponent::apply. The details of that are explained in the bevy issue above.

The problem is not with bevy_reflect::Array + !bevy_reflect::Lists (which are fixed size and will be applied in their entirety), but with bevy_reflect::Lists which is confusingly a supertrait of Array.

For instance, the Children component uses a SmallVec, which is a List, hence the issues with entities not being removed if self.len() > value.len().

There is a pr for adding remove functionality to List, so perhaps there is hope for this to work after all :) bevyengine/bevy#7063

@johanhelsing
Copy link
Collaborator Author

Relevant bevy pr implementing change detection bypass: bevyengine/bevy#5635

@gschup
Copy link
Owner

gschup commented Mar 30, 2023

Since the bevy PR is now merged, we should be able to use it now, right?

@johanhelsing
Copy link
Collaborator Author

johanhelsing commented Mar 30, 2023

If i remember correctly, we can't do the nicest fix, since reflect apply is imo still broken. But perhaps we might get a decent workaround with change detection bypass.

This will probably all be irrelevant after the rewrite, though?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants