Allow countermeasures to decoy missiles once only#415
Conversation
Adds ai_profiles flag
$countermeasures decoy a missile once:
Also (re)adds logging to make it easier to figure out what the
countermeasures are doing. Try adding "+countermeasures" to your
debug_filter.cfg file.
|
Why not use a set for |
|
I chose a vector because it's guaranteed contiguous memory which really helps with CPU cache hits on modern CPUs. Regarding a set, I'm don't believe we need the data sorted so that'd point to an unordered_set which should be faster than a set, and unordered_sets have this bucket interface thing which I'm led to believe is a terrible idea that leads to all implementations using linked lists and they're really bad with CPU cache hits. |
|
Map vs vector depends on the size of the vector. If it's small then it's likely that using a vector is faster than using an unordered map. If there are a lot of values then the linear complexity could lead to worse performance than using an unodered map because that typically only needs constant time to determine if a value is already in the map. |
|
the lookup time for a cache miss can be 100x times worse than a cache hit. So can we extrapolate that a vector with up to 100 entries would be on average faster than a map? Is a map likely to have only one extra cache miss vs the vector? Or will there be multiple misses as the internal linked list is followed? |
|
Even if an unordered map were a good idea here, |
|
How many entries can there be in the vector? I'd guess that the vector would be faster until at least a thousand entries. How many weapons can there be in the game? |
|
master:code/globalincs/globals.h:#define MAX_WEAPONS 2000 |
|
I've had a chance to review the patch, and it seems legit -- it does appear to work properly as coded. But it also uses a sequence of cascading if() checks that aren't terribly clear, at least in patch form. Furthermore, the I wonder if the patch could be rewritten to make the countermeasure code more elegant, or if this is the best we can reasonably expect without major surgery in this part of the code... |
If I'm understanding you correctly, this is intentional. Each CM should consider each missile only once. However if you instead mean that a missile will ignore a CM that its chasing, then that's a problem I'll have to look at.
That's partly from wanting to keep the retail code exactly as is, just controlled by if() checks. Would extra comments help? |
|
I think his point was that the name of the variable doesn't quite match its function, but it does; it ignores that CM for further checks. The fact that we're using two different meanings of "ignore" is potentially confusing, though. |
|
Yeah, the ignore_objnum field uses one sense of "ignore", and ignore_list uses the other sense. (That's why I suggested "handle_list" in the SCP internal.) I like the sense that ignore_list is using -- it considers each countermeasure once, decides to either ignore it or chase it, and then never considers it again. I would like to be able to just toss out the existing countermeasure checks, including both the Actually, I wonder if that's really a showstopper considering how many other flaws we've found in the countermeasure code. The missile should never have a chance to oscillate if there is only a two-frame limit under retail behavior. I value very highly the preservation of retail code when appropriate, but for countermeasures it may not be meaningful. |
|
If we limit the size of ignore_list to 1, then missiles should still be able to "oscillate" for two frames. I'll try a new PR based on that idea, then we can rip it apart (aka rigorously assess/test it) to ensure it'll match (or very closely approximate) retail behaviour. |
|
See #463 for the alternative solution discussed, I've thought through the logic several times and am reasonably confident that this will act the same as retail. BUT, I'm super keen to see that confirmed/challenged. |
|
alternate solution implemented in #463 |
Adds ai_profiles flag
$countermeasures decoy a missile once:
Also (re)adds logging to make it easier to figure out what the
countermeasures are doing. Try adding "+countermeasures" to your
debug_filter.cfg file.
(I'll look at these two in future PRs: