-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Segregate inter level hostility #44107
Segregate inter level hostility #44107
Conversation
0ae6c39
to
c95c04f
Compare
An idea for the future, we can use the new UPD: after a bit of thinking, that won't actually speed up anything, as the |
f142c03
to
d6baa73
Compare
d6baa73
to
3ec366f
Compare
Updated to opportunistically shortcut out of checking for NPCs and player as well. |
} | ||
monster &mon = *shared; | ||
float rating = rate_target( mon, dist, smart_planning ); | ||
if( rating == dist ) { |
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.
It is not safe to compare two floats like that.
@alvean we could add the opposite cache value of all_open or similar built the same way and use it to determine the first layer with obstacles more cheaply. @ZhilkinSerg the only time I expect that code to trigger is when the relative positions of monsters are rotations of each other, i.e. 1,7 vs 7,1, and in that case I do expect them to trigger reliably. I'm not against adding some kind of epsilon here to make it trigger a bit more, but that requires a bit more thought and I don't want to mess with it in this pr. |
Good idea, however I'm going to try checking |
Summary
SUMMARY: Performance "Reduce inter-faction hostility overhead with a inter-level visibility cache."
Purpose of change
Execution time when passing time when near a large number of monsters hostile to each other is slow, and profiling says it's dominated by inter-faction vision checks.
Describe the solution
One of the dominant use cases where this happens is inside or near a lab complex since there are many monsters hostile to each other separated by walls. This use case is ameniable to special handling by seperating the maps of creatures based on levels, and only checking for visibility between monsters on levels that have some kind of visibility between them.
I added a bool per map level cache entry that tracks whether the level has a contiguous floor. This is calculated essentially for free in build_floor_cache.
An accessor walks these entries and tabulates which levels the origin level has visibility to as a bitset.
I split the monster faction map by level, within the entry for each faction, there is a sparse map of levels, each of which contains a data structure holding the actual weak pointers to the monsters.
When scanning the faction map for enemies, the code can now exit early on entries on levels not visible to the current monster.
Describe alternatives you've considered
This still consumes a significant amount of processing time, though it is no longer dominant, so further optimization is warranted.
Testing
A timing test of waiting outside a lab for three hours tool 52 seconds before this change, and 40.75 seconds after this change. Profiling with perf also indicated that this particular codepath is doing drastically less work. The new cache creation code is not appearing in profiling.