Quick Modding Questions Thread

Is there any way to link/call methods between the UI and the gameplay context? I never understand why `GetUpgradeResourceCost` is UIContext only... . However I am also using some methods that are available only in the Gameplay context. What is the proper solution for this one?
 
Is there any way to link/call methods between the UI and the gameplay context? [...] What is the proper solution for this one?
Search in 'Civ6 - Creation & Customization' for "ExposedMembers.".
I never understand why `GetUpgradeResourceCost` is UIContext only...
Don't worry, that is simply to drive modders crazy, who are not primarily interested in art style & skins. :D
 
How to find out in lua code if the unit has some active effect? I mean the effects from visiting a NaturalWonder or from barracks and other buildings in the city where it was trained (like additional speed or +20% XP for example)?
 
@Zur13 You need to check the modifiers for that unit.
In Better Report Screen, there is a code that does that, so you might wanna take a look at it.
Thanks, looks like it is what I'm looking for. Now I'm trying to figure out how to get localized modifier description for showing to user.

I have tried to use GameEffects.GetModifierText( instID ) but it fails with the error:

Runtime Error: Invalid number of arguments. Expected - modifier_instance or modifier_id, key, [object_instance].

Any idea what is the key parameter it requires and optional object_instance parameter?

Edit: while trying to figure things out with modifiers I found that the original code from the Better report screen mod is not working for me because iUnitOwnerID decoded incorrectly from sOwnerString:

"Unit: 262147, Owner: 0, SubType: 1, SubValue: -274492200, Type: 20 Position: 66x39"

According to the code there should be ", Type" part after the "Owner: " but there is a "SubType:" now at least in my case. I've made this function to extract numeric parameter value from parameters string:

Code:
--************************************************************
function GetNumberFromParametersString( str, paramKey )
    --local str = "Unit: 262147, Owner: -330, SubType: 1, SubValue: -274492200, Type: 20 Position: 66x39";
    --local paramKey = "Owner:";

    local startIdx = -1;
    local endIdx = -1;
    startIdx, endIdx = string.find( str, paramKey .. ".?%-?%d+" ); -- find pattern param + any character + optional minus sign + any number of digits

    if startIdx ~= nil and endIdx ~= nil and startIdx >= 0 and endIdx >= 0 then
        local res = string.sub( str, startIdx, endIdx ); -- res == "Owner: -330"
       
        if res ~= nil and #res > 0 then
            local cutPrefix = string.gsub( res, "%-?%d+" ,"" ); -- cutPrefix == "Owner: "
           
            if cutPrefix ~= nil and #cutPrefix > 0 and ( #cutPrefix + 1 ) <= #res then
                res = string.sub( res, #cutPrefix + 1 ); -- res == "-330"
            end
           
            if res ~= nil and #res > 0 then
                local resNum = tonumber( res );
                --print( str, " Found: ", paramKey, resNum );
                return resNum;
            end

        end -- if res ~= nil
    else
        print( "Not found",  startIdx, startIdx );
    end -- if startIdx ~= nil

    return nil;
end



Edit: OK I've check and it seems there are no localizations for most modifiers I'm interested in.
 
Last edited:
I'm attempting to modify the RaF version of Removable Districts mod to reduce the production cost to be minimal. How can I do this?

I tried setting
Code:
UPDATE Districts SET Cost = -100
, as well as UPDATE Buildings, UPDATE Wonders cost. It didn't work.

Code:
INSERT INTO Types ( Type, Kind )
 SELECT 'PROJECT_REMOVE_'||DistrictType, 'KIND_PROJECT'
-- FROM Districts WHERE RequiresPlacement = 1 AND MaxPerPlayer = -1.0 AND OnePerCity = 1;
FROM Districts WHERE RequiresPlacement = 1 AND MaxPerPlayer = -1.0;


INSERT INTO Projects (
    ProjectType,
    Name,
    ShortName,
    Description,
    Cost,
    CostProgressionModel,
    CostProgressionParam1,
    PrereqDistrict )
SELECT    
    'PROJECT_REMOVE_'||DistrictType,
    CASE WHEN instr(Name, 'LOC_') = 0 THEN 'Remove '||Name ELSE 'LOC_PROJECT_REMOVE'||substr(Name, 4) END,
    CASE WHEN instr(Name, 'LOC_') = 0 THEN 'Remove '||Name ELSE 'LOC_PROJECT_REMOVE'||substr(Name, 4) END,
    'Removes the district with all its buildings.',
    80,
    'COST_PROGRESSION_GAME_PROGRESS',
    200,
    -- 'TECH_ENGINEERING',
    -- 'CIVIC_RD_DUMMY_!'||DistrictType,
    DistrictType
-- FROM Districts WHERE RequiresPlacement = 1 AND MaxPerPlayer = -1.0 AND OnePerCity = 1;
FROM Districts WHERE RequiresPlacement = 1 AND MaxPerPlayer = -1.0;

-- UPDATE Districts SET cost = 1;
-- UPDATE Buildings SET cost = 1 WHERE IsWonder = 1;

CREATE TABLE "RD_civType_uniqueDistrictType" (
        "CivType" TEXT NOT NULL,
        "ReplacedDistrictType" TEXT NOT NULL,
        "UniqueDistrictType" TEXT NOT NULL);

INSERT INTO RD_civType_uniqueDistrictType ( CivType, ReplacedDistrictType, UniqueDistrictType )
 SELECT a.CivilizationType, c.ReplacesDistrictType, b.DistrictType FROM CivilizationTraits AS a, Districts AS b, DistrictReplaces AS c WHERE a.TraitType = b.TraitType AND c.CivUniqueDistrictType = b.DistrictType ;

Edit: Figured it out. Was changing the wrong variable. Instead, change:
Code:
'LOC_PROJECT_REMOVE'||substr(Name, 4) END,
    'Removes the district with all its buildings.',
    0,
    'COST_PROGRESSION_GAME_PROGRESS',
    0,
for zero production cost.
 
Last edited:
Within 10 nanoseconds of a new Civ expansion coming out, the the steam workshop is flooded with entitled comments of the "update the mod already" kind. As civs and leaders seem to get the bulk of these comments, my question is: is there a form of digital duct tape that we users can apply that will make most modded civs and leaders work sufficiently that we can still play with them until the modder has time to do a proper update?
 
1. Disable the expansion.
2. Disable the mod.
3. Force enabling both and hope nothing breaks.
 
Could anyone please tell me any way to retrieve the map/game seed from LUA? In Gameplay context if possible.

EDIT: turn out I need to obtain it from SQL database, not LUA script because I cannot alter any database after game is loaded and script executed. I checked GlobalParameters but it's not there.
 
Last edited:
Could anyone please tell me any way to retrieve the map/game seed from LUA? In Gameplay context if possible.

EDIT: better yet, if it's obtainable from SQL database, it would be great. I checked GlobalParameters but it's not there.

I'm not sure about SQL but in lua you can look at InGametopOptionsMenu.lua

Code:
local gameSeed        :string    = tostring( GameConfiguration.GetValue("GAME_SYNC_RANDOM_SEED") );
local mapSeed        :string    = tostring( MapConfiguration.GetValue("RANDOM_SEED") );
 
@Zur13 thanks, it's very helpful, but as for my current mod, I just realize I cannot really do anything from LUA because of inability to alter database when LUA script is executed. Thanks anyway.

I wonder if there is any value in the SQL database that is fairly random but stay the same for each game.
 
Last edited:
Maybe I'm missing the obvious, but how do I make renaissance walls available to build until a later tech? I know how to write the UPDATE command in SQL, I just can't see what table has the information. Searching via this nifty tool I can't find any results containing both TECH_STEEL (currently the tech that stops you building them) and BUILDING_STAR_FORT (I'm guessing the latter is the walls).
 
The thing you are looking for is in TechnologyModifiers. They are "TECH_STEEL" | "STEEL_UNLOCK_URBAN_DEFENSES". You may want to move that one to some other tech.
 
Table <Buildings>
Code:
<Row BuildingType="BUILDING_STAR_FORT" Name="LOC_BUILDING_STAR_FORT_NAME"
     Description="LOC_BUILDING_STAR_FORT_DESCRIPTION"

     PrereqTech="TECH_SIEGE_TACTICS"

     PrereqDistrict="DISTRICT_CITY_CENTER" Cost="305" AdvisorType="ADVISOR_GENERIC"
     OuterDefenseHitPoints="100" OuterDefenseStrength="3"/>
and for the Building Prereq: table <BuildingPrereqs>
Code:
		<Row Building="BUILDING_STAR_FORT" PrereqBuilding="BUILDING_CASTLE"/>
Has nothing to do with TechnologyModifiers.

Neither of the two expansions alter this definition.

And from the BaseGameText tag definitions in file C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\Text\en_US\Types_Text.xml:
Code:
<Row Tag="LOC_BUILDING_STAR_FORT_NAME">
	<Text>Renaissance Walls</Text>
</Row>

---------

TECH_STEEL is a Modern Era technology in Civ6, so looking for it is not going to do any good for a Renaissance Era building, unit, whatever.
 
Last edited:
I think we understand the question in two different ways (and I think in a sense both are correct).

My understanding is that he wants to allow Re Wall to be able to build until later (that is, delay the Urban Defense, because that thing make all wall obsolete and you can't build it anymore).

LeeS thinks it means "should be able to build much later in tech tree".

My follow question is: how does Urban Defense make all walls un-buildable? Can we allow Walls to be built even after but the Strength/ranged attack still take place? I checked the Modifiers but it seems they stuff everything in one modifier/effect (MODIFIER_PLAYER_GRANT_CITIES_URBAN_DEFENSES / EFFECT_ADJUST_CITIES_HAS_URBAN_DEFENSES) and we can't do that.
 
Sorry if my question was unclear. I seldom manage to get walls built in time before steel is researched, so I wanted to have a later tech be the cut-off point. Using the TechnologyModifiers approach provided above, I changed TECH_STEEL to TECH_ROCKETRY and got the desired result.
 
Back
Top Bottom