Tutorial: Modding with SQLLite Studio (PC)

I followed this tutorial when creating my mod and I've hit a roadblock. I started adding new icons for a couple techs/buildings/projects. It took me a while to hunt down the info on how to do it, and now I have a custom icon for one of my new projects. It loads correctly and shows in game and I'm happy with that. Next, I wanted to add a texture for one of my new buildings. I made my dds file the same way I did for the project. I declare it, load it, etc. all exactly the same. I'm declaring my <File>s in my modinfo, then again under the import section and finally I'm referencing them in my icon.xml when I'm declaring my atlases. Again, I already have a texture loading in the game. But here's the difference: when I try to add more than exactly 1 of the resolutiona of my building, I get an immediate crash upon creating or loading a game. The game automatically exits, with a popup asking if I want to submit the bug report. Upon checking the packaged dump folder, the crash report seems very hard to understand, but there seems to be something about an attempt to illegally access a memory address. Then there are some addresses given, such as the exe of the game in the steam folder and a few references to locations i system32. I don't get it and I'm struggling here. I can't understand what I've done incorrectly. Does anyone have any idea what might be causing this?

I've looked through all the files in the Log folder, and nothing there was helpful. Could there be some other location I could find the problem or some sort of debugging mode I can turn on that will give me more information? I havent used any of the dev tools when creating my mod, only direct xml and sql edits. should i be using mod buddy? what IS mod buddy?
 
Hi dunkleosteus, if you are adding icons or any artwork, I would strongly suggest that you use the tools provided by firaxis and use their assets as a guide to make your own. Ideally a mod with artwork should not even contain any DDS files in the mods folder (they get packed into BLP files). The mod tools will create .dep and .blp files that cannot be generated in any other way that I know of.https://forums.civfanatics.com/members/dunkleosteus.271795/
 
Hey man you are awesome doing this, giving back is what life is all about. You have helped me understand modding of civ6 a lot, I have been playing since 1998 :P This is a pleasure reading the details and you went out of your way to help Chillbaka1 like it was natural. I admire that myself, it is called being in service to others. Where most people are in service to themselves, you sir are very cool! Thanks very much! :D
 
I've been trying my hand at creating a mod using sql using this guide, and it has been very interesting so far, but it seems that I run into some sort of load issue. Does anyone have any idea why that would be ?

The goal of this small mod is to change the leader trait of Wilhelmina to have an extra economic policy slot

This is what I have in my Billionaire.modinfo file,
Code:
<?xml version="1.0" encoding="utf-8"?>
<Mod id="5a49c033-8f55-486a-a238-4a10de74eb66" version="1">
    <Properties>
        <Name>Queen Wilhelmina Billionaire</Name>
        <Teaser>Adds Economic Policy slot to Wilhelmina</Teaser>
        <Description>Changes Wilhelmina's leader trait from "Radio Oranje" to "Billionaire", which simply adds an economic policy slot.</Description>
        <Authors>Put your name here</Authors>
    </Properties>

    <Files>
        <File>Billionaire.sql</File>
    </Files>

    <Components>
        <UpdateDatabase id="Gameplay">
            <Items>
                 <File>Billionaire.sql</File>
            </Items>
        </UpdateDatabase>
    </Components>
</Mod>

And this is the contents of my Billionaire.sql file
Code:
UPDATE LeaderTraits SET TraitType='TRAIT_BILLIONAIRE' WHERE LeaderType='LEADER_WILHELMINA';

INSERT INTO TraitModifiers          
        (TraitType,                                            ModifierId)
VALUES    ('TRAIT_BILLIONAIRE',                                'TRAIT_ECONOMIC_GOVERNMENT_SLOT');

INSERT INTO Modifiers  
        (ModifierId,                                        ModifierType,                                                    Permanent)
VALUES    ('TRAIT_ECONOMIC_GOVERNMENT_SLOT',                    'MODIFIER_PLAYER_CULTURE_ADJUST_GOVERNMENT_SLOTS_MODIFIER',        0);
   
INSERT INTO ModifierArguments
        (ModifierId,                                        Name,                        Value)
VALUES    ('TRAIT_ECONOMIC_GOVERNMENT_SLOT',                    'GovernmentSlotType',        'SLOT_ECONOMIC');

Any and all help is appreciated.

EDIT; problem solved over here https://forums.civfanatics.com/threads/sql-modding-issue-leader-trait-change.644749/#post-15427609
 
Last edited:
I've been trying my hand at creating a mod using sql using this guide, and it has been very interesting so far, but it seems that I run into some sort of load issue. Does anyone have any idea why that would be ?

The goal of this small mod is to change the leader trait of Wilhelmina to have an extra economic policy slot

This is what I have in my Billionaire.modinfo file,
Code:
<?xml version="1.0" encoding="utf-8"?>
<Mod id="5a49c033-8f55-486a-a238-4a10de74eb66" version="1">
    <Properties>
        <Name>Queen Wilhelmina Billionaire</Name>
        <Teaser>Adds Economic Policy slot to Wilhelmina</Teaser>
        <Description>Changes Wilhelmina's leader trait from "Radio Oranje" to "Billionaire", which simply adds an economic policy slot.</Description>
        <Authors>Put your name here</Authors>
    </Properties>

    <Files>
        <File>Billionaire.sql</File>
    </Files>

    <Components>
        <UpdateDatabase id="Gameplay">
            <Items>
                 <File>Billionaire.sql</File>
            </Items>
        </UpdateDatabase>
    </Components>
</Mod>

And this is the contents of my Billionaire.sql file
Code:
UPDATE LeaderTraits SET TraitType='TRAIT_BILLIONAIRE' WHERE LeaderType='LEADER_WILHELMINA';

INSERT INTO TraitModifiers          
        (TraitType,                                            ModifierId)
VALUES    ('TRAIT_BILLIONAIRE',                                'TRAIT_ECONOMIC_GOVERNMENT_SLOT');

INSERT INTO Modifiers  
        (ModifierId,                                        ModifierType,                                                    Permanent)
VALUES    ('TRAIT_ECONOMIC_GOVERNMENT_SLOT',                    'MODIFIER_PLAYER_CULTURE_ADJUST_GOVERNMENT_SLOTS_MODIFIER',        0);
   
INSERT INTO ModifierArguments
        (ModifierId,                                        Name,                        Value)
VALUES    ('TRAIT_ECONOMIC_GOVERNMENT_SLOT',                    'GovernmentSlotType',        'SLOT_ECONOMIC');

Any and all help is appreciated.


Have you looked in Database.log to see if there are errors?

I'd start by reversing the order of the commands.


INSERT INTO Modifiers
(ModifierId, ModifierType, Permanent)
VALUES ('TRAIT_ECONOMIC_GOVERNMENT_SLOT', 'MODIFIER_PLAYER_CULTURE_ADJUST_GOVERNMENT_SLOTS_MODIFIER', 0);

INSERT INTO ModifierArguments
(ModifierId, Name, Value)
VALUES ('TRAIT_ECONOMIC_GOVERNMENT_SLOT', 'GovernmentSlotType', 'SLOT_ECONOMIC');

INSERT INTO TraitModifiers
(TraitType, ModifierId)
VALUES ('TRAIT_BILLIONAIRE', 'TRAIT_ECONOMIC_GOVERNMENT_SLOT');


You need to create the TRAIT_ECONOMIC_GOVERNMENT_SLOT before you can insert it into TraitModifiers.
 
Your tutorial really helped me starting with SQL modding but I've got a problem and no clue as to what is causing it, but it seems to be related with the expansion packs. I created my own version of the "half production costs" mod and discovered that it doesn't update the database of the units and buildings from the expansions.

The code is as follows and the dependencies of the modinfo are properly set to include both expansions and all DLC.

-- Buildings cost
UPDATE Buildings
SET Cost = ROUND(Cost /4)
WHERE Cost > 1;

-- Units cost
UPDATE Units
SET Cost = ROUND(Cost /4)
WHERE Cost > 1;

As expected, this reduces the cost of all vanilla units and buildings to 1/4, as well as those from standalone DLC like Poland (It didn't affect DLC before I included their dependencies in the modinfo). However, units and buildings which were included or modified in the expansions (like the Knight and Mamluk, whose cost got changed to 220) aren't affected by the mod.

I also tried to individually change the cost of each unaffected unit in the sql but it didn't work either, which means that for some reason it is failing to update anything within either Rise and Fall or Gathering Storm.
 
Your tutorial really helped me starting with SQL modding but I've got a problem and no clue as to what is causing it, but it seems to be related with the expansion packs. I created my own version of the "half production costs" mod and discovered that it doesn't update the database of the units and buildings from the expansions.

The code is as follows and the dependencies of the modinfo are properly set to include both expansions and all DLC.

-- Buildings cost
UPDATE Buildings
SET Cost = ROUND(Cost /4)
WHERE Cost > 1;

-- Units cost
UPDATE Units
SET Cost = ROUND(Cost /4)
WHERE Cost > 1;

As expected, this reduces the cost of all vanilla units and buildings to 1/4, as well as those from standalone DLC like Poland (It didn't affect DLC before I included their dependencies in the modinfo). However, units and buildings which were included or modified in the expansions (like the Knight and Mamluk, whose cost got changed to 220) aren't affected by the mod.

I also tried to individually change the cost of each unaffected unit in the sql but it didn't work either, which means that for some reason it is failing to update anything within either Rise and Fall or Gathering Storm.


This is most likely a load order issue being caused by your mod loading prior to the expansions. Look on the forums for some examples of how you put load order in the modinfo. Load order wasn't an issue when I first wrte this tutorial.
 
This is most likely a load order issue being caused by your mod loading prior to the expansions. Look on the forums for some examples of how you put load order in the modinfo. Load order wasn't an issue when I first wrte this tutorial.

Yeah it was a problem with the load order, thanks. I was confused because it worked with all the DLC but not the expansions.
 
Awesome tutorial, learned a lot!
I'm still really new to this and want to learn more. I would love to change the leader ability of Gorgo where she receives culture from kills to receiving production from kills.
I have really no idea how to do that and if that is possible in the first place...

Anyone able to help me?
 
Awesome tutorial, learned a lot!
I'm still really new to this and want to learn more. I would love to change the leader ability of Gorgo where she receives culture from kills to receiving production from kills.
I have really no idea how to do that and if that is possible in the first place...

Anyone able to help me?


Production is a local rather than a Global yield so as far as I know this will not work out of the box. There may be some creative way to make it worth with Lua.

Faith, Science, or Gold would be fairly easy to do.
 
Gosh.. i've missed soooooo much precious SQL/Editing details that i might have screwed up my multi-tasking attempts to enhance the CHMZ mod enough with proper INSERT statements where & how they should.
I'll release the initial version (UPDATES and SETS -- minimally direct so far) this week-end anyway.. but i'll make sure to come back right here to discuss whatever else if need be.
Thanks for the minimal tutorial basics -- it must be fully understood to grasp the required (more complex) skills for sure.
 
Okay -- i am almost ready to try INSERT(s) & the necessary other instructions to activate custom Wonders/GFX validity on the Timeline with dedicated Moments of their own.

Refer to the Mod here ... (( https://steamcommunity.com/sharedfiles/filedetails/?id=1737288652 )) and take a look at the last preview image for details.

The SQL coding i think could work as is...
Code:
--CHMZ(W)_Wonders Bonus (by Zyxpsilon)  .. to DO!
--Init Phase

INSERT INTO MomentIllustrationType (  'MOMENT_ILLUSTRATION_WONDER'  )

INSERT INTO MomentIllustrations (  MomentIllustrationType, MomentDataType, GameDataType, Texture  )
            VALUES (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_GREAT_BATH', 'CHMZ_Moment_Wonder_GreatBath.dds'  );
--... until all *49* instances have been listed here!

--Final Hook "replacer(s) of the default Small/Moments cycle" for each Wonders as declared above!

UPDATE [Moments]
SET [BackgroundTexture] = NULL, [IconTexture] = NULL, [MomentIllustrationType] = 'MOMENT_ILLUSTRATION_WONDER'
WHERE ([MomentType] = 'MOMENT_BUILDING_CONSTRUCTED_GAME_ERA_WONDER');

UPDATE [Moments]
SET [BackgroundTexture] = NULL, [IconTexture] = NULL, [MomentIllustrationType] = 'MOMENT_ILLUSTRATION_WONDER'
WHERE ([MomentType] = 'MOMENT_BUILDING_CONSTRUCTED_PAST_ERA_WONDER');

Can anyone confirm or indicate whatever else i must do to make sure? There's 49 unique Insert/Steps to create. If the regular system in place allows for proper Natural Wonders dispatch via such ILLUSTRATIONS method.. i don't see why it shoudn't with these pre-formatted "Buildings" (which LOC-Strings are already pulled by those OLD/CURRENT GameDataTypes anyway, right?) as well, IMO.

So better start anything rationally than regret everything later! :scan:

Just for kicks -- that's the GREAT BATH in question...

BG(Mask1)_GreatBath.png

:)

OH -- @isau + @Infixo ... this might help getting some precious attention(s).
 
Last edited:
Okay.. i just gave the above an honest attempt by listing all 6 Ancient Era Wonders & it failed miserably.
Even managed to scrap the DebugGameplay file a few times. Could reset everything back as "normal" it seems.

Sooooooo.. until someone could help out, sadly i'm just stuck without clues how to fix these problems.

:dunno:
:please:
 
Something suddenly just blasted off my mind...
Code:
INSERT INTO MomentIllustrationTypes (  'MOMENT_ILLUSTRATION_TYPE'  )
       VALUES (  'MOMENT_ILLUSTRATION_WONDER'  );

Haven't officially tried this little fix yet.. but i suppose the new proper TYPE for WONDER wasn't registering correctly without the necessary VALUE!
Formatting gimmick & absurb newbie error.
:crazyeye:
 
FINALLY.. success!
With a bit more tricky adjustments to the CHMZ_Wondering.SQL code like this...
Code:
INSERT INTO MomentIllustrationTypes (  'MOMENTILLUSTRATIONTYPE'  )
       VALUES (  'MOMENT_ILLUSTRATION_WONDER'  );

INSERT INTO MomentIllustrations (  MomentIllustrationType, MomentDataType, GameDataType, Texture  )
--Ancient(6)
       VALUES (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_GREAT_BATH', 'CHMZ_Moment_Wonder_GreatBath.dds'  ),
       (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_STONEHENGE', 'CHMZ_Moment_Wonder_Stonehenge.dds'  ),
       (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_HANGING_GARDENS', 'CHMZ_Moment_Wonder_HangingGardens.dds'  ),
       (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_PYRAMIDS', 'CHMZ_Moment_Wonder_Pyramids.dds'  ),
       (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_ORACLE', 'CHMZ_Moment_Wonder_Oracle.dds'  ),
       (  'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_TEMPLE_ARTEMIS', 'CHMZ_Moment_Wonder_TempleArtemis.dds'  );
--... until all *49* instances have been listed here!

UPDATE [Moments]
SET [InterestLevel] = '3', [BackgroundTexture] = NULL, [MomentIllustrationType] = 'MOMENT_ILLUSTRATION_WONDER'
WHERE ([MomentType] = 'MOMENT_BUILDING_CONSTRUCTED_GAME_ERA_WONDER');

UPDATE [Moments]
SET [InterestLevel] = '3', [BackgroundTexture] = NULL, [MomentIllustrationType] = 'MOMENT_ILLUSTRATION_WONDER'
WHERE ([MomentType] = 'MOMENT_BUILDING_CONSTRUCTED_PAST_ERA_WONDER');

The initial result is precisely how the whole gimmick should work ingame...

IT-Worked_GreatBath.png


Very happy conclusion to this first step of intended major features.
Soooooo.. i'll have some more tricky questions (two other specific subjects) in a few days -- **IF** i'm stuck again.
 
Hello Isau, thanks for your post...

I'm currently working on a mod to include Civ V wonders into CivVI. I wrote a code in Notepad++ and when I tried to test it in SQLite, I got this:

upload_2019-5-14_17-0-30.png


I really do not understand what happened. I rewrote and checked some mistakes, but I still cannot figure out what the problem is. If there's not much trouble for you, can you offer me some insight on what I'm doing wrong and how to avoid it?

I also get this:

[17:07:57] Error while executing SQL query on database 'DebugGameplay': FOREIGN KEY constraint failed

I have no idea...

This is what I've been trying so far...

-----------------------------------------------
-- Types
-----------------------------------------------

INSERT INTO Types
(Type, Kind )
VALUES ('BUILDING_GLOBE_THEATRE', 'KIND_BUILDING' );

-----------------------------------------------------------------------------------
-- Buildings
-----------------------------------------------------------------------------------

INSERT INTO Buildings
(BuildingType, Name, PrereqTech, PrereqCivic, Cost, MaxPlayerInstances, MaxWorldInstances, Capital, PrereqDistrict, AdjacentDistrict, Description, RequiresPlacement, RequiresRiver, OuterDefenseHitPoints, Housing, Entertainment, AdjacentResource, Coast, EnabledByReligion, AllowsHolyCity, PurchaseYield, MustPurchase, Maintenance, IsWonder, TraitType, OuterDefenseStrength, CitizenSlots, MustBeLake, MustNotBeLake, RegionalRange, AdjacentToMountain, ObsoleteEra, RequiresReligion, GrantFortification, DefenseModifier, InternalOnly, RequiresAdjacentRiver, Quote, QuoteAudio, MustBeAdjacentLand, AdvisorType, AdjacentCapital, AdjacentImprovement, CityAdjacentTerrain, UnlocksGovernmentPolicy, GovernmentTierRequirement)
VALUES ('BUILDING_GLOBE_THEATRE', 'LOC_BUILDING_GLOBE_THEATRE_NAME', 'TECH_PRINTING', NULL, 820, -1, 1, 0, NULL, NULL, 'LOC_BUILDING_GLOBE_THEATRE_DESCRIPTION', 1, 0, NULL, 0, 1, NULL, NULL, 0, 0, NULL, 0, 0, 1 NULL, 0, NULL, 0, 0, 0, 0, 'NO_ERA' 0, 0, 0, 0, 0, 'LOC_BUILDING_GLOBE_THEATRE_QUOTE', NULL, 0, 'ADVISOR_GENERIC', 0, NULL, NULL, 0, NULL );

-----------------------------------------------------------------------------------
-- Building_YieldChanges
-----------------------------------------------------------------------------------

INSERT INTO Building_YieldChanges
(BuildingType, YieldType, YieldChange )
VALUES ('BUILDING_GLOBE_THEATRE', 'YIELD_CULTURE', 2 );

-----------------------------------------------------------------------------------
-- Building_GreatWorks
-----------------------------------------------------------------------------------

INSERT INTO Building_GreatWorks
(BuildingType, GreatWorkSlotType, NumSlots, ThemingUniquePerson, ThemingUniqueObjectType, ThemingUniqueCivs, ThemingSameEras, ThemingYieldMultiplier, NonUniquePersonYield, NonUniquePersonTourism, ThemingBonusDescription )
VALUES ('BUILDING_GLOBE_THEATRE', 'GREATWORKSLOT_WRITING', 2, 1, 1, 1, 1, 100, 0, 0, 'LOC_MAGIL_WW_THEMINGBONUS_WRITING' );

-----------------------------------------------------------------------------------
-- Building_ValidTerrains
-----------------------------------------------------------------------------------

INSERT INTO Building_ValidTerrains
(BuildingType, TerrainType )
VALUES ('BUILDING_GLOBE_THEATRE', 'TERRAIN_GRASS' ),
('BUILDING_GLOBE_THEATRE', 'TERRAIN_PLAINS' ),
('BUILDING_GLOBE_THEATRE', 'TERRAIN_TUNDRA' ),
('BUILDING_GLOBE_THEATRE', 'TERRAIN_SNOW' ),
('BUILDING_GLOBE_THEATRE', 'TERRAIN_DESERT' );

-----------------------------------------------------------------------------------
-- Modifiers
-----------------------------------------------------------------------------------

INSERT INTO Modifiers
(ModifierId, ModifierType, RunOnce, NewOnly, Permanent, OwnerRequirementSetId, SubjectRequirementSetId, OwnerStackLimit, SubjectStackLimit )
('GLOBE_THEATRE_GRANT_WRITER', 'MODIFER_SINGLE_CITY_GRANT_GREAT_PERSON_CLASS_IN_CITY', 1, 0, 1, NULL, 'GOLDEN_GLOBE_WRITER_REQUIREMENTS' NULL, NULL );

-----------------------------------------------------------------------------------
-- ModifierArguments
-----------------------------------------------------------------------------------

INSERT INTO ModifierArguments
(ModifierId, Name, Type, Value, Extra, SecondExtra )
VALUES 'GLOBE_THEATRE_GRANT_WRITER', 'GreatPersonClassType', 'ARGTYPE_IDENTITY', 'GREAT_PERSON_CLASS_WRITER', NULL, NULL ),
'GLOBE_THEATRE_GRANT_WRITER', 'Amount' 'ARGTYPE_IDENTITY', 1, NULL, NULL );

-----------------------------------------------------------------------------------
-- Requirements
-----------------------------------------------------------------------------------

INSERT INTO Requirements
(RequirementId, RequirementType, Likeliness, Impact, Inverse, Reverse, Persistent, ProgressWeight, Triggered )
VALUES ('REQUIRES_PLAYER_CAN_EVER_EARN_WRITER', 'REQUIREMENT_PLAYER_CAN_EVER_EARN_GREAT_PERSON_CLASS', 0, 0, 0, 0, 0, 1, 0 );

-----------------------------------------------------------------------------------
-- RequirementSetRequirements
-----------------------------------------------------------------------------------

INSERT INTO RequirementSetRequirements
(RequirementSetId, RequirementId )
VALUES ('GLOBE_THEATRE_WRITER_REQUIREMENTS', 'REQUIRES_PLAYER_CAN_EVER_EARN_WRITER' );

-----------------------------------------------------------------------------------
-- RequirementArguments
-----------------------------------------------------------------------------------

INSERT INTO RequirementArguments
(RequirementId, Name, Type, Value, Extra, SecondExtra )
VALUES ('REQUIRES_PLAYER_CAN_EVER_EARN_WRITER', GreatPersonClass, 'ARGTYPE_IDENTITY', 'GREAT_PERSON_CLASS_WRITER', NULL, NULL );

-----------------------------------------------------------------------------------
-- RequirementSets
-----------------------------------------------------------------------------------

INSERT INTO RequirementSets
(RequirementSetId, RequirementSetType )
VALUES ('GLOBE_THEATRE_WRITER_REQUIREMENTS', 'REQUIREMENTSET_TEST_ALL' );
Thanks a lot
 
Last edited:
Ya know what the real difference is between THEATER & THEATRE.. easy, two hours worth of Hit'n'Run quest for buggy SQL that keeps crashing a mod.

All it took was this silly typo..
( 'MOMENT_ILLUSTRATION_WONDER', 'MOMENT_DATA_BUILDING', 'BUILDING_BOLSHOI_THEATER', 'CHMZ_Moment_Wonder_BolshoiTheater.dds' ),

When the actual valid string is & has always been == BUILDING_BOLSHOI_THEATRE
Kept my DDS file as is.
--duh.
:hammer2:
 
I'd like to change the value of yield & production of tiles, terrain & bonus. I can't find them in the sqLite studio.
 
Back
Top Bottom