We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.
You are using an out of date browser. It may not display this or other websites correctly. You should upgrade or use an alternative browser.
This fixes the quote issue (by doing a hack of replacing all the slash+quote with empty in the .mod files, so it doesn't actually check that you have quotes around mods with spaces or anything, and one asks why cannot paradox just not care if there are quotes or not anyways)
In the top right there is a menu which you can change to "Show main mod errors", which ideally should not show dependent mod errors. However, it will still try to parse dependent mods to deal with event ids and stuff.
For the ignore, I think putting it right above "id = XXX" (i.e. not above the "country_event = { ... }" part) works
Code:
# don't put the ignore here
country_event = {
# put the ignore here
id = whatever
}
the ignore targets the node right below it, so in the case of yours, it's targeting country_event and not id.
This fixes the quote issue (by doing a hack of replacing all the slash+quote with empty in the .mod files, so it doesn't actually check that you have quotes around mods with spaces or anything, and one asks why cannot paradox just not care if there are quotes or not anyways)
I think it would be valuable to add a little more explanation to the "Did You Know.pdf", to clarify that "." only means "next statement" NOT "next line".
Added text in bold and underlined:
Let’s dissect what this means. “Audax Validator” are just keywords that indicate that the comment means something. The “.” specifies the target of the ignore command. A period just means: the next non-comment in the file. (In the example above, this corresponds to just the "AND" token, not the whole line. One way to think of this is: if you rewrote the code with the minimum possible amount on each line, a "." will suppress errors on the next line. In the example above, "AND = { ai = yes }" could be written as three lines, so the "." will only suppress the first of those three lines, ie. the "." will only suppress errors caused by the "AND".) Where does 1001 come from? It is from a list of error codes in Information/errorCodes.txt. You can find the code of the error you are trying to disable in here.
In the top right there is a menu which you can change to "Show main mod errors", which ideally should not show dependent mod errors. However, it will still try to parse dependent mods to deal with event ids and stuff.
Unfortunately, this really doesn't work for my use case. I need to include dependencies on workshop mods, which are zipped, which means they crash the Validation process if they are included as dependencies. (This probably affects other people too, but I have no idea how many.)
My current workaround is to comment-out the "dependencies" line in the .mod file before Validation. And uncomment it afterwards. But it's very easy to forget to uncomment it (and waste time doing useless/misleading testing), so this is not at all ideal.
Please could you think again about this issue?
Add a switch inside the Validator that forces it to NOT parse mod dependencies
IE: My previous request
If the Validator encounters a magic string in the .mod file then it won't parse that mod's dependencies
Eg. If "# Audax Validator IGNORE_DEPENDENCIES" exists in the .mod file then the Validator doesn't try to parse the dependencies
Allow the user to tell the Validator that the mod folder is in a different location
IE: Allow the user to specify something other than %USERPROFILE%\Documents\Paradox Interactive\Crusader Kings II\mod
The user could then set up a staging folder where everything is nicely arranged for the Validator, and use batch files etc to transfer back and forth from the "real" mod folder
Add the ability for the Validator to parse zip files
This would be a big task, but maybe worthwhile in the long run (eg. for other games)
7zip portable is very useful for these kinds of projects... but I'm not sure exactly what the licensing terms are...
I think it would be valuable to add a little more explanation to the "Did You Know.pdf", to clarify that "." only means "next statement" NOT "next line".
Unfortunately, this really doesn't work for my use case. I need to include dependencies on workshop mods, which are zipped, which means they crash the Validation process if they are included as dependencies. (This probably affects other people too, but I have no idea how many.)
My current workaround is to comment-out the "dependencies" line in the .mod file before Validation. And uncomment it afterwards. But it's very easy to forget to uncomment it (and waste time doing useless/misleading testing), so this is not at all ideal.
Please could you think again about this issue?
Add a switch inside the Validator that forces it to NOT parse mod dependencies
IE: My previous request
If the Validator encounters a magic string in the .mod file then it won't parse that mod's dependencies
Eg. If "# Audax Validator IGNORE_DEPENDENCIES" exists in the .mod file then the Validator doesn't try to parse the dependencies
Allow the user to tell the Validator that the mod folder is in a different location
IE: Allow the user to specify something other than %USERPROFILE%\Documents\Paradox Interactive\Crusader Kings II\mod
The user could then set up a staging folder where everything is nicely arranged for the Validator, and use batch files etc to transfer back and forth from the "real" mod folder
Add the ability for the Validator to parse zip files
This would be a big task, but maybe worthwhile in the long run (eg. for other games)
7zip portable is very useful for these kinds of projects... but I'm not sure exactly what the licensing terms are...
Is it difficult to maintain two .mod files, one of which is for development?
By crash do you mean actually crash or not do anything, or just emit errors about the mod? If it's the former then it might be possible to just report errors that a mod was ignored for being a zip. In any case, a simple repro would be useful.
But on another level, it does seem to be difficult for me to remember to re-enable dependencies before testing! And forgetting to do that can lead to an annoying waste of time.
By crash do you mean actually crash or not do anything, or just emit errors about the mod? If it's the former then it might be possible to just report errors that a mod was ignored for being a zip. In any case, a simple repro would be useful.
Sorry, I was unclear. The Validation process ends unexpectedly immediately after starting, because the Validator can't read the zipped dependent mod. See attached screenshot & zip file.
If you have two .mod files, wouldn't you have one of them remain enabled? And that one is called "Modname" and gets shipped, while the one called "Modname (Validator)" will have no dependencies and you'd never use it for anything except Validator?
If you have two .mod files, wouldn't you have one of them remain enabled? And that one is called "Modname" and gets shipped, while the one called "Modname (Validator)" will have no dependencies and you'd never use it for anything except Validator?
It's quite possible I've done something wrong here... but I can't think what!
See attached zip file for the relevant setup: I have two .mod files, one with the dependency line and one without. But the validator-only .mod file isn't recognised by the validator. (Speculation: Maybe the Validator requires both the "modname.mod" file and "modname" folder to exist, when in fact only the .mod file is needed?)
Which is weird, because it implies there are two completely different ways to tell the Validator to look at a particular mod: the mod name from inside the .mod file; and the name of the mod file or folder. Is this deliberate?
I discovered a potential oversight in the Validator: If you make a self-targeted decision (filter = self and/or ai_target_filter = self) then the criteria restricting who can take the decision need to be in the potential block, NOT the from_potential block.
The error.log warns about this:
[decision.cpp:752]: Usage of from potential on self targeted decision found, use potential instead! key: expd_tv_make_shieldmaiden_self
Discovered because I started having male shieldmaidens pop up in my game when I introduced a self-targeted decision aimed at making female warrior lodge members declare themselves to be shieldmaidens. (Because, seriously, Heroines should be shieldmaidens.)
Relevant (erroneous) code snippet below, full (erroneous) mod attached.
In this erroneous code, it appear that the entire from_potential clause is disregarded, because the decision is self-targeted. The fix, apparently, is to move everything from from_potential into potential, and delete from_potential.
Code:
targetted_decisions = {
expd_tv_make_shieldmaiden_self = {
# Female members of warrior lodges (including unlanded!) can declare themselves to be shieldmaidens
# Intended, mostly, to ensure that AI warriors declare themselves to be shieldmaidens
# (because they have the ability to make other people shieldmaidens)
# but this may be useful for the player too, occasionally.
is_in_society = yes
filter = self
ai_target_filter = self
ai_check_interval = 24
from_potential = {
is_female = yes
is_adult = yes
NOT = { trait = shieldmaiden }
is_member_of_any_warrior_lodge_trigger = yes
prisoner = no
}
potential = {
character = FROM
}
Important outstanding question: Does this same rule apply to all of the *_including_me scopes?
I discovered a potential oversight in the Validator: If you make a self-targeted decision (filter = self and/or ai_target_filter = self) then the criteria restricting who can take the decision need to be in the potential block, NOT the from_potential block.
The error.log warns about this:
...but the Validator (v1.34.17) does not.
Important outstanding question: Does this same rule apply to all of the *_including_me scopes?
I've come across this too. It does not apply to those other ones, from what I remember, which makes sense since they also target other characters than the decision taker.
I do have to wonder why Paradox decided to break syntax here, for so little gain.
Haven't exhaustively tested it, but it seems to be working perfectly.
Here are some more reports and various tidbits, if you're still willing to work on the Validator:
min_age and max_age do not work in create_character (and create_random_<occupation>), after more testing
A humble request:
Error code to ignore duplicate localisation keys (as per instructions in DidYouKnow.pdf and errorCodes.txt).
Currently CK2+ generates many of these needless warnings, likely due to being based on CleanSlate, which also contains all localisation from vanilla. I'd like to weed out these errors without disabling all validation of our localisation files, hence the above request.
Code:
At <mod>\events\mnm_job_offmap.txt [character_event] (Line 1467, column 1):
This hidden event has a title
Interesting quirk here. This event is indeed hidden, but the title is used for the tooltip in the list of possible job_action outcomes in the council screen.
Would it be possible to allow events listed there to have titles despite being hidden events?
At <mod>\events\mnm_hermetics_events.txt [character_event\immediate\if\FROM] (Line 16216, column 4):
Invalid use of 'FROM': No non-repeat_event calls found for .
Works as intended, all scopes provided by an on_action are passed on 'as is' by calling an event by means of repeat_event. I hope this one isn't too tricky.
Events below:
Code:
# ROOT is new artifact owner
# FROM is inherited artifact
# FROMFROM is previous owner
# CleanSlate meta event to sort out artifact inheritance logic
character_event = {
id = HFP.16004
is_triggered_only = yes # on_artifact_inheritance
hide_window = yes
immediate = {
if = {
limit = { FROM = { has_artifact_flag = ingredient } }
repeat_event = { id = MN.5108 } # Deal with inherited ingredients
}
else = {
random = {
chance = 5 # Old destruction chance
repeat_event = { id = HFP.16005 } # Deal with all other inherited artifacts
}
}
}
}
character_event = {
id = HFP.16005
is_triggered_only = yes
hide_window = yes
trigger = {
NOT = { has_character_flag = dealing_with_inherited_artifacts }
}
fail_trigger_effect = {
# If you are already dealing with another artifact, queue this one up...
repeat_event = {
id = HFP.16005
days = 12
}
}
immediate = {
if = { # AIs get the short stick...
limit = {
ai = yes
FROM = { is_indestructible = no }
}
FROM = { destroy_artifact = yes }
}
else = { # Players get a choice... (CleanSlate: as does AI for indestructible artifacts)
set_character_flag = dealing_with_inherited_artifacts
FROM = { save_event_target_as = inherited_artifact }
FROMFROM = { save_event_target_as = previous_owner }
character_event = {
id = HFP.16006 # Actual event
days = 5
}
}
}
}
# Dealing with inherited ingredients - delays the visible event
character_event = {
id = MNM.5108
is_triggered_only = yes
hide_window = yes
immediate = {
# FROMFROM = { save_event_target_as = previous_ingredient_owner } # does this work on dead folk?
if = {
limit = { ai = yes }
FROM = { destroy_artifact = yes }
}
else = {
set_character_flag = dealing_with_inherited_ingredients
if = {
limit = {
NOT = { has_character_flag = owns_inherited_ingredients }
}
set_character_flag = owns_inherited_ingredients
repeat_event = { id = MNM.5108 days = 10 } # if this is the first instance of this event, send this event again to check if you ever inherited more than one ingredient...
}
else_if = { # run second time around
limit = {
has_character_flag = owns_inherited_ingredients
any_artifact = {
count >= 2
has_artifact_flag = ingredient
}
}
repeat_event = { id = MNM.5109 } # send visible event
}
}
}
}
Code:
--- Error 1 of 2 ---
At <mod>\common\objectives\000_CK2Plus_factions.txt [faction_tradition\membership\additive_opinion_modifier\who] (Line 1326, column 4):
"FROM" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
--- Error 2 of 2 ---
At <mod>\common\objectives\000_CK2Plus_factions.txt [faction_tradition\membership\additive_opinion_modifier\this] (Line 1325, column 4):
"ROOT" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
Tested to work, see below. THIS and PREV also work here (and all stacked FROMs and ROOT_FROMs, of course, and saved event targets, whether normal, global or persistent).
Code:
namespace = test
character_event = {
id = test.1
is_triggered_only = yes
option = {
spouse = {
character_event = { id = test.2 }
}
}
}
character_event = {
id = test.2
is_triggered_only = yes
option = {
random = {
chance = 0
additive_opinion_modifier = {
factor = 1
this = FROM
who = ROOT
}
wealth = 1000
}
}
}
Code:
--- Error 1 of 2 ---
At <mod>\common\scripted_score_values\000_CK2Plus_faction_scores.txt [faction_glory_join_score\additive_exported_value_modifier\who] (Line 50, column 3):
"ROOT" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
* called from <mod>\common\objectives\000_CK2Plus_factions.txt [faction_glory\membership\faction_glory_join_score] (Line 930, column 3)
--- Error 2 of 2 ---
At <mod>\common\scripted_score_values\000_CK2Plus_faction_scores.txt [faction_glory_join_score\additive_exported_value_modifier\who] (Line 56, column 3):
"FROM" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
* called from <mod>\common\objectives\000_CK2Plus_factions.txt [faction_glory\membership\faction_glory_join_score] (Line 930, column 3)
Like above, tested to work with adjusted event test.2:
Code:
character_event = {
id = test.2
is_triggered_only = yes
option = {
random = {
chance = 0
faction_court_start_score = yes
faction_court_join_score = yes
wealth = 1000
}
}
}
faction_court_start_score = {
additive_exported_value_modifier = {
value = diplomacy
who = FROM
factor = 5
}
}
faction_court_join_score = {
additive_exported_value_modifier = {
value = diplomacy
who = ROOT
factor = 5
}
}
Code:
--- Error 1 of 2 ---
At <mod>\decisions\realm_decisions.txt [decisions\form_new_empire\effect\hidden_effect\else_if\create_title\base_title] (Line 2983, column 7):
"capital_scope" is not a valid AnyTitle or MaybeEventTargetCharProvTitle.
--- Error 2 of 2 ---
At <mod>\decisions\realm_decisions.txt [decisions\form_new_empire\effect\hidden_effect\else\create_title\base_title] (Line 3003, column 7):
"primary_title" is not a valid AnyTitle or MaybeEventTargetCharProvTitle.
Both tested to work. 'location' and 'family_palace' also work.
Code:
At <mod>\decisions\zz_CK2Plus_minor_decisions.txt [decisions\come_out_of_hiding_siege\allow\custom_tooltip\NOT\capital_scope\any_province_holding\OR\NOT\controlled_by] (Line 4423, column 17):
"holder_scope" is not a valid AnyTitle, MaybeEventTargetChar, or PrefixedCharId.
Tested to work. 'owner', being an alias of 'holder_scope' also works.
Code:
At <mod>\events\base_on_action_events.txt [narrative_event\immediate\if\set_title_landless\title] (Line 4085, column 5):
"event_target:religious_head_title" is not a valid "THIS" or AnyTitle.
Tested to work. Takes any relative title scope, in the form of ROOT, FROM, ROOT_FROM, etc. Script below:
At <mod>\decisions\settlement_decisions.txt [settlement_decisions\nomad_adopt_republicanism\effect\if\limit\FROM\any_realm_province\ROOT\NOT\is_capital] (Line 1609, column 17):
"PREV" is not a valid Bool.
Accepts scopes like ROOT and FROM, so PREV also works.
Code:
At <mod>\events\rip_physician_events.txt [character_event\option\event_target:recruited_physician_target\if\transfer_scaled_wealth\value] (Line 2735, column 6):
"local_physician_cost" is not a valid All, NnDbl, or VariableName.
This one is definitely working in-game. Script below. 'code' is in 'immediate', the other part is in 'option'. Perhaps that's where Validator has trouble. Variables prefixed with 'local_' are event variables, that are not saved in any scope and are carried along an unbroken event chain, the same way event targets are.
Code:
new_character = {
set_character_flag = no_court_invites
set_character_flag = is_court_physician
save_event_target_as = recruited_physician_target
trigger_switch = {
on_trigger = has_character_flag
physician_village_drunkard = { set_variable = { which = local_physician_cost value = 0.3 } }
physician_ships_physician = { set_variable = { which = local_physician_cost value = 0.1 } }
physician_wise_dwarf = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_jewish_exile = { set_variable = { which = local_physician_cost value = 0.2 } }
# physician_condemned_sorcerer # No cost
# physician_cynical_clergyman # No cost
physician_chinese_doctor = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_arab_scholar = { set_variable = { which = local_physician_cost value = 0.15 } }
physician_beloved_wise_man = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_wandering_genius = { set_variable = { which = local_physician_cost value = 0.35 } }
physician_erudite_herbalist = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_pagan_mystic = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_insane_zealot = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_well_traveled_pilgrim = { set_variable = { which = local_physician_cost value = 0.15 } }
physician_student_of_medicine = { set_variable = { which = local_physician_cost value = 0.03 } }
physician_blind_miracle_worker = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_field_surgeon = { set_variable = { which = local_physician_cost value = 0.3 } }
physician_schooled_eunuch = { set_variable = { which = local_physician_cost value = 0.15 } }
physician_pus_sucking_nun = { set_variable = { which = local_physician_cost value = 0.3 } }
# physician_witch # No cost
# physician_horse_md # No cost
physician_travelling_nestorian = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_mazdan_doctor = { set_variable = { which = local_physician_cost value = 0.25 } }
# physician_manichaean_merchant # No cost
}
}
if = {
limit = {
check_variable = {
which = local_physician_cost
value > 0
}
}
transfer_scaled_wealth = {
from = ROOT
value = local_physician_cost
min = 10
}
}
Haven't exhaustively tested it, but it seems to be working perfectly.
Here are some more reports and various tidbits, if you're still willing to work on the Validator:
min_age and max_age do not work in create_character (and create_random_<occupation>), after more testing
A humble request:
Error code to ignore duplicate localisation keys (as per instructions in DidYouKnow.pdf and errorCodes.txt).
Currently CK2+ generates many of these needless warnings, likely due to being based on CleanSlate, which also contains all localisation from vanilla. I'd like to weed out these errors without disabling all validation of our localisation files, hence the above request.
Code:
At <mod>\events\mnm_job_offmap.txt [character_event] (Line 1467, column 1):
This hidden event has a title
Interesting quirk here. This event is indeed hidden, but the title is used for the tooltip in the list of possible job_action outcomes in the council screen.
Would it be possible to allow events listed there to have titles despite being hidden events?
At <mod>\events\mnm_hermetics_events.txt [character_event\immediate\if\FROM] (Line 16216, column 4):
Invalid use of 'FROM': No non-repeat_event calls found for .
Works as intended, all scopes provided by an on_action are passed on 'as is' by calling an event by means of repeat_event. I hope this one isn't too tricky.
Events below:
Code:
# ROOT is new artifact owner
# FROM is inherited artifact
# FROMFROM is previous owner
# CleanSlate meta event to sort out artifact inheritance logic
character_event = {
id = HFP.16004
is_triggered_only = yes # on_artifact_inheritance
hide_window = yes
immediate = {
if = {
limit = { FROM = { has_artifact_flag = ingredient } }
repeat_event = { id = MN.5108 } # Deal with inherited ingredients
}
else = {
random = {
chance = 5 # Old destruction chance
repeat_event = { id = HFP.16005 } # Deal with all other inherited artifacts
}
}
}
}
character_event = {
id = HFP.16005
is_triggered_only = yes
hide_window = yes
trigger = {
NOT = { has_character_flag = dealing_with_inherited_artifacts }
}
fail_trigger_effect = {
# If you are already dealing with another artifact, queue this one up...
repeat_event = {
id = HFP.16005
days = 12
}
}
immediate = {
if = { # AIs get the short stick...
limit = {
ai = yes
FROM = { is_indestructible = no }
}
FROM = { destroy_artifact = yes }
}
else = { # Players get a choice... (CleanSlate: as does AI for indestructible artifacts)
set_character_flag = dealing_with_inherited_artifacts
FROM = { save_event_target_as = inherited_artifact }
FROMFROM = { save_event_target_as = previous_owner }
character_event = {
id = HFP.16006 # Actual event
days = 5
}
}
}
}
# Dealing with inherited ingredients - delays the visible event
character_event = {
id = MNM.5108
is_triggered_only = yes
hide_window = yes
immediate = {
# FROMFROM = { save_event_target_as = previous_ingredient_owner } # does this work on dead folk?
if = {
limit = { ai = yes }
FROM = { destroy_artifact = yes }
}
else = {
set_character_flag = dealing_with_inherited_ingredients
if = {
limit = {
NOT = { has_character_flag = owns_inherited_ingredients }
}
set_character_flag = owns_inherited_ingredients
repeat_event = { id = MNM.5108 days = 10 } # if this is the first instance of this event, send this event again to check if you ever inherited more than one ingredient...
}
else_if = { # run second time around
limit = {
has_character_flag = owns_inherited_ingredients
any_artifact = {
count >= 2
has_artifact_flag = ingredient
}
}
repeat_event = { id = MNM.5109 } # send visible event
}
}
}
}
Code:
--- Error 1 of 2 ---
At <mod>\common\objectives\000_CK2Plus_factions.txt [faction_tradition\membership\additive_opinion_modifier\who] (Line 1326, column 4):
"FROM" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
--- Error 2 of 2 ---
At <mod>\common\objectives\000_CK2Plus_factions.txt [faction_tradition\membership\additive_opinion_modifier\this] (Line 1325, column 4):
"ROOT" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
Tested to work, see below. THIS and PREV also work here (and all stacked FROMs and ROOT_FROMs, of course, and saved event targets, whether normal, global or persistent).
Code:
namespace = test
character_event = {
id = test.1
is_triggered_only = yes
option = {
spouse = {
character_event = { id = test.2 }
}
}
}
character_event = {
id = test.2
is_triggered_only = yes
option = {
random = {
chance = 0
additive_opinion_modifier = {
factor = 1
this = FROM
who = ROOT
}
wealth = 1000
}
}
}
Code:
--- Error 1 of 2 ---
At <mod>\common\scripted_score_values\000_CK2Plus_faction_scores.txt [faction_glory_join_score\additive_exported_value_modifier\who] (Line 50, column 3):
"ROOT" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
* called from <mod>\common\objectives\000_CK2Plus_factions.txt [faction_glory\membership\faction_glory_join_score] (Line 930, column 3)
--- Error 2 of 2 ---
At <mod>\common\scripted_score_values\000_CK2Plus_faction_scores.txt [faction_glory_join_score\additive_exported_value_modifier\who] (Line 56, column 3):
"FROM" is not a valid MaybeEventTargetChar or CharTargetExcludingMaybeEventTarget.
* called from <mod>\common\objectives\000_CK2Plus_factions.txt [faction_glory\membership\faction_glory_join_score] (Line 930, column 3)
Like above, tested to work with adjusted event test.2:
Code:
character_event = {
id = test.2
is_triggered_only = yes
option = {
random = {
chance = 0
faction_court_start_score = yes
faction_court_join_score = yes
wealth = 1000
}
}
}
faction_court_start_score = {
additive_exported_value_modifier = {
value = diplomacy
who = FROM
factor = 5
}
}
faction_court_join_score = {
additive_exported_value_modifier = {
value = diplomacy
who = ROOT
factor = 5
}
}
Code:
--- Error 1 of 2 ---
At <mod>\decisions\realm_decisions.txt [decisions\form_new_empire\effect\hidden_effect\else_if\create_title\base_title] (Line 2983, column 7):
"capital_scope" is not a valid AnyTitle or MaybeEventTargetCharProvTitle.
--- Error 2 of 2 ---
At <mod>\decisions\realm_decisions.txt [decisions\form_new_empire\effect\hidden_effect\else\create_title\base_title] (Line 3003, column 7):
"primary_title" is not a valid AnyTitle or MaybeEventTargetCharProvTitle.
Both tested to work. 'location' and 'family_palace' also work.
Code:
At <mod>\decisions\zz_CK2Plus_minor_decisions.txt [decisions\come_out_of_hiding_siege\allow\custom_tooltip\NOT\capital_scope\any_province_holding\OR\NOT\controlled_by] (Line 4423, column 17):
"holder_scope" is not a valid AnyTitle, MaybeEventTargetChar, or PrefixedCharId.
Tested to work. 'owner', being an alias of 'holder_scope' also works.
Code:
At <mod>\events\base_on_action_events.txt [narrative_event\immediate\if\set_title_landless\title] (Line 4085, column 5):
"event_target:religious_head_title" is not a valid "THIS" or AnyTitle.
Tested to work. Takes any relative title scope, in the form of ROOT, FROM, ROOT_FROM, etc. Script below:
At <mod>\decisions\settlement_decisions.txt [settlement_decisions\nomad_adopt_republicanism\effect\if\limit\FROM\any_realm_province\ROOT\NOT\is_capital] (Line 1609, column 17):
"PREV" is not a valid Bool.
Accepts scopes like ROOT and FROM, so PREV also works.
Code:
At <mod>\events\rip_physician_events.txt [character_event\option\event_target:recruited_physician_target\if\transfer_scaled_wealth\value] (Line 2735, column 6):
"local_physician_cost" is not a valid All, NnDbl, or VariableName.
This one is definitely working in-game. Script below. 'code' is in 'immediate', the other part is in 'option'. Perhaps that's where Validator has trouble. Variables prefixed with 'local_' are event variables, that are not saved in any scope and are carried along an unbroken event chain, the same way event targets are.
Code:
new_character = {
set_character_flag = no_court_invites
set_character_flag = is_court_physician
save_event_target_as = recruited_physician_target
trigger_switch = {
on_trigger = has_character_flag
physician_village_drunkard = { set_variable = { which = local_physician_cost value = 0.3 } }
physician_ships_physician = { set_variable = { which = local_physician_cost value = 0.1 } }
physician_wise_dwarf = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_jewish_exile = { set_variable = { which = local_physician_cost value = 0.2 } }
# physician_condemned_sorcerer # No cost
# physician_cynical_clergyman # No cost
physician_chinese_doctor = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_arab_scholar = { set_variable = { which = local_physician_cost value = 0.15 } }
physician_beloved_wise_man = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_wandering_genius = { set_variable = { which = local_physician_cost value = 0.35 } }
physician_erudite_herbalist = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_pagan_mystic = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_insane_zealot = { set_variable = { which = local_physician_cost value = 0.05 } }
physician_well_traveled_pilgrim = { set_variable = { which = local_physician_cost value = 0.15 } }
physician_student_of_medicine = { set_variable = { which = local_physician_cost value = 0.03 } }
physician_blind_miracle_worker = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_field_surgeon = { set_variable = { which = local_physician_cost value = 0.3 } }
physician_schooled_eunuch = { set_variable = { which = local_physician_cost value = 0.15 } }
physician_pus_sucking_nun = { set_variable = { which = local_physician_cost value = 0.3 } }
# physician_witch # No cost
# physician_horse_md # No cost
physician_travelling_nestorian = { set_variable = { which = local_physician_cost value = 0.2 } }
physician_mazdan_doctor = { set_variable = { which = local_physician_cost value = 0.25 } }
# physician_manichaean_merchant # No cost
}
}
if = {
limit = {
check_variable = {
which = local_physician_cost
value > 0
}
}
transfer_scaled_wealth = {
from = ROOT
value = local_physician_cost
min = 10
}
}
For easy testing, are these from a specific mod? (If not I can work with the samples you give, but a specific mod to test against is always convenient)
For easy testing, are these from a specific mod? (If not I can work with the samples you give, but a specific mod to test against is always convenient)
"AddFlag = Localization.IgnoreNonReplaceDuplicatesIfInVanilla" (works for main mod vs base mod localization, despite the name; the similar sounding one in the current version's settings file is a typo)
Works as intended, all scopes provided by an on_action are passed on 'as is' by calling an event by means of repeat_event. I hope this one isn't too tricky.
Events below:
So if I understand correctly, this is in title scope, and it is checking against a title to see if the current scope title is the capital of the other title?
This one is definitely working in-game. Script below. 'code' is in 'immediate', the other part is in 'option'. Perhaps that's where Validator has trouble. Variables prefixed with 'local_' are event variables, that are not saved in any scope and are carried along an unbroken event chain, the same way event targets are.
Is emf_nwo_create_female_ruler_effect defined correctly? From what I can tell `new_character` should be a part of it but is instead below. This causes Validator to think that the new_character in the call is a scripted_effect call, and hence not look under it for set_variable. I guess Validator can always look under even if it thinks it's a scripted_effect, but is naming scripted effects builtin things like `new_character` really valid?
"AddFlag = Localization.IgnoreNonReplaceDuplicatesIfInVanilla" (works for main mod vs base mod localization, despite the name; the similar sounding one in the current version's settings file is a typo)
So if I understand correctly, this is in title scope, and it is checking against a title to see if the current scope title is the capital of the other title?
In this case, it's checked in character scope, so it's checking if the target province is the capital of the scoped character. This trigger only works like that in character scope, so it's effectively an entirely different trigger than the one that's used in title and province scopes.
Is emf_nwo_create_female_ruler_effect defined correctly? From what I can tell `new_character` should be a part of it but is instead below. This causes Validator to think that the new_character in the call is a scripted_effect call, and hence not look under it for set_variable. I guess Validator can always look under even if it thinks it's a scripted_effect, but is naming scripted effects builtin things like `new_character` really valid?
There was indeed an issue there, exactly as you described, so there's no need to change anything in the Validator. I don't see how it was related to the issue at hand, but fixing the effect has fixed the report coming up.