mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-16 21:17:39 +03:00
<!-- This is a semi-strict format, you can add/remove sections as needed but the order/format should be kept the same Remove these comments before submitting --> # Excerpt <!-- Explain this PR in as much detail as applicable Some example prompts to consider: How might this affect the game? The codebase? What might be some alternatives to this? How/Who does this benefit/hurt [the game/codebase]? --> thou shall be thy axe that continues the work - to behead all `EntityQueryEnumerator`s, and thus i require it. 'tis imperative i have at thee and perform the duties. if the plague bearing shitcode is not cut at thy roots, it shall only nest a deeper grave and spread locusts. --- # Description It has been a reoccuring theme that someone irresponsibly uses `EntityQueryEnumerator` and then suddenly server performance is worse. A lot of these cases involve using EQE to iterate a timer on a component, to start or stop an effect after a delay. Rather than iterating `frames * n` times per second FOR EVERY UNIQUE SYSTEM THAT DOES THIS (QUITE A FEW), we instead iterate `frames` per second regardless of systems using the Event Scheduler. The Event Scheduler itself is a list of events that wait to be triggered after a delay. Rather than iterating through all of them, they are sorted in order of occurance using a PriorityQueue. I love priority queues because they sort as you enqueue to them, and apparently the sort complexity is logarithmic? But mostly because of the former. I chose to write the scheduler the way I did because the choice to use async seems too big for me alone. So this system is synchronous and updates on game time. This is mostly a practical optimisation. The code which I have written is almost certainly not optimal, but the simple act of replacing EQE delays will significantly improve server performance anyway. Rust monsters feel free to rewrite the event scheduler to be more performant. NOTE: For some reason PriorityQueue is banned on the client, and configuring it requires editing a RobustToolbox file. So for now this system is restricted to Content.Server until we start using our engine fork. --- # TODO <!-- A list of everything you have to do before this PR is "complete" You probably won't have to complete everything before merging but it's good to leave future references --> - [x] Working queue of events ordered by execution times - [x] A function to enqueue any-event-defined-ever into the scheduler with a delay - [x] Delay the event, and then fire it - [x] Implement retroactive schedule cancelling In a future PR: - Add ```System.Collection.Generic.PriorityQueue`2``` to whitelist in `RobustToolbox/Robust.Server/ContentPack/Sandbox.yml` - - Shared files had to be relocated to server because they were banned on the client and would cause an exception. - Investigate insert performance as more systems are added to use the EventScheduler - - MLGTASTICa rose the idea of 'buckets' as an optimisation. - - I theorise multiple priority queues for different types of events might also work. --- <!-- This is default collapsed, readers click to expand it and see all your media The PR media section can get very large at times, so this is a good way to keep it clean The title is written using HTML tags The title must be within the <summary> tags or you won't see it --> <details><summary><h1>Media</h1></summary> <p> Demonstration: https://youtu.be/CGB6SDWGc-Q Response to MLGTASTICa, stress testing: https://youtu.be/30OA06Pzhtk </p> </details> --- # Changelog <!-- You can add an author after the `🆑` to change the name that appears in the changelog (ex: `🆑 Death`) Leaving it blank will default to your GitHub display name This includes all available types for the changelog --> - add: Added the EventScheduler system that lets you raise an event at a certain time or after a delay without killing performance. - fix: Optimised EMP by migrating from EQE to the new EventScheduler system.