Suggestions, ideas and bugfixes related to modding

  • Add/Remove Modifiers via Lua for all entities
 
This sort of thing is getting <expletive> old, so it would be awesome if a modding-related patch fixed it:

Database.log:
[3365664.683] [Database] ERROR: UNIQUE constraint failed: IconDefinitions.Name, IconDefinitions.Atlas

Modding.log:
[3365664.610] Reloading Tuner states.
[3365664.621] Reloading icons.
[3365664.688] Reloading colors.
[3365664.972] Successfully reconfigured game.
*EOF*

Nothing in my logs directory is telling me what's wrong of giving me the slightest hope of fixing it (searching all files in the directory for 3365664 yields nothing apart from the single instance in database.log). To be clear, the specific error posted here re: icon atlases isn't the issue - it happens with far too many other errors, too ("too many" is defined as >0 IMHO).

Unrelated, if a modding patch could remove redundant entries (I just got 3 identical errors totalling 21 lines telling me that Firaxis derped with a city state). Modding can generate a lot of errors (especially for those of us with who aren't JFD/Civitas/Leiugi/Sukritact-tier modders) so cutting down on how much has to be sifted through couldn't hurt.
 
[3365664.683] [Database] ERROR: UNIQUE constraint failed: IconDefinitions.Name, IconDefinitions.Atlas

It could tell you the table and constraint name and the offending line of SQL - file and line number.
 
It would be desirable to delete all occurances within Firaxis-created lua files of "RowID - 1".

The problem is that RowID does not update to reflect changes to database table "numbering" that come from mods. If I delete the Lumber Mill from the game, for example, this is the result
Code:
> print(GameInfo.Improvements["IMPROVEMENT_GOODY_HUT"].RowId - 1)
9
Whereas the correct data from using Index of the relevant Row in the database gives the following
Code:
> print(GameInfo.Improvements["IMPROVEMENT_GOODY_HUT"].Index)
8
In this specific instance, since Lumber Mill comes in the Improvements table before Goody Huts, the map generation files attempt to place not Goody Huts, but Oil Wells within the CanPlaceGoodyAt() routine. The routine fails the checks shown here
Code:
function CanPlaceGoodyAt(improvement, plot)

	local improvementID = improvement.RowId - 1;
	local NO_TEAM = -1;
	local NO_RESOURCE = -1;
	local NO_IMPROVEMENT = -1;

	............

	if (not ImprovementBuilder.CanHaveImprovement(plot, improvementID, NO_TEAM)) then
		return false;
	end
       .........

	if (plot:GetResourceType() ~= NO_RESOURCE) then
		return false;
	end
"improvement.RowId" returns an erroneous row number, so the improvementID number garnered in the method
Code:
local improvementID = improvement.RowId - 1;
is also erroneous because RowId apparently does not reflect changes made within the database by mods.

Code:
ImprovementBuilder.CanHaveImprovement(plot, improvementID, NO_TEAM)
will return erroneous data for the plot in question since the return for ImprovementBuilder.CanHaveImprovement() is based not on the Goody Hut but rather the Oil Well's Index ID #. The results will be bizarre to say the least, and for the specific modding example given to cause goody huts never to be placed because if the first snippeted check passes the test, the second for "No Resource" will not pass the testing, since Goody Huts cannot be placed on resources according to the CanPlaceGoodyAt routine, but Oil Wells must be placed on Oil Resources.
 
This might be too vague of a suggestion, but here goes.

Unlock everything to be moddable unless it's so critical that it absolutely can't be. A couple of examples - there appears to be a hard limit of 8 for governors, even though we can add more via mods (related: we don't appear to be able to give new governors their own portraits).

Another example is that we can't (AFAIK) add custom yields to tiles (I'd be a fan of making tourism one, but I'm weird like that).

The NPC decision-making tree would almost certainly get a tonne of love from the modding community and the game would be better for it.

I realise there could come a point where you'd end up with people making entirely new games if you opened up enough ~stuff~, but is that really a big deal when people still have to buy the game in order to use the mods?
 
The number of Artifacts and Relics is hardcoded in GreatWorksOverview.lua and GreatWorkShowcase.lua which is bad because I can't add new Artifacts and Relics without overriding Lua files. The way this works is really ridiculous. :(

Code:
local NUM_RELIC_TEXTURES:number = 24;
local NUM_ARIFACT_TEXTURES:number = 25;

...
    if greatWorkInfo.GreatWorkObjectType == GREAT_WORK_ARTIFACT_TYPE then
        local greatWorkType:string = greatWorkInfo.GreatWorkType;
        greatWorkType = greatWorkType:gsub("GREATWORK_ARTIFACT_", "");
        local greatWorkID:number = tonumber(greatWorkType);
        greatWorkID = ((greatWorkID - 1) % NUM_ARIFACT_TEXTURES) + 1;
        greatWorkIcon = "ICON_GREATWORK_ARTIFACT_" .. greatWorkID;
    elseif greatWorkInfo.GreatWorkObjectType == GREAT_WORK_RELIC_TYPE then
        local greatWorkType:string = greatWorkInfo.GreatWorkType;
        greatWorkType = greatWorkType:gsub("GREATWORK_RELIC_", "");
        local greatWorkID:number = tonumber(greatWorkType);
        greatWorkID =  ((greatWorkID - 1) % NUM_RELIC_TEXTURES) + 1;
        greatWorkIcon = "ICON_GREATWORK_RELIC_" .. greatWorkID;
    else
        greatWorkIcon = "ICON_" .. greatWorkInfo.GreatWorkType;
    end
 
Remove all hard-coding from Lua for things that can be determined from the dynamic data in the database and cached.
 
Last edited:
Feature ideas for Modbuddy:
* ArtDefs that are not referenced in the Mod.Art.xml are highlighted red (or different colour).
* XLPs that are not referenced in the Mod.Art.xml are highlighted red (or different colour).
* Assets that are not referenced in any XLP are highlighted red (or different colour).
* Icons/UI Textures that are not referenced in any XLP are highlighted red (or different colour).
* Mod.Art.xml highlighted red (or different colour) if it's not added into UpdateArt (Mod Art Dependency File).
 
Not sure if this is an issues related to my Nvidia drivers or Asset Editor but AE does not recognize OpenGL drivers anymore and keeps warning that cooking will be slow. If this is AE looking for old drivers could it please be updated to detect the latest OpenGL drivers?
 
It seems that a .dep file is not created unless the *.Art.xml references at least one .artdef file in the mod? In other words, you can't have an XLP only Art.xml -> dep file. This isn't really made clear anywhere.
 
It would be good if the hardcoding in NaturalDisasterPopup.lua below was fixed as shown so that we don't have to overwrite in mods.

Code:
--[[
local m_EventMap = {
   ["RANDOM_EVENT_VOLCANO_GENTLE"]                = { Animation="REVEAL_ERUPTION",            Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=nil                            ,VFX=nil};
   ["RANDOM_EVENT_VOLCANO_CATASTROPHIC"]          = { Animation="REVEAL_ERUPTION_CATASTROPHIC",Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=nil                            ,VFX=nil};
   ["RANDOM_EVENT_VOLCANO_MEGACOLOSSAL"]          = { Animation="REVEAL_ERUPTION_MEGACOLOSSAL",Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=nil                            ,VFX=nil};
   ["RANDOM_EVENT_VESUVIUS_MEGACOLOSSAL"]         = { Animation="REVEAL_ERUPTION_MEGACOLOSSAL",Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=GetAffectedPlots_NaturalWonder ,VFX=nil};
   ["RANDOM_EVENT_KILIMANJARO_GENTLE"]            = { Animation="REVEAL_ERUPTION",            Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=GetAffectedPlots_NaturalWonder ,VFX=nil};
   ["RANDOM_EVENT_KILIMANJARO_CATASTROPHIC"]      = { Animation="REVEAL_ERUPTION_CATASTROPHIC",Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=GetAffectedPlots_NaturalWonder ,VFX=nil};
   ["RANDOM_EVENT_EYJAFJALLAJOKULL_CATASTROPHIC"] = { Animation="REVEAL_ERUPTION_CATASTROPHIC",Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=GetAffectedPlots_NaturalWonder ,VFX=nil};
   ["RANDOM_EVENT_EYJAFJALLAJOKULL_MEGACOLOSSAL"] = { Animation="REVEAL_ERUPTION_MEGACOLOSSAL",Sound="Play_Disaster_Volcano_Movie_Loop",   Callback=GetAffectedPlots_NaturalWonder ,VFX=nil};
   ["RANDOM_EVENT_FLOOD_MODERATE"]                = { Animation="REVEAL_FLOOD",               Sound="Play_Disaster_Flood_Movie_Loop",     Callback=GetAffectedPlots_Flood         ,VFX=nil};
   ["RANDOM_EVENT_FLOOD_MAJOR"]                   = { Animation="REVEAL_FLOOD",               Sound="Play_Disaster_Flood_Movie_Loop",     Callback=GetAffectedPlots_Flood         ,VFX=nil};
   ["RANDOM_EVENT_FLOOD_1000_YEAR"]               = { Animation="REVEAL_FLOOD",               Sound="Play_Disaster_Flood_Movie_Loop",     Callback=GetAffectedPlots_Flood         ,VFX=nil};
   ["RANDOM_EVENT_BLIZZARD_SIGNIFICANT"]          = { Animation="REVEAL_STORM",               Sound="Play_Disaster_Blizzard_Movie_Loop",  Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_BLIZZARD_CRIPPLING"]            = { Animation="REVEAL_STORM",               Sound="Play_Disaster_Blizzard_Movie_Loop",  Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_DUST_STORM_GRADIENT"]           = { Animation="REVEAL_STORM_SMALL",          Sound="Play_Disaster_Sandstorm_Movie_Loop", Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_DUST_STORM_HABOOB"]             = { Animation="REVEAL_STORM",               Sound="Play_Disaster_Sandstorm_Movie_Loop", Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_TORNADO_FAMILY"]                = { Animation="REVEAL_STORM_SMALL",          Sound="Play_Disaster_Tornado_Movie_Loop",   Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_TORNADO_OUTBREAK"]              = { Animation="REVEAL_STORM",               Sound="Play_Disaster_Tornado_Movie_Loop",   Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_HURRICANE_CAT_4"]               = { Animation="REVEAL_STORM",               Sound="Play_Disaster_Hurricane_Movie_Loop", Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_HURRICANE_CAT_5"]               = { Animation="REVEAL_STORM",               Sound="Play_Disaster_Hurricane_Movie_Loop", Callback=GetAffectedPlots_Storm         ,VFX=nil};
   ["RANDOM_EVENT_NUCLEAR_ACCIDENT_MINOR"]        = { Animation="REVEAL_FLOOD",                Sound="Play_Disaster_Meltdown_Movie_Loop",  Callback=nil                            ,VFX="DISASTER_NUCLEAR_MELTDOWN"};
   ["RANDOM_EVENT_NUCLEAR_ACCIDENT_MAJOR"]        = { Animation="REVEAL_FLOOD",                Sound="Play_Disaster_Meltdown_Movie_Loop",  Callback=nil                            ,VFX="DISASTER_NUCLEAR_MELTDOWN"};
   ["RANDOM_EVENT_NUCLEAR_ACCIDENT_CATASTROPHIC"] = { Animation="REVEAL_FLOOD",                Sound="Play_Disaster_Meltdown_Movie_Loop",  Callback=nil                            ,VFX="DISASTER_NUCLEAR_MELTDOWN"};
   ["RANDOM_EVENT_DROUGHT_MAJOR"]                 = { Animation="REVEAL_DROUGHT",             Sound="Play_Disaster_Drought_Movie_Loop",   Callback=GetAffectedPlots_Drought       ,VFX=nil};
   ["RANDOM_EVENT_DROUGHT_EXTREME"]               = { Animation="REVEAL_DROUGHT",             Sound="Play_Disaster_Drought_Movie_Loop",   Callback=GetAffectedPlots_Drought       ,VFX=nil};
};
--]]

local m_EventMap = {}
for row in GameInfo.EventMap() do

   local callbackFunction = nil

   if row.CallbackType == 'NaturalWonder' then
      callbackFunction = GetAffectedPlots_NaturalWonder;
   elseif row.CallbackType == 'Storm' then
      callbackFunction = GetAffectedPlots_Storm;
   elseif row.CallbackType == 'Flood' then
      callbackFunction = GetAffectedPlots_Flood;
   elseif row.CallbackType == 'Drought' then
      callbackFunction = GetAffectedPlots_Drought;
   end

   m_EventMap[row.RandomEventType] = {Animation = row.Animation, Sound = row.Sound, Callback=callbackFunction, VFX = row.VFX}
end
 
Proper support for Dam World Wonders would be nice - perhaps with Hoover Dam or Three Gorges as an example? Windfly's Three Gorges is a very good effort but AFAIK there is no support to having face in the correct direction with regards to river flow.
 
Proposed OP update, let me know if I've forgotten something:

Graphic
  • Allow SQL queries to modify the Artdef tables
  • Make the heightmap update in game when placing Terrain and Features without a reload be. This happens when constructing a Dam - I understand that this is because Dams use the "TerrainEditMaterial" rather a "TerrainElement" but it seems like if the engine can handle the Heightmap being edited on the fly by the TerrainEditMaterial or Coastal Flooding it should be able to handle on on the fly heightmap changes when planting Features or adding removing Terrain and Features in the WorldBuilder tab in FireTuner.
  • Make it possible for Units to change the Terrain - yes, with the above I want true terraforming with Units!
  • Make it possible to add new base Terrain types outside of Snow/Tundra/Plains/Grassland/Desert - there is an unfortunate amount of hard-coding around these eg TerrainStyle.artdef StandardFlat Collection.
  • Make it possible to re-skin Particle FX - I can do it by editing the text strings in the .psb using Notepad by that's not as straight-forward as re-skinning the 3D assets.
  • Add 3 tile "C-shape" and 4 tile "Tri-star shape" TerrainElement configurations for Features/Natural Wonders - see post #5
  • Ability to set opacity maps for units. By now its not possible to have a opacity texture map in the material for a unit.
  • Ability to use different Tints for different Attachments in the Asset Editor like I can in the artdefs. At the moment I can only specify one Tint for the entire unit including all Attachments which doesn't imitate what is possible via the Artdefs. This would be handy for making Unit Portraits so that, for example, I can have blue horse armor without having a blue horse body.
  • If possible, update the unit preview script so it can preview both the horse and rider at the same time
  • Ability to test TerrainElement Materials outside of the game (including Heightmap changes) so that you combine with the TerrainElementAssets and fully test Natural Wonders outside of the game
  • Proper support for Dam World Wonders would be nice - perhaps with Hoover Dam or Three Gorges as an example? Windfly's Three Gorges is a very good effort but AFAIK there is no support to having face in the correct direction with regards to river flow

Gameplay (Lua methods & events)
  • API documentation : full list of available methods and parameters
  • Game events that you can use to modify the gameplay, similar to civ5 (TestAll):
    • GameEvents.CanMakeDiplomaticAction( PlayerID1, PlayerID2, DiplomaticActionType)
    • GameEvents.CanTrade( PlayerID1, PlayerID2, ResourceType )
    • GameEvents.CanMakeDeal( PlayerID1, PlayerID2, DealType )
    • GameEvents.CityCanCreate ( PlayerID, CityID, ProjectType )
    • GameEvents.CityCanConstruct ( PlayerID, CityID, BuildingType )
    • GameEvents.CityCanCreate ( PlayerID, CityID, ProjectType )
    • GameEvents.CityCanTrain ( PlayerID, CityID, UnitType )
    • GameEvents.PlayerCanConstruct ( PlayerID, BuildingType )
    • GameEvents.PlayerCanCreate ( PlayerID, ProjectType )
    • GameEvents.PlayerCanResearchTech ( PlayerID, TechType )
    • GameEvents.PlayerCanResearchCivic ( PlayerID, CivicType )
    • GameEvents.PlayerCanAdoptPolicy ( PlayerID, PolicyType )
    • GameEvents.PlayerCanAdoptGovernment ( PlayerID, GovernmentType )
    • GameEvents.PlayerCanTrain ( PlayerID, UnitType )
    • GameEvents.UnitCanAttack ( UnitID1 , UnitID2 )
    • GameEvents.UnitCanDoActionAt ( UnitID , ActionType, PlotID )
  • More gameplay related methods like the DeclareWarOn() added for DLC scenarios :
    • DoActionOn( OtherPlayerID1, DiplomaticActionType)
    • DoTradeWith
    • DoDealWith
  • Add/Remove Modifiers via Lua for all entities
  • Method to change/set rivers/mountains/deserts/volcanoes names on all maps
  • Core events and methods to take direct control over AI units (there is a move method, but no engine event we can hook into to use it correctly, the AI units either double move or not move at all, and there is nothing for combat)
  • Linked to the above, Core events to to control a combat or a movement before it's executed, to allow things like various support fire (preparatory fire, counter-fire, opportunity fire, defensive fire, ...), first strike, ambushes, etc...
  • User exits for scoring done by the AI, eg a scoring done by AI is passed and updated with a return value, this would allow for a finer control on what and when AI builds and does, especially for city evaluation when assessing the attack possibilites and for plot evaluation when settling. And ideally if this would also support Contract Managers from behavior trees.


Gameplay (general, database)

  • "StackingClasses" or "StackingWeigth" tables to allow separate values for stacking units type (for example 2 civilians + 1 ranged + 1 melee + 1 recon on a tile), ATM the stacking of various existing units type (civilian, support, religious, combat, ...) seems completly hardcoded.
  • Bug fixes
    • Allows AI units to stack depending on the value of PLOT_UNIT_LIMIT or those in the proposed Stacking tables (Last time I tried there is a check at the end of the AI turn to unstack units even when PLOT_UNIT_LIMIT > 1)
  • More ARGTYPES for ModifierArguments (right now we have just these 3: ARGTYPE_IDENTITY, ScaleByGameSpeed, LinearScaleFromDefaultHandicap)
    • ScaleByGameEra
    • ScaleByMapSize
    • ScaleByGameTurn
  • Add a field to Technologies and Civics that makes them assignable by Modifiers only (similar to the new field for Projects in the Projects_XP2 table)
  • AdjacentDistrict not only for building wonders but also for building other districts and improvements (and possibly terrains and others)
  • Ability to add new types of moments with their triggering requirements. Right now that seems to all be done at the Game Core level
  • Output table and constraint name and the offending line of SQL (file and line number) on Database Error
  • Delete all occurances within Firaxis-created lua files of "RowID - 1". The problem is that RowID does not update to reflect changes to database table "numbering" that come from mods, in which case (row.RowID - 1) can be different than row.Index (which is the value used in core)
  • Remove all hard-coding from Lua for things that can be determined from the dynamic data in the database and cached

Alternatively, the release of the DLL source code would allow us to do all the gameplay related request ourselves.


Modbuddy

  • ArtDefs that are not referenced in the Mod.Art.xml are highlighted red (or different colour)
  • XLPs that are not referenced in the Mod.Art.xml are highlighted red (or different colour)
  • Assets that are not referenced in any XLP are highlighted red (or different colour)
  • Icons/UI Textures that are not referenced in any XLP are highlighted red (or different colour)
  • Mod.Art.xml highlighted red (or different colour) if it's not added into UpdateArt (Mod Art Dependency File)
  • Scripts to streamline mod creation from assets
 
Last edited:
And let me know if something has been added in one of the patches since the thread creation.
 
The September 2019 SDK update has broken the ability to Attach Assets and have them show up in the Asset Previewer. When you connect them nothing shows up in the 3D Viewer. Please can this be fixed!

unknown.png
 
The September 2019 SDK update has broken the ability to Attach Assets and have them show up in the Asset Previewer. When you connect them nothing shows up in the 3D Viewer. Please can this be fixed!

Further to this there should be a way to roll back to the previous release of the SDK for when something major gets broken, in the same way as the Steam BETAs "ineedlegacyaccess" method for the game itself.
 
It's good that there was a Asset Editor update with the May 2020 patch. Sadly the Tint Color picker now doesn't allow for manually entry of colours via RGB or Hex code. Backward step. :(

Also still not possible to Tint each attachment separately as in game which would be very helpful so that you don't have blue or red skin in Unit Portraits.

upload_2020-6-4_17-29-19.png


upload_2020-6-4_17-33-42.png
 
Back
Top Bottom