Quick Modding Questions Thread

Hello everyone!

I am not sure if this is the correct place to post, but I've been trying to follow the unit art assets tutorial and I came to the last part before testing. He said that if I don't know how to actually implement the unit then that's a problem. Well, I am not entirely sure how to do it..

I copied his sql and when I remove all the standard .xml files from the mod, there is a unit in the game with a weird name (the name thats entered into the Units by the sql: LOC_UNIT_TEST_NAME). So here I am doubting if I did the right thing, because in the xml files that I removed there were some unit_text.xml files which seemed to contain info about these references. So, now I'm lost and I can't seem to find a tutorial here. I feel like most people here came from civ 5 modding, but I never modded or even played civ 5. My modding experience comes only from civ 4 and civ 3 which didn't use modbuddy.

So I guess my question is mostly: can someone point me to a place where I can find out more about what I have to edit to add new units and/or buildings to the game? Thanks!
LeeS Modding Guide is the right thing for you. You will find there everything you need as a new Civ 6 beginner modder (even as an advanced one).

If your Unit is showing In-Game and works just fine, then you're nearly done. You just need to fix the Text/Localaisation of the Unit, which is the simplest part in your work IMO. Just follow the instrctions in the Guide.

GL!
 
you still have the issue of "local globals", the "true" flag is to include multiple files starting with the same prefix.
Yeah, I forgot that. Inconvenient, but as long as you need to just overwrite some few function you just need to copy the "local globals". Do the "local globals" in the new lua file that will overwrite the original function also overwrite the original "local globals" (that get used by original functions, hence you might change the outcome completely), or it works just for that overwriting file?
 
in the case of @dbergan question, m_kGreatPeople is a table that would contain different entries depending of the file in which a function is using it, if both set it as
Code:
local m_kGreatPeople        :table;

not tested, but I suppose that even if the second file (including the first), (re)define it as a global
Code:
m_kGreatPeople        :table;
the first one will use its local version.
 
That depends on the coding. Database updates don't have any effect on saved Games (maybe modifiers and requirements only, but those could break the Game sometimes), ...
This is not true. Changes to the database will always be reflected in the database. Alterations in the database to what a building, district, unit, etc., or modifier does will be implemented by the game with two basic caveats

(1) -- elements that are already in the game as an "object" will not reflect the alterations.

So if you complete a Monument in a city and then save/exit the game to alter the effects of the Monument building, the existing Monuments will generally not reflect these alterations but new copies added to the game will. This is true for modifiers as well. Once a modifier has been applied to a game object like a city, the definition of that modifier is "locked" in essence by the game for that city for that modifier. New cities or cities which did not get the modifier previous to the change will reflect the changes made in the database.

(2) -- Certain GlobalParameters are only read by the game when the new game is created and any changes will be shown in the database but not implemented. Other GlobalParameters will be both implemented in the database and in a saved game and the alterations will be reflected as soon as the saved game is loaded. I do not know that anyone has made a comprehensive list of which GlobalParameters are only implemented when starting a new game. Other GlobalParameters (like the one for Plot Buying / City Workable range) are not alterable even though changes made to them will be reflected in the database -- these are hardcoded within the non-accessible DLL code.

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

You can in fact add entirely new Modifiers to the game and attach them to Buildings, Units, whatever, with of course the caveat about new stuff will not be implemented on stuff already in the game. Players and leaders are usually treated by the game as "stuff already in the game" for these purposes so there is often nothing wrong with one's code other than the fact that "you" are trying to add it to an existing saved game.

What you should never try to do is to add anything that must be registered in table "Types" to an exising game as this can completely corrupt that saved game. The game works on ID # assignments to everything, and table "Types" is where these ID # assignments are passed out to Players, Civilizations, Policies, DynamicModifiers, Districts, Buildings, Units, UnitAbilities, etc. And the corollary to this is that you should never delete anything that has to be registered in table Types without starting an entirely new game.
 
Last edited:
This is not true. Changes to the database will always be reflected in the database. Alterations in the database to what a building, district, unit, etc., or modifier does will be implemented by the game with two basic caveats

(1) -- elements that are already in the game as an "object" will not reflect the alterations.

So if you complete a Monument in a city and then save/exit the game to alter the effects of the Monument building, the existing Monuments will generally not reflect these alterations but new copies added to the game will. This is true for modifiers as well. Once a modifier has been applied to a game object like a city, the definition of that modifier is "locked" in essence by the game for that city for that modifier. New cities or cities which did not get the modifier previous to the change will reflect the changes made in the database.

(2) -- Certain GlobalParameters are only read by the game when the new game is created and any changes will be shown in the database but not implemented. Other GlobalParameters will be both implemented in the database and in a saved game and the alterations will be reflected as soon as the saved game is loaded. I do not know that anyone has made a comprehensive list of which GlobalParameters are only implemented when starting a new game. Other GlobalParameters (like the one for Plot Buying / City Workable range) are not alterable even though changes made to them will be reflected in the database -- these are hardcoded within the non-accessible DLL code.

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

You can in fact add entirely new Modifiers to the game and attach them to Buildings, Units, whatever, with of course the caveat about new stuff will not be implemented on stuff already in the game. Players and leaders are usually treated by the game as "stuff already in the game" for these purposes so there is often nothing wrong with one's code other than the fact that "you" are trying to add it to an existing saved game.

What you should never try to do is to add anything that must be registered in table "Types" to an exising game as this can completely corrupt that saved game. The game works on ID # assignments to everything, and table "Types" is where these ID # assignments are passed out to Players, Civilizations, Policies, DynamicModifiers, Districts, Buildings, Units, UnitAbilities, etc. And the corollary to this is that you should never delete anything that has to be registered in table Types without starting an entirely new game.
That's pretty interesting. Thanks for the Clarification and Infos! Didn't know that GlobalParameters changes could have effect on saved Games.
I never noticed when the changes take effect on saved Games and when not. I will be more attentive to that in the Future.
 
Tbh I'm not really familiar with them, I always get lost when I open a xml context file :lol:. Any suggestion from where I should start to learn how it works or Threads that explain that?

Hi Zegangani!

I guess I don't think they're that intimidating... but maybe that's all my years of web programming speaking. I've got ReligionScreen.xml open right now and yeah, the top two lines look pretty obtuse (just ignore those), but after that they're fairly self-explanatory. <Container> defines something that contains other things. <Image> is an image. <Label> is some text. <Stack> and <Grid> represent the most common layouts... Stacks are items displayed in a line (either vertical or horizontal... think: DiplomacyRibbon or TopPanel) and Grids put things in a two-dimensional grid (think: selecting beliefs for your religion).

Attributes (the things inside <>) are similarly pretty easy-to-understand. "size" defines the size of the item. "offset" is used to nudge things relative where it would go without an offset. "anchor" is used to define if something is left-, right-, or center-aligned (also, top- and bottom-). "Hidden" hides things.

You'll pick it up pretty quickly if you just open up ReligionScreen.xml, play with the values, and see how they change the UI. Also open ReligionScreen.lua and you can see the interplay between the two. The lua files usually reference the xml files via the "Name" or 'ID" attributes. When the lua file says:
Code:
local m_ReligionTabsIM:table = InstanceManager:new("ReligionTab", "Button", Controls.TabContainer);

You can go to the context xml file and ctrl-f "ReligionTab" to find what it's refering to.
Code:
    <Instance Name="ReligionTab">
        <GridButton    ID="Button" Size="50,34" Style="TabButton" FontSize="14" TextOffset="0,2">
            <Image ID="Icon" Size="22,22" Texture="Religions22" Offset="8,8" />
            <GridButton ID="Selection" Offset="-2,0" Size="parent,parent" Style="TabButtonSelected" ConsumeMouseButton="0" ConsumeMouseOver="1" Hidden="1"/>
            <Image ID="SelectionIcon" Size="22,22" Texture="Religions22" Offset="8,8" />
        </GridButton>
    </Instance>

The annoying part of programming with the context xml files is that they are just the starting templates, not the final result. Therefore, you can make changes to the xml file that look like they don't have any effect on the screen. For example, sometimes I'll assign something as Hidden in the context xml file, but it won't be hidden on the screen because in the corresponding lua file it has a SetHide(false) command on the thing I want hidden. But still, whenever a context xml change works, I think it's the way to go.


There are some Notes in GreatWorksOverview_KublaiKhanVietnam_Monopolies.lua that make compatibility with other UI files possible:
Code:
-- This file is being included into the base GreatWorksOverview file using the wildcard include setup in GreatWorksOverview.lua
-- Refer to the bottom of GreatWorksOverview.lua to see how that's happening
-- DO NOT include any GreatWorksOverview files here or it will cause problems
-- include("GreatWorksOverview");

And in GreatWorksOverview.lua:
Code:
-- This wildcard include will include all loaded files beginning with "GreatWorksOverview_"
-- This method replaces the uses of include("GreatWorksOverview") in files that want to override
-- functions from this file. If you're implementing a new "GreatWorksOverview_" file DO NOT include this file.
include("GreatWorksOverview_", true);

I never tested this, so I can't say if this works also with other UI files or it was just included explicitly for that file (hardcoded stuff?). If Yes, then it's the best thing that we got in the January Pack, even better than the Industry/Monopoly Mode :D (but we wouldn't have got it if it weren't the Mode).

Oh, I can definitely tell you how those work. I've wrestled with them quite a bit.

The old way Firaxis did a lua file replacement was to have "TechTree.lua" in the base game and then "TechTree_Expansion1.lua" would include it like so:
Code:
include("TechTree")

And then "TechTree_Expansion2.lua" would start with:
Code:
include("TechTree_Expansion1")



The new way is what you copied. If they refactored TechTree with the new way it would go like this. The base file would end with
Code:
include("TechTree_", true);

And then neither TechTree_Expansion1 nor TechTree_Expansion2 would have an include() for the previous version. That command sets the base file looking for the expansion replacement files automatically.


This is nice for Firaxis because when they make "TechTree_Expansion2" they don't have to check whether they're including TechTree or TechTree_Expansion1. It just works either way. (Because sometimes there isn't an _Expansion1 file.)

Now for modders, this means that if you create a file that starts with "GreatWorksOverview_" (e.g. GreatWorksOverview_Zegangani.lua) and ImportFiles it with your mod, it will automatically be included after the base file and any subsequent expansion lua files by Firaxis. And, as the comment says, you don't include('GreatWorksOverview') in your file. All you have to do is make sure the filename starts the right way.

Unfortunately, this only works when Firaxis ended their lua file with include("BaseFileName_", true), which isn't often. But when they did, it's a nice option for modders, because if you're overwriting a function in the base file, you don't have to make additional files and modinfo criteria for Expansion1 and Expansion2 just to make sure the subsequent lua files get included.

Also unfortunately, this neat feature doesn't work-around the locally-global variables that I mentioned in previous posts. In that case, I still have to replace the whole lua file to make that tiny change.

Kind regards,
DB
 
Thanks for the Explanation @dbergan !

The FoW is gone now and I can see it more clear now. Sounds simple to understand, I will follow your Advice and try to edit a context xml file and see how it changes the UI. I never tryed to make a custom UI apart from changing infos shown in existing Panels/Screens and ToolTips, so that really helped me to understand how it works. Thanks again!

Unfortunately, this only works when Firaxis ended their lua file with include("BaseFileName_", true), which isn't often. But when they did, it's a nice option for modders, because if you're overwriting a function in the base file, you don't have to make additional files and modinfo criteria for Expansion1 and Expansion2 just to make sure the subsequent lua files get included.
The only Time where this will be less inconvenient is when Firaxis finishes the Game and releases the Complete Version and a Modder uploads all the UI files with that "include" methode (if the Devs haven't already done it themselves by then).

I'm wondering if included UI lua files that rewrite the same function just need the usual LoadOrder to rewrite each other. I suppose Yes.

Also unfortunately, this neat feature doesn't work-around the locally-global variables that I mentioned in previous posts. In that case, I still have to replace the whole lua file to make that tiny change.
Yeah, That's really annoying. Some few global locals to copy aren't an Issue, but a buch of them and you better rewrite the whole lua file. But you can include the "include" Methode for other Modders though (assuming there are some relevant functions that don't need many global locals).
 
Glad to help!

Yeah, That's really annoying. Some few global locals to copy aren't an Issue, but a buch of them and you better rewrite the whole lua file.

I tried that once and found that even 1 locally-global variable is a problem. It's not just a matter of making my own version of the variable, the problem is that it gets set in some other function before the function I'm tweaking. And it potentially gets used in another function after the one I tweaked. Thus, those functions need to be copied into my lua, and they inevitably contain other locally-global variables... and once that cascades into 9 or 10 functions, you're better off copying the whole file, because that's easier to maintain than a pile of random functions.

Kind regards,
DB
 
LeeS Modding Guide is the right thing for you. You will find there everything you need as a new Civ 6 beginner modder (even as an advanced one).

If your Unit is showing In-Game and works just fine, then you're nearly done. You just need to fix the Text/Localaisation of the Unit, which is the simplest part in your work IMO. Just follow the instrctions in the Guide.

GL!
Thank you! I will take a look!
 
Hi! I am absolutely 100% brand new to modding, but there's an idea I'd really like to see, so I figure, why not at least try? Maybe you can help me get started;

How to I get the full regular list of Great Prophets by era from the game files?
 
I could find which files control the Advanced Setup phase & specially, what components/principles deal with those newest Leader-Picker & CityStates-Picker systems along with their dual LUA/XML coding methods.

BUT -- the Natural Wonders-Picker files are nowhere to be found into the usual FrontEnd folders.

Anyone knows the real facts about those strangely mis-located or somewhat hidden assets??

PS; I would try to mimic the double columns selection process for NWP too.. but without any reliable source code or direct proper file(s) access -- it's just impossible, AFAIC.
 
I could find which files control the Advanced Setup phase & specially, what components/principles deal with those newest Leader-Picker & CityStates-Picker systems along with their dual LUA/XML coding methods.

BUT -- the Natural Wonders-Picker files are nowhere to be found into the usual FrontEnd folders.

Anyone knows the real facts about those strangely mis-located or somewhat hidden assets??

PS; I would try to mimic the double columns selection process for NWP too.. but without any reliable source code or direct proper file(s) access -- it's just impossible, AFAIC.
it's a generic multi picker windows, look for MultiSelectWindow .lua & .xml
 
not just the wording, the whole setup framework is very complex.
 
Agreed.. i just tried digging through the XML section that i presumed was the culprit (single slot width instead of double column like Leaders & CS) -- but, even the basic principles feel completely off standards from what i could detect... starts from line #24;
Code:
            <!-- Selection Grid (Left Side Panel)-->
            <Grid ID="ItemsSection" Style="DecoGrid" Offset="0,38" Size="640,parent-38" Anchor="L,C" Color="30,66,96,255">
                <Stack Anchor="C,T" StackGrowth="Bottom" Padding ="5">

                    <Line Start="10,1"            End="630,1"        Color="30,66,96,255" Width="2" />

                    <!--Item Selection Scroll Panel-->
                    <ScrollPanel Anchor="L,T" ID="ItemsScrollPanel" Offset="0,10" Vertical="1" Size="Parent-8,Parent-38">
                        <Stack ID="ItemsPanel" Anchor="C,T" Offset="0,0" Padding="7" StackGrowth="Bottom"/>
                        <ScrollBar Style="Slider_Blue"  Anchor="R,C" Offset="5,0"/>
                    </ScrollPanel>
                </Stack>
            </Grid>

Might need somebody's help to re-write ScrollPanel or Stack sizing (320?), Vertical (2?) and StackGrowth ("Right"?) ... plus whatever else needs adjustment(s).
I compared the above with the LEADERPicker file and that structure is much more complex.
Gonna run more tests. :scan:

In the meantime, any hints from you.. please?
 
Last edited:
UI coding is really not my thing, but I suppose you'll need a parent stack with growth right and two children stack with growth bottom, then handle in Lua the alternate placement of instances in one of the children stack or the other for left/right columns.
 
There we go.. the solution is already written up in clear logic within the City-States-Picker XML like this (and basicly what you suggested earlier)...
Code:
<!-- Screen description -->
            <Stack Anchor="C,T" Offset="0,5" StackGrowth="Down" StackPadding="2">
                <Label ID="TopDescription" Anchor="C,T" Style="BlueGlow" WrapWidth="620"/>
                <!-- City-State Count -->
                <Stack Anchor="C,T" StackGrowth="Right" StackPadding="40">
                    <Stack StackGrowth="Right" Anchor="C,C">
                        <Label Style="ShellOptionText" ID="StringName" Anchor="L,C" String="LOC_CITY_STATE_PICKER_SORT_BY"/>
                        <PullDown ID="SortByPulldown" Anchor="C,C" Style="PullDownBlue" Size="300,24"/>
                    </Stack>
                    <Stack StackGrowth="Right" Anchor="C,C">
                        <Label Style="ShellOptionText" Anchor="L,C" String="LOC_CITYSTATE_COUNT_NAME"/>
                        <Slider ID="CityStateCountSlider" Style="SliderControl" Size="250,13" Anchor="L,C"/>
                        <Image Texture="Controls_CircleCompass" Size="52,53" Color="ShellControl">
                            <Label ID="CityStateCountNumber" Style="FontFlair40" String="10" Anchor="C,C" FontStyle="stroke" Color0="208,212,217,255" Color1="0,0,0,50"/>
                        </Image>
                    </Stack>
                </Stack>
                <Label ID="CountWarning" Anchor="C,T" WrapWidth="620"/>
            </Stack>
            <!-- Selection Grid (Left Side Panel)-->
            <Grid ID="ItemsSection" Style="DecoGrid" Offset="0,100" Size="640,parent-100" Anchor="L,T" Color="30,66,96,255">
                <Stack Anchor="C,T" StackGrowth="Bottom" Padding="5">
                    <Line Start="10,1" End="630,1" Color="30,66,96,255" Width="2" debug="*"/>
                    <!--Item Selection Scroll Panel-->
                    <ScrollPanel Anchor="L,T" ID="ItemsScrollPanel" Offset="-4,10" Vertical="1" Size="Parent,Parent-38">
                        <Stack ID="ItemsPanel" Anchor="C,T" Offset="0,0" Padding="7" StackGrowth="Right" WrapWidth="700" WrapGrowth="Down"/>
                        <ScrollBar Style="Slider_Blue" Anchor="R,C" Offset="5,0"/>
                    </ScrollPanel>
                </Stack>
            </Grid>
 
Last edited:
Back
Top Bottom