-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Add parallelization to RadiationSystem.GridCast #39173
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
base: master
Are you sure you want to change the base?
Add parallelization to RadiationSystem.GridCast #39173
Conversation
|
Need for tritium fire PR |
|
2ms for that little to process still seems goofy to me? |
|
Realistically radiation was never built with performance in mind but if we actually want to use it more the first thing to do is to use b2dynamictree for radiation sources then iterate every receiver in parallel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Read through the code. Looks good just got a couple style changes. Still need to test in game.
|
Also possible testfail fake |
Co-authored-by: Southbridge <[email protected]>
Good thing. I used it with the difference that I didn't use B2DynamicTree directly, but its wrapper DynamicTree (DynamicTree.cs line 76) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple other minor changes
|
Looks good and thank you for contributing! |
|
second approve is true... |


About the PR
This PR significantly optimizes the RadiationSystem to handle hundreds (maybe thousands?) of radiation sources without causing server lag. The system has been redesigned to use parallel processing in combination with a two-stage selection strategy, significantly reducing its impact on performance.
Why / Balance
The previous implementation had a computational complexity of O(Sources × Receivers). In scenarios with a large number of radiation sources (e.g., widespread tritium fires), this led to the system's update time exceeding 20ms, causing noticeable server-side lag and impacting the game's tick rate.
This change is purely a performance optimization. The underlying radiation mechanics and final calculated values remain identical, ensuring no change to game balance. It simply allows the system to perform as intended under heavy load.
There was a TODO for this
Technical details
1. Incremental, Event-Driven Architecture:
ComponentInit,ComponentShutdown,MoveEvent, etc.). This eliminates the performance cost of collection building from the main update loop, ensuringUpdateGridcastis extremely lightweight.Parallelization by Receiver: The main loop now iterates over radiation receivers in parallel using an
IParallelRobustJob. Each thread is responsible for calculating the total radiation for a single receiver.Two-Stage Culling: To avoid the expensive O(S×R) complexity, each parallel task performs a two-stage culling process for its assigned receiver:
DynamicTreewhich stores all active radiation sources. For each receiver, a fastQueryAabbis performed to get a small list of potentially relevant nearby sources. After this initial spatial culling, a cheap distance check is performed using the pre-calculatedmaxRange(Intensity / Slope) to further refine the candidate list.Irradiatemethod, which performs the actual grid intersection tests and raycasting.List<Entity<MapGridComponent>>for grid intersection checks, completely eliminating race conditions that were present in earlier parallelization attempts.resultsarray (the "Gather" phase). The application of these results (updating components and raising events viaIrradiateEntity) is then done sequentially in the main thread (the "Apply" phase), preventing race conditions with non-thread-safe systems called viaOnIrradiatedEvent.Media
A result of 1.5 - 2.5 ms update time was achieved for 51 receivers, 628 sources.

Requirements
Breaking changes
None
Changelog
🆑 Naxel