I don't have proof either but suspect that each monitor adds a little extra processing overhead - aside from its condition checking.
One important fact with monitor condition checks is that it stops checking as soon as one is found to be false.
e.g.
Code:
monitor_event FactionTurnStart FactionType england
and FactionBuildingExists >= governors_house
and FactionIsLocal
This monitor fires on every faction during their turn start. If this faction is not england then not only does the monitor's body not get executed but those other two conditions are not even tested. I assume that FactionBuildingExists takes longer to process than FactionIsLocal; if england is not the local faction then testing that (longer) FactionBuildingExists first was a waste of processing time.
I don't know how long each condition takes to test but if I suspect that it would be something that the game would need to go and work out (distances, near other character types, trait presence/levels, etc.) then I put them at the bottom of the condition list.
Say the campaign currently has 300 characters on the map (including agents, captains, etc.) and 15 belong to england. At the start of an england character's turn, who can be identified by a unique trait, we need to test who currently owns Paris...
Code:
monitor_event CharacterTurnStart FactionType england
and Trait my_trait > 0
and I_SettlementOwner Paris england
;do something
end_monitor
monitor_event CharacterTurnStart FactionType england
and Trait my_trait > 0
and I_SettlementOwner Paris france
;do something else
end_monitor
monitor_event CharacterTurnStart FactionType england
and Trait my_trait > 0
and I_SettlementOwner Paris hre
;do something else again
end_monitor
This will add 900 monitor firings to the turn end: 300 characters x 3 monitors. 45 (15 england characters) will get past the FactionType check. The trait check (a lag causer?) will be evaluated 45 times. I_SettlementOwner will be checked 3 times (only one character will get through the Trait check, in all 3 monitors).
Whereas this...
Code:
monitor_event CharacterTurnStart FactionType england
and Trait my_trait > 0
if I_SettlementOwner Paris england
;do something
end_if
if I_SettlementOwner Paris france
;do something
end_if
if I_SettlementOwner Paris hre
;do something
end_if
end_monitor
...will add 300 monitor firings to the turn end: 300 characters x 1 monitors. 15 (15 england characters) will get past the FactionType check. The trait check (a lag causer?) will be evaluated 15 times. I_SettlementOwner will be checked 3 times.
That is 600 less FactionType checks and 30 less Trait checks. Simply by doing in one monitor what was being done by three. Add a lot more characters to the game (which a later game will have) and a bunch of other factions for the owner tests and the difference in numbers will be much larger.
NOTE: as only the england character has the unique trait the FactionType check is functionally redundant. It was added to cut down on the number of Trait checks. Whether or not that is actually saving more processing than what the extra condition (FactionType) is adding I do not know.
(In that first example I_SettlementOwner could have been moved up the condition order. I expect that it is faster than Trait.)
Is there a way to terminate a monitor that has not met its condition, with another monitor?
That is another advantage of using IFs instead of monitor conditions. More chance that the body of the monitor will be executed and therefore killable via a terminate_monitor inside it.
Code:
monitor_event CharacterTurnStart FactionType england
and I_LocalFaction england
;do something
end_monitor
If england is not the player faction then this monitor still fires on every character for the campaign's lifetime. It won't "do something" because it won't get past the I_LocalFaction check for any character. But it is still a pointless waste of processing time, checking FactionType on every character and then I_LocalFaction on every england character. Whereas this...
Code:
monitor_event CharacterTurnStart FactionType england
if not I_LocalFaction england
terminate_monitor
end_if
;do something
end_monitor
...will kill itself on the first england character's turn start, if england is not the player.
To answer your question: no, not really. The only way to kill a monitor is to get it to kill itself. For that to happen the monitor must make it through its conditions - something that simply won't happen in some cases. By moving conditions that have no trigger requirements (I_xxx ones plus a couple of others) from the monitor conditions to the body as IFs you can increase the chances of the monitor making it through its conditions ... to a terminate_monitor waiting inside.
An exception is a monitor that is testing for an event counter value change: the EventCounter event, as used for yes/no response for example.
Code:
monitor_event EventCounter EventCounterType question_accepted
and EventCounter > 0
;answered "yes": do something
terminate_monitor
end_monitor
monitor_event EventCounter EventCounterType question_declined
and EventCounter > 0
;answered "no": do something else
terminate_monitor
end_monitor
These are waiting for an answer to the "question" yes/no historic event. But only one will fire because the user can only answer one way, so the other one will never terminate. Probably no big deal because that monitor will never fire anyway (so no processing used up?) but if you want to kill it then you could do this...
Code:
monitor_event EventCounter EventCounterType question_accepted
and EventCounter > 0
if not I_EventCounter question_accepted == 1
;answered "no" - signaled to terminate
set_event_counter question_accepted 0
terminate_monitor
end_if
;answered "yes": do something
terminate_monitor
end_monitor
monitor_event EventCounter EventCounterType question_declined
and EventCounter > 0
if not I_EventCounter question_declined == 1
;answered "yes" - signaled to terminate
set_event_counter question_declined 0
terminate_monitor
end_if
;answered "no": do something
terminate_monitor
end_monitor
monitor_event FactionTurnEnd FactionType slave
if I_EventCounter question_accepted == 1
set_event_counter question_declined 2 ;signal to terminate
terminate_monitor
end_if
if I_EventCounter question_declined == 1
set_event_counter question_accepted 2 ;signal to terminate
terminate_monitor
end_if
end_monitor
The third monitor, if it sees that the question has been answered, signals the monitor of the other answer to terminate (using "2").
This might be overkill. However, the same principle can be used for monitor_conditions that are checking counter values. Although, if it is being used to check for event counter values, like yes/no responses, then ... why?! monitor_conditions is a bad way to do that ... use the EventCounter event instead. Avoid monitor_conditions - for anything - wherever possible!
EDIT: this is another way to do that EventCounter script, not requiring a third monitor...
Code:
monitor_event EventCounter EventCounterType question_accepted
and EventCounter > 0
if I_EventCounter question_accepted == 2
;answered "no" - signaled to terminate
set_event_counter question_accepted 0
terminate_monitor
end_if
;answered "yes": do something
;...and signal other monitor to terminate
set_event_counter question_declined 2
terminate_monitor
end_monitor
monitor_event EventCounter EventCounterType question_declined
and EventCounter > 0
if I_EventCounter question_declined == 2
;answered "yes" - signaled to terminate
set_event_counter question_declined 0
terminate_monitor
end_if
;answered "no": do something
;...and signal other monitor to terminate
set_event_counter question_accepted 2
terminate_monitor
end_monitor