Skip to content

Moving off async outside IO and into bevy_ecs #178

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

Merged
merged 76 commits into from
Jun 2, 2025
Merged

Conversation

ReCore-sys
Copy link
Collaborator

@ReCore-sys ReCore-sys commented May 21, 2025

Turns out a homebrew ECS and event system isn't very reliable. Who would have guessed? Not us apparently.

Description

This is a massive PR implementing a huge amount of changes over the entire codebase. There are 2 big parts of this PR:
Part 1 is completely separating out the sync and async code. Async code is now exclusively used for networking IO and the rest of the server runs entirely on native threads, managed by bevy_ecs. Doing fully async or fully sync has been the easiest option for a while but it is far from the most efficient, so we decided to bite the bullet and do it properly. Originally I was able to split the async and sync without using bevy, hence the name of the branch, but this quickly highlighted the issues with our own ECS and event system which leads into the second major change;
Part 2 is entirely removing our homemade ECS and event system, in favor of bevy's much more advanced and performant ECS and event system. This comes with many upsides, such as less maintenance cost on us, more effective parallelism and a much more flexible architecture. While we are very proud of our custom ECS, we ultimately decided that using a better alternative developed by some extremely talented programmers and driven by a passionate community was the way forward. Due to the major differences between bevy and our old ECS, massive changes had to be made to the codebase (hence the ~7.7k total lines changed at time of writing) so large amounts of the codebase will be wildly different.

Some less major changes were made such as:

  • Moving the login/config/status stage out of the ECS and normal packet handling into a simple flow on connection. This means that connections that aren't actually in the game are isolated, meaning other parts of the code don't have to check if the player is actually in the game.
  • Packet handling was moved to the binary crate to better integrate with bevy_ecs.
  • Networking runs on a single thread with a single tokio task per connection. Later I'd like to make this configurable but for now it should be fine.
  • Game loop now runs on ticks. Previously packets would handled as soon as they arrive, now they are processed at the start of every tick.
  • Broadcasting was removed. It was unnecessarily complex with the callbacks, and it would now have to take an ECS query as a parameter at which point it's just easier to iterate all connections manually.
  • A player list was added to the state so the list of players and their UUIDs can be accessed without needing the ECS. This is primarily for status requests where the ECS isn't present.

Motivation and Context

After constant issues with the ECS and the original developer of our event system dropping off the face of the planet with no-one having any idea how it worked, we decided to cut our losses and move onto a more battle-tested ECS and event system. Just eyeballing it, performance is a bit better but not by a massive amount. However, the callstack not being muddied by tokio and bevy's reflection approach means that diagnosing performance issues are going to be much easier in the future.

How has this been tested?

Units tests aren't really for feasible for this, but it compiles fine and all functionality seems to work as intended. Still keeping an eye out for bugs.

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (restructuring code, without changing its behavior)

Checklist:

  • My code follows the code style of this project.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • Clippy passes with no warnings.

ReCore-sys and others added 30 commits March 20, 2025 19:08
How the hell does this event system work???
Gunna take verq's suggestion and try decoupling the handshake and play stages of the networking
@ReCore-sys ReCore-sys marked this pull request as ready for review June 2, 2025 06:25
@ReCore-sys
Copy link
Collaborator Author

Sweatty said to merge it and fix later so it's on him if it doesn't work (jk)

@ReCore-sys ReCore-sys merged commit ea7e3c3 into master Jun 2, 2025
6 checks passed
@ReCore-sys ReCore-sys deleted the rewrite/sync-async branch June 2, 2025 06:40
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.

2 participants