[GS] Looking for some help with a leader trait

Zagaroth

Chieftain
Joined
Nov 27, 2009
Messages
60
I am creating a music focused civilization with a somewhat whimsical/fantastical element to it, and I want the leader trait to include granting a promotion to all units upon creation of a great work of music. I think I know all the things I need to call upon, but I'm having a bit of trouble getting all the parts assembled correctly.

So, I know my modifier will have a collection type of Player_Units, and will have an effect type of "EFFECT_ADJUST_UNIT_GRANT_EXPERIENCE", and that the argument should have a value of '-1' to grant exactly 1 level (per the Terracotta Army wonder).

I think I want RunOnce to be set to 0 (because I want it to happen every time a great work of music is created), and Permanent to be set to 1 (since the bonus never goes away).

Now, I'm looking to trigger this off of Event.GreatWorkCreated with a value of GREATWORKOBJECT_MUSIC, and I think I do that off of Owner/SubjectRequirementSetId, but my brain has decided to fry over parsing how to get that all working, it looks like I need to work down 2 or 3 more steps to get it laid out correctly, I'm just not sure how to lay this all out.

All suggestions welcome! For all I know there is a much easier way to do this that I am just missing.
 
Events.GreatWorkCreated is an lua event-hook. Lua event-hooks are not triggered from SQL/XML code or vice versa.

The game database (SQL/XML code) is locked and static before you ever get in-game from the start-up screens. Lua scripts run after you are in-game and cannot alter anything in the game's database. Lua hook-events are triggered by the appropriate activity happening as a result of real-time game-play, and do not access or pass along information from a Modifier, SubjectRequirementSet, RequirementSet, or anything else.

Events.GreatWorkCreated is triggered whenever a great work is created (as one would expect), but only has relevance within the lua script that is set up to run an lua function whenever this trigger event-hook is initiated by something that happens in the actual game. It has no relevance to anything done in SQL or XML code except in this particular case the game's core operating engine will send data to the lua script regarding for example which great work was created. When a great work is created it triggers the game's core engine to initiate lua's Events.GreatWorkCreated, which will provide to any function assigned to it the following arguments:
Code:
playerID  -- the player ID # from the lua Players table
unitID     -- the lua unit ID number of the actual ingame unit that created the great work. this is an lua object ID # and not an index value from database table <Units>
iCityPlotX -- the map grid X position of the city where the great work was placed
iCityPlotY -- the map grid Y position of the city where the great work was placed
buildingID -- the database table index # from table <Buildings> for the type of building where the great work was placed (Temple, Museum, etc)
greatWorkID -- the database table index # from table <GreatWorks> representing the individual great work created.
None of this references anything in any modifier table or any requjirementset, nor can lua be used to signal the game that a modifier's requirements have been met.

Lua code can read what is in the game's database for any game-table, but this is not the same thing as triggering based on what is in the game's database.
 
I'd be happy to trigger off of getting a great person instead, it'd be fewer promotions but was my original intent. But I'm not sure that'd be any easier. If that can't be done I'll try and think of something else.

I've also been working on a supplemental ability, and this one should work unless I misunderstand how it functions? This should grant one great musician point per combat victory/kill.

Code:
INSERT INTO    TraitModifiers   
        (TraitType,                                ModifierId                                        )
VALUES   ('TRAIT_LEADER_ZAG_SUMETAL_UA',            'MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'    );



INSERT INTO    DynamicModifiers
        (ModifierType,                                CollectionType,                EffectType                                        )
VALUES   ('MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS',        'COLLECTION_OWNER',        'EFFECT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL'    );



INSERT INTO    Modifiers
        (ModifierId,                                        ModifierType,                                OwnerRequirementSetId,                SubjectRequirementSetId,            RunOnce,    Permanent    )
VALUES   ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS',                'MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS',        NULL,                                NULL,                                0,            1            );
INSERT INTO    ModifierArguments
        (ModifierId,                                    Name,                        Value                        )
VALUES   ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'            'Amount',                    1                            ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'            'GreatPersonClassType',        'GREAT_PERSON_CLASS_MUSICIAN');

I also tried COLLECTION_ALL_UNITS, but that didn't seem to make a difference.
 
For my alternative to granting promotions, I'm thinking of trying to use EFFECT_ADJUST_PLAYER_STRENGTH_MODIFIER, and set the value equal to number of great musicians or great works of music, but this isn't an excel table and it wants an integer, so I don't know if it would accept a reference to a count or how to even reference those numbers. Once more I suspect I'd need to learn how to use Lua code, and as this is my first real mod is figure I should get a working mod via easier scripting before I try getting into Lua. I'm at least passingly familiar with XML and SQL.
 
I'd be happy to trigger off of getting a great person instead, it'd be fewer promotions but was my original intent. But I'm not sure that'd be any easier. If that can't be done I'll try and think of something else.

I've also been working on a supplemental ability, and this one should work unless I misunderstand how it functions? This should grant one great musician point per combat victory/kill.

Code:
INSERT INTO    TraitModifiers   
        (TraitType,                                ModifierId                                        )
VALUES   ('TRAIT_LEADER_ZAG_SUMETAL_UA',            'MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'    );



INSERT INTO    DynamicModifiers
        (ModifierType,                                CollectionType,                EffectType                                        )
VALUES   ('MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS',        'COLLECTION_OWNER',        'EFFECT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL'    );



INSERT INTO    Modifiers
        (ModifierId,                                        ModifierType,                                OwnerRequirementSetId,                SubjectRequirementSetId,            RunOnce,    Permanent    )
VALUES   ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS',                'MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS',        NULL,                                NULL,                                0,            1            );
INSERT INTO    ModifierArguments
        (ModifierId,                                    Name,                        Value                        )
VALUES   ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'            'Amount',                    1                            ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'            'GreatPersonClassType',        'GREAT_PERSON_CLASS_MUSICIAN');

I also tried COLLECTION_ALL_UNITS, but that didn't seem to make a difference.
You need to create a Unit Ability to which this modifier will be attached via table UnitAbilityModifiers.

In the definition of the Unitability you need to set "Inactive" as "true" (integer 1 in SQL)

You need to make sure all appropriate Unit-Classes such as CLASS_MELEE are register within table TypeTags to be valid for the UnitAbility.

Then your TraitModifier needs to be of ModiferType MODIFIER_PLAYER_UNITS_GRANT_ABILITY and its arguments needs to be of the type that designates the ability to be granted
Code:
	<Types>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Kind="KIND_ABILITY"/>
	</Types>
	<TypeTags>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_LANDCIVILIAN"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_RECON"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_MELEE"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_RANGED"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_SIEGE"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_HEAVY_CAVALRY"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_LIGHT_CAVALRY"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_RANGED_CAVALRY"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_ANTI_CAVALRY"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_HEAVY_CHARIOT"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_LIGHT_CHARIOT"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_BATTERING_RAM"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_SIEGE_TOWER"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_OBSERVATION"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_ANTI_AIR"/>
		<Row Type="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Tag="CLASS_GARDE"/>
	</TypeTags>
	<UnitAbilities>
		<Row UnitAbilityType="ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST" Name="LOC_ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST_NAME" Description="LOC_ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST_DESCRIPTION" Inactive="true"/>
	</UnitAbilities>
	<UnitAbilityModifiers>
		<Row>
			<UnitAbilityType>ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST</UnitAbilityType>
			<ModifierId>MOD_IGNORE_CROSSING_RIVERS_COST</ModifierId>
		</Row>
	</UnitAbilityModifiers>
	<Modifiers>
		<Row>
			<ModifierId>LRS_IGNORE_RIVERCROSSING_COST</ModifierId>
			<ModifierType>MODIFIER_PLAYER_UNITS_GRANT_ABILITY</ModifierType>
			<Permanent>true</Permanent>
		</Row>
	</Modifiers>
	<ModifierArguments>
		<Row>
			<ModifierId>LRS_IGNORE_RIVERCROSSING_COST</ModifierId>
			<Name>AbilityType</Name>
			<Value>ABILITY_LRS_IGNORE_CROSSING_RIVERS_COST</Value>
		</Row>
	</ModifierArguments>
	<TraitModifiers>
		<Row TraitType="TRAJANS_COLUMN_TRAIT" ModifierId="LRS_IGNORE_RIVERCROSSING_COST"/>
	</TraitModifiers>
There was already an existing MOD_IGNORE_CROSSING_RIVERS_COST that served my need when creating this set-up so instead of creating a new ModifierId for the UnitAbility I used the existing one. Most of the time however you will need to create the ModifierId for the UnitAbility as well as the one for the TraitModifier.
 
For my alternative to granting promotions, I'm thinking of trying to use EFFECT_ADJUST_PLAYER_STRENGTH_MODIFIER, and set the value equal to number of great musicians or great works of music, but this isn't an excel table and it wants an integer, so I don't know if it would accept a reference to a count or how to even reference those numbers. Once more I suspect I'd need to learn how to use Lua code, and as this is my first real mod is figure I should get a working mod via easier scripting before I try getting into Lua. I'm at least passingly familiar with XML and SQL.
SQL (and XML) columns are static. They are not dynamic. So you cannot give a "count" number or a formula. You have to give a direct integer value or a direct Boolean value, or a direct text-string where for example a tag is being referenced like "BUILDING_TEMPLE". There are a few specific ModifierTypes which allow "count at least" or "min distance" (etc) Name arguments in table ModifierArguments, but the Value setting for such a row in the table must be an integer, not a formula.

Civ6 uses SQLite rather than the more advanced versions of SQL so much that can be done with the more advanced SQL apps that allow the sort of spreadsheet conditional formulas you mention aren't available in SQLite.
 
Actually either of these ModifierTypes would allow attaching a modifier directly to all of a player's units:
ModifierType | CollectionType | EffectType
MODIFIER_PLAYER_UNITS_ATTACH_MODIFIER | COLLECTION_PLAYER_UNITS | EFFECT_ATTACH_MODIFIER
MODIFIER_PLAYER_UNITS_GRANT_ABILITY | COLLECTION_PLAYER_UNITS | EFFECT_GRANT_ABILITY
I just tend to use and think in terms of attaching a unit-ability rather than directly attaching a modifier to all of a player's units.
 
Thank you for all of this! This is a little more limiting than I'd like, so for today I'm going to just get the bonus Great Musician points going, and think on what else to do to complement it, as that half is kind of weak. I actually have three different ideas already (bonus yields from great works of music, units bonuses within x range of a Theater District, and having Great Musicians act like Great Generals), I just need to decide which one I think will fit best.

And your quote made me look Sulla up, looks like you have a typo though. :) Lucius Cornelius Sulla Felix has only one 'l' in Cornelius.

Also, I now hear your quote in the voice of Blue from Overly Sarcastic Productions. It sounds like the sort of quip he'd make.
 
OK, I'm having some trouble and I just can't figure it out. I've been tweaking parts of it back and forth to see if I just hadn't gotten something quite right, but I seem to be missing something still. I'll break it down into parts so I can explain what I think is going on. First, we are declaring types.

Code:
INSERT INTO    Types
        (Type,                                            Kind            )
VALUES    ('TRAIT_LEADER_ZAG_SUMETAL_UA',                    'KIND_TRAIT'    ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'            'KIND_MODIFIER'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS'            'KIND_ABILITY'    ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'    'KIND_MODIFIER'    ),
        ('MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'    'KIND_MODIFIER'    );
I have my trait, a ModifierId for that trait, the ability to be given to units, ModifierId for that ability, and a ModiferType to use to assign my effect to that ModifierId.

Now Typetags. I did my best to cover everything that could have some sort of combat. Quick question here: Can I assign tags here that don't exist in an unmodded game, so that it works with or without those mods? Like, if I added CLASS_SAMURAI to work with Radiant's Samurais and Monks mod, would that create any issues for someone using this mod with out Radiant's mod?

Code:
INSERT INTO    TypeTags
        (Type,                                    Tag                        )
VALUES    ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_RECON'            ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_MELEE'            ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_RANGED'            ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_SIEGE'            ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_HEAVY_CAVALRY'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_LIGHT_CAVALRY'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_RANGED_CAVALRY'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_ANTI_CAVALRY'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_HEAVY_CHARIOT'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_LIGHT_CHARIOT'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_BATTERING_RAM'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_SIEGE_TOWER'        ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_ANTI_AIR'        ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_WARRIOR_MONK'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_RELIGIOUS'        ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_NAVAL_MELEE'        ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_NAVAL_RANGED'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_NAVAL_RAIDER'    ),
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'CLASS_NAVAL_CARRIER'    );

On to trait. I have text tagged for the trait name and description pointers, and leader type is correct. This should assign the modifier to the trait.

Code:
INSERT INTO    Traits
        (TraitType,                            Name,                                        Description                                        )
VALUES    ('TRAIT_LEADER_ZAG_SUMETAL_UA',    'LOC_TRAIT_LEADER_ZAG_SUMETAL_UA_NAME',    'LOC_TRAIT_LEADER_ZAG_SUMETAL_UA_DESCRIPTION'    );

INSERT INTO    LeaderTraits
        (LeaderType,            TraitType                        )
VALUES    ('LEADER_ZAG_SUMETAL',    'TRAIT_LEADER_ZAG_SUMETAL_UA'    );

INSERT INTO    TraitModifiers   
        (TraitType,                                ModifierId                                        )
VALUES   
        ('TRAIT_LEADER_ZAG_SUMETAL_UA',            'MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'    );

Now we move on to defining our unit ability., and assigning it a modifier.

Code:
INSERT INTO UnitAbilities
        (UnitAbilityType,                        Name,                                            Description,                                            Inactive    )
VALUES    ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'LOC_ABILITY_ZAG_SUMETAL_UA_GPM_POINTS_NAME',    'LOC_ABILITY_ZAG_SUMETAL_UA_GPM_POINTS_DESCRIPTION'        1            );
INSERT INTO    UnitAbilityModifiers
        (UnitAbilityType,                            ModifierId                                )
VALUES   
        ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',        'MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'    );

We also need to create our Modtype for the ability.

Code:
INSERT INTO    DynamicModifiers
        (ModifierType,                                    CollectionType,                    EffectType                                        )
VALUES   
        ('MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY',    'COLLECTION_PLAYER_UNITS',        'EFFECT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL'    );

Now we assign modifier types to the modifier IDs, and make them permanent

Code:
INSERT INTO    Modifiers
        (ModifierId,                                        ModifierType,                                    OwnerRequirementSetId,                SubjectRequirementSetId,            RunOnce,    Permanent    )
VALUES   
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS',                'MODIFIER_PLAYER_UNITS_GRANT_ABILITY',            NULL,                                NULL,                                0,            1            ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY',        'MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY',    NULL,                                NULL,                                0,            1            );

And then finally, we feed our arguments to the ModifierType. The first argument is what assigns the previously defined ability to the units, the next two fill in the variables for the effect.

Code:
INSERT INTO    ModifierArguments
        (ModifierId,                                        Name,                        Value                            )
VALUES   
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS'                'AbilityType',                'ABILITY_ZAG_SUMETAL_UA_GPM_POINTS'    ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'        'GreatPersonClassType',        'GREAT_PERSON_CLASS_MUSICIAN'        ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'        'Amount',                    1        );



So now I'm just at a loss trying to figure this out.
 
syntax error
Code:
INSERT INTO UnitAbilities
        (UnitAbilityType,                        Name,                                            Description,                                            Inactive    )
VALUES    ('ABILITY_ZAG_SUMETAL_UA_GPM_POINTS',    'LOC_ABILITY_ZAG_SUMETAL_UA_GPM_POINTS_NAME',    'LOC_ABILITY_ZAG_SUMETAL_UA_GPM_POINTS_DESCRIPTION'        1            );
You are missing a needed comma to separate 'LOC_ABILITY_ZAG_SUMETAL_UA_GPM_POINTS_DESCRIPTION' from 1

You need to inspect database.log and cure any syntax errors before proceeding to anything else (such as testing in-game whether you get the result you expected).

-------------------------

Also, ModifierId's never need to be declared as "Types". They are not KIND_MODIFIER, they are merely tag-names to hang the ModifierType and the RequirementSets upon.

Only a new ModifierType needs to be defined as a KIND_MODIFIER in table "Types". The clue is the use of "__Type" in the parent table:
Code:
BuildingType	"KIND_BUILDING"
BeliefType	"KIND_BELIEF"
CivicType	"KIND_CIVIC"
ModifierType	"KIND_MODIFIER"
etc

-------------------------------------------------

Get rid of this entirely because you don't need it
Code:
INSERT INTO    DynamicModifiers
        (ModifierType,                                    CollectionType,                    EffectType                                        )
VALUES   
        ('MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY',    'COLLECTION_PLAYER_UNITS',        'EFFECT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL'    );
The MODIFIER_PLAYER_UNITS_GRANT_ABILITY' ModifierType gives the specified Unitability to all of a player's units, so you want the ModifierId attached to the Unitability to have a COLLECTION_OWNER (ie, the unit owns the modifier that has been attached to it) and an effect-type of 'EFFECT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL'. There is already an existing ModifierType which is defined in table DynamicModifiers for this very thing
ModifierType | CollectionType | EffectType
MODIFIER_PLAYER_UNIT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL | COLLECTION_OWNER | EFFECT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL
So
Code:
INSERT INTO    Modifiers
        (ModifierId,                                        ModifierType,                                    OwnerRequirementSetId,                SubjectRequirementSetId,            RunOnce,    Permanent    )
VALUES   
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS',                'MODIFIER_PLAYER_UNITS_GRANT_ABILITY',            NULL,                                NULL,                                0,            1            ),
        ('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY',        'MODIFIER_PLAYER_UNIT_ADJUST_GREAT_PEOPLE_POINTS_PER_KILL',    NULL,                                NULL,                                0,            1            );
and you can get rid of these entirely for the reasons just mentioned
Code:
('MODIFIER_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'    'KIND_MODIFIER'    ),
        ('MODTYPE_ZAG_SUMETAL_UA_GPM_POINTS_ABILITY'    'KIND_MODIFIER'    )

-----------------------

So far as compatibility to Unique CLASS_X tags added by other mods, if those mods are structured "normally" they will usually also give one or more of the "base" Unit-Class designations to the unit, like CLASS_MELEE.

If not, it is usually best to take those other mods into account on an as-needed bases and in separate UpdateDatabase Actions where the compatibility code cannot bork the main part of your code.
 
Alright, Looks like some of what is in Keniisu's template isn't needed (which is why I thought I needed to add a Dynamic Modifier entry). Looks like I just need to declare the ability and the trait then. and I was using this spread sheet as my source for effects: https://docs.google.com/spreadsheet...D_xTTld4sFEyMxrDoPwX2NUFc/edit#gid=1391246980 rather than looking at what's already in the table, which I only just now thought to look for (and found).

I think for future proofing, I'm going to add CLASS_ALL_COMBAT_UNITS which should catch anything capable of combat. Which also means I probably don't need most of the rest of the tags, but it's probably better to be redundant here, for maximum compatibility.

Oh, and I think Radiant made a new class so that he could keep everything orderly when he created a new set of promotions.

I'll finish fixing things, double check my database.log, and give a test. Modbody wasn't giving me any errors on the build, so I wasn't looking for another locations.
 
YESSS! it worked! Thank You!

This also made me double check myself before I rebuilt and I had missed more commas too.
 
Modbuddy doesn't check for syntax errors when building. It only reports errors that are related to not being able to open a file, find a file, etc.

Even if you open an SQL or XML file in Modbuddy and the page shows syntax errors in the file, this has no effect whatever on the error-messages Modbuddy gives when building the mod. So you have to use Database.log to check for syntax errors, missing reference elements, and the like.

The code in your SQL or XML file can be absolute nonsense and so long as it is formatted properly Modbuddy will not show errors when you open the file -- so again, Database.log is the place to look.
 
Get a Database viewer program that can open SQLite database files. Such as SQLite Browser. There are several such programs available for free as downloads on the internet. You can then inspect the game database directly. ChimpanG's spreadsheet is still very useful, but being able to inspect directly the complete contents of table DynamicModifiers is invaluable in multiple ways, not the least of which is seeing what has already been defined for usage as ModifierTypes.

Being able to open the game database directly is also useful as a debugging tool because if all else fails when trying to find a reported syntax error you can check what parts of a given file actually got added to the database, and thereby better determine where the syntax error is located.

The InGame Database is found at
C:\Users\UserName\Documents\My Games\Sid Meier's Civilization VI\Cache/DebugGameplay.sqlite
File "DebugConfiguration.sqlite" is for the FrontEnd Database.

File "DebugLocalization.sqlite" is for the Text Localization Database but does not include anything added by the two expansions or stuff added by mods. If this confuses you a bit that is all thanks to Firaxis.
 
Top Bottom