The requirements Meridian told me where actually much less conflicting with how I envisioned it than what you told me in the comments about the initial pull-request.
They were:
1. Fully backwards-compatible, which just means that when not using the option, the game behaves exactly like before. That seemed most easy to realize by using my own methods for everything and leaving the methods of the base-AI alone. But that approach is something that you seemed to have taken an issue with due to duplicating code. I have not copied any method that I didn't change at least something in. In the later iterations the changes have become bigger and bigger. So even the initially almost unaltered methods are now quite different than what their origin looked like. They still often fulfill the same task but in a way meant to optimize efficiency rather than emulating OG-behaviour.
OXCE is not fully "compatible" with OG, there is multiple changes in behavior (and even AI) but most of them are subtile and do not affect game play aside of some corner cases.
If feature was critical and important then Meridian would allow small changes in OG behavior, but as he think that new BrutalAI is neither, and because of this, he demand no changes at all in default behavior.
I personalty could permit more changed in OG behavior at least if they are faithful to OG. But for now if Meridian explicit require it from you then I will not try override his request and I consider it still holding.
For you code, as I previously said if your new function is fully configurable then I could accept duplication of code as it make easier to realize Meridian requirements. Only thing I require more is that new AI could be configure in that way that for normal user will not see difference to old AI. This mean not work exactly same but overall similar and you could ignore corner cases. This should be relative easy to do.
2. No work in progress. This was only a problem to me as long as I had no alternative to allow people to test my work beforehand. But we found a compromise where he builds versions for me from a separate branch. I now even prefer it this way as it allows me to experiment with things I probably wouldn't have experimented with before and can tidy everything up later. But that also means it will definitely not happen anytime soon. Developing AI has a bigger scope than adding a new button that does something very specific. So it definitely will take some time until I run out of things to improve.
What you were asking in those comments, however, seemed much more difficult to realize than what Meridian asked for. Especially since it seemed to be partially conflicting with Meridian's requirement #1.
I really do not want to mess around with the original AI code and inject all of my stuff there. This would make ensuring backwards-compatibility very, very difficult and lead to almost incomprehensible code within those methods.
Magic word: Refactor
Some times function it impossible to change but you can rewrite it in that way its behavior do not change but adding new functionality is trivial.
This could even make code easier to read. At least this would be approach I would take to improve code like AI.
This would require lot of skill and time but in long run would reduce work you need to do in improving AI.
Another benefits of refactor like this would be closing all holes in engine logic, some thing like this could even permit changes in visible behavior of aliens.
Again this is not that you should do it now, but how I would try approach this problem. I already apply this approach to some changes I did before in OXCE, last one was custom move cost that required lot of refactor of handle both TU and Energy as limits. This could be inspiration how it could be done for AI.
I think at this point it would be even better to add my AI as a completely new class to keep it even more strictly separated.
Your other point was to make different behaviors of the AI configurable separately. I think that something like that only really starts to make sense when the AI is mostly finished and thoroughly tested so one can actually have an overview of what would make sense to be configurable.
I definitely do not think that every single thing about it should get it's separate switch.
Right now I see 2 main options that I think make sense for it:
1. Respect limitiations. => There's some optional (and controversial, if I read the threads about these correctly) limitations for the regular AI that are active by default. I want my AI to ignore these limitations by default but think there should be a way to reenable all of the them as an option.
2. Giving modders control of when to use it or not. I'm not really sure though what possibilities a modder has when it comes to defining conditions for something like that. There's many potential possibilities and I don't know just yet. For example: Assign it to certain units/unit-ranks. Could, for example have the Leaders and Commanders use it but not the basic soldiers. Or you could want to make the Sectoids use it but not the Mutons.
Other possible scenarios could be to enable it with a turn-timer in a mission... or a month-timer in the game... or for specific mission-types. There's a lot of thinkable scenarios and I don't know yet if I have to specify them separately or if the modder can control all of them with only one hook in the code.
As I said, when it comes to sub-routines also being moddable, we'd first need to define for which sub-routines that makes sense in the first place. This would have to be based on feedback in the sense of: "I wished they could still do that but would not do that."
Now goes my requirements (for now this is only things I will require in future before inclusion of your code to OXCE):
For 1. even if you make separate AI it should obey configs set by modder, as whole point of them was to control AI, if you do not want this restriction make mod that set them all to zero, and this mod could be part of default OXCE install (same how we handle features from UFOextender).
And this should be way how your change be enabled, special mod that can be enabled with any other mod.
For 2. Make simple `struct AiConfig { bool UseBrutalAi, UseBehaviorA, CheckForX, IgnoreZ; void load(const YAML::Node&); };`, AI object get copy of this struct and read only from it, and do not check any global state. How AI get this struct should not bother you now any way, this will be for future to decide, for now it could be one object for whole `class Mod`.
Every function as part of AI class have access to this `AiConfig` and check for `if (_config.SomeFeatureC)` if you need alter behavior in some subroutine.
For start, function that you will need to allow configure is one that make biggest departure from original AI, this mean modder can restore partially old behavior.
This mean you do not need exactly implement old behavior, but it need be close enough that is easy to miss when you do not know for what to look.
e.g. Door blocking by Xcom soldier, normally AI will fail to open them, but your can do it, you add `if (_config.OpenBlockedDoors)`and this could be `true` by default for your AI.