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

Rewrite the project with evenio #596

Open
rj00a opened this issue Jan 29, 2024 · 0 comments
Open

Rewrite the project with evenio #596

rj00a opened this issue Jan 29, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@rj00a
Copy link
Member

rj00a commented Jan 29, 2024

For the past few months I have been working on a little ECS library called evenio. This is in response to some limitations I have encountered using bevy_ecs in Valence. In essence, I believe that "run once per frame" systems as the primary abstraction is fundamentally inadequate. This one fact has been the source of many design issues in Valence. Here are some of the problems and how evenio could fix them:

  • In bevy_ecs, there aren't any reliable ways to enforce that entities have certain combinations of components because there's always a delay between when the violation occurs and when it can be acted on. As a result, we don't even attempt to detect these potential mistakes. evenio lets us write handlers that run the moment before a component is added or removed, making these violations feasible to detect and act on.

  • Whenever an entity is despawned we almost always need to do some cleanup work. Bevy lets us detect that an entity is removed from the world, but doesn't give access to the entity's components because the entity is already gone. We work around this by using a Despawned component to signal removal, then letting systems in PostUpdate run before it's removed. This works, but it's very error prone because there's nothing stopping someone from calling .despawn() instead of adding the marker. evenio fixes this problem by signaling entity despawns with an event, allowing code to run immediately before the entity is removed.

  • A lot of valence's APIs are based on a pattern where we let the user make some changes to the world in Update and then defer handling the changes until PostUpdate. Compared to the simple procedural approach, This is a lot more cumbersome. Case in point, I tried to improve layers and clean things up in Redesign layers and valence_server schedule. #533 but the resulting code was so complicated and error prone that I gave up. In evenio, we can just use events to signal state changes instead of using change detection or diffing.

  • While reading packets from clients, we split the stream of packets into separate event buffers based on packet type. The problem is, this loses the order between different packet types. To get around this, I made an entirely separate schedule which runs in a loop to ensure that packet handler code is executed in the correct order. This is ugly and slow. Process client packets before run schedulers #587 tried to simplify this a bit without being aware of these details. We could have easily fixed this by using system callbacks, but this wouldn't really integrate with bevy's schedules. In evenio, event handlers are run in the order events are produced (regardless of type) so the problem goes away.

  • Every system added in Bevy has a cost. Systems run every frame even if they have no work to do. This is especially bad with the multithreaded executor due to the overhead involved. Add default fields for all entities in extractor #571 tried to fix the entity extractor and entity tracked data, but the solution would have caused an explosion in the number of systems. With evenio, systems don't have a cost unless the event they're listening for is actually sent.

  • In Poor performance in bench_players example. #323 I noticed poor performance while the server isn't doing anything. Likely related to the previous point.

  • Bevy's change detection feature is not flexible enough. Sometimes it works fine, but in other cases we end up using .bypass_change_detection() which results in footguns for end users.

  • evenio doesn't have system order ambiguities, so Resolve system order ambiguities #542 goes away.

  • Cancelable event  #399 wants to introduce cancellable events similar to bukkit. This might be a lot easier with evenio events.

So, here's my plan. Let's burn it all to the ground and start over with evenio. We can leave valence_protocol and everything below it mostly intact, but everything else needs to go. Although evenio needs quite a lot of work before I would call it production ready, it should be usable enough to get started. Bevy has recently adopted some features like one-shot systems to address the above problems, but I don't really think they get at the root of the issue.

During this rewrite I would like to do a few other things:

I have started work in #599

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

Successfully merging a pull request may close this issue.

1 participant