1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

How do you debug a mod when you're not getting any lua errors?

Discussion in 'Civ5 - Creation & Customization' started by Jiska, May 29, 2019.

  1. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    So say you have a mod:

    https://steamcommunity.com/sharedfiles/filedetails/?id=1737956594

    and you're experiencing random crashes. All your code seems to work, and the crashes aren't reproducible. You've put a debug print at the beginning and end of each of your blocks of code, and the game doesn't seem to be crashing when you code is fired.

    I've checked the database, gamecore, and net_message_debug logs, and none of them seem to have any pertinent information. Are there any additional ways of diagnosing the cause of the crashes?
     
  2. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    6,279
    Location:
    Illinois, USA
    If you are allowing purchase of buildings with Faith via Pantheon, Founder, or Enhancer Beliefs this is a prime candidate for mystery-crashes unless you've also re-written the DLL to accomodate.

    With the base-game DLL for G&K / BNW, only Follower and Reformation Beliefs execute properly for unlocking faith-purchased buildings.
    • Pantheons are not allowed to do this without crash-happiness of the game, nor will the game's standard DLL implement such an effect - the pantheon can be chosen and the religion "screens" may even say the Pantheon unlocks buying the building, but the game does not actually allow it.
    • Under the game's standard DLL, allowing a Founder or Enhancer Belief to unlock purchase of a building by faith leads directly to intermittent crashing of the game, either when the human attempts to spread such a religion or when the AI does so, and when the religion is spread to a city via religious pressure.
      • The CTD's are intermittent, essentially random, and unfixable.
      • A save of a game right before spreading religion to a new city can be reloaded and the CTD may or may not recur for spreading the religion to the city with the same Missionary, for example. Multiple repeat tests of the same actions after repeat reloads of the save may or may not show differing behavior each time the reload is done.
    CTDs that come from these Belief issues don't give any real usable clues in any of the logs, either.
     
  3. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    Thanks for the reply LeeS!

    No actually, I have some buildings in the Pantheon portion of my mod, but they're unlocked for regular construction via dummy-prerequisite-building-added-by-lua rather than by Faith purchase. However, I do have a lot, like 50+ dummy buildings used as substitutes for Beliefs when purchasing additional Pantheon Beliefs. There probably aren't more than a few of them in a City at any given time, but does mass adding dummy Buildings affect game stability?
     
  4. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,350
    Location:
    Near Portsmouth, UK
    Do your dummy buildings have specialist slots? And if so, does your code for removing the dummy buildings take extra care to remove any pop assigned as specialists in them and relocate them elsewhere? As this is also a cause of rando CTDs
     
  5. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    Nope, they're all super simple, nothing much but greatworkcount -1
    The beliefs and dummy-belief-buildings are here: https://pastebin.com/h441ZpE9
    and they almost all look like:
    Code:
    <Type>ISKA_BUILDING_PANTHEON_0_ALL_FATHER</Type>
                <BuildingClass>BUILDINGCLASS_ISKA_PANTHEON_0_ALL_FATHER</BuildingClass>
                <Cost>-1</Cost>
                <FaithCost>-1</FaithCost>
                <PrereqTech>NULL</PrereqTech>
                <ArtDefineTag>NONE</ArtDefineTag>
                <MinAreaSize>-1</MinAreaSize>
                <NeverCapture>true</NeverCapture>
                <HurryCostModifier>-1</HurryCostModifier>
                <IconAtlas>BW_ATLAS_1</IconAtlas>
                <PortraitIndex>19</PortraitIndex>
                <Description>TXT_KEY_ISKA_DUMMY</Description>
                <GreatWorkCount>-1</GreatWorkCount>
    and the Pantheon buildings are here: https://pastebin.com/1XAuhB48
     
  6. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    6,279
    Location:
    Illinois, USA
    You have a whole smattering of beliefs for which you've never stated the Type of Belief. Instead of for example
    Code:
    <Pantheon>true</Pantheon>
    You've got
    Code:
    <LandBarbarianConversionPercent>-1</LandBarbarianConversionPercent>
    Beliefs need to be assigned to a Belief-type: Pantheon, Founder, Follower, Enhancer, or Reformation.

    While LandBarbarianConversionPercent is a valid column, I don't think Firaxis used it anywhere in either of G&K or BNW.

    Also, it is emphatically not true that YIELD_FAITH is the only yield that works in table <Building_BuildingClassYieldChanges>. Any of the yields PRODUCTION, GOLD, FOOD, CULTURE, FAITH, SCIENCE can be used with the game's standard DLL. Using this table with dummy buildings can often have weird results especially as dummies are removed or added. There is a common misunderstanding however with regard to how the effects of this table stack for multiple copies of a dummy building. The effects do not stack for multiple copies of a BuildingType within the same city. So this will only provide more than 1 faith for each shrine when more than one city contains a ISKA_BUILDING_PANTHEON_0_ALL_FATHER
    Code:
    <Row>
          <BuildingType>ISKA_BUILDING_PANTHEON_0_ALL_FATHER</BuildingType>
         <BuildingClassType>BUILDINGCLASS_SHRINE</BuildingClassType>
          <YieldType>YIELD_FAITH</YieldType>
         <YieldChange>1</YieldChange>
     </Row>
    I use the table all the time with "normal" buildings as the BuildingType for all of the yields noted above -- there is no problem with any of them.

    Database Error:
    Code:
    2378.        <Row>
    2379.            <BuildingType>ISKA_BUILDING_PANTHEON_20_ASPECT_OF_NATURE</BuildingType>
    2380.            <FeatureType></FeatureType>
    2381.            <YieldType>YIELD_FAITH</YieldType>
    2382.            <Yield>4</Yield>
    2383.        </Row>
    You can't have a null in that column
    Code:
    <Column name="FeatureType" type="text" reference="Features(Type)"/>
     
  7. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    Thanks for the reply LeeS!

    This is intentional. These second set of Pantheon Beliefs aren't supposed to show up when choosing Pantheon, Founder, Follower, Enhancer, or Reformation Beliefs, but instead are flagged by
    Code:
    <LandBarbarianConversionPercent>-1</LandBarbarianConversionPercent>
    which isn't actually supposed to do anything, but instead mark them as to be shown among the other Pantheon Beliefs when choosing secondary, tertiary, and quaternary Pantheon Beliefs.

    So since these things are intentional and their idiosyncrasies seem to be working as intended with the rest of my code... is it possible that <LandBarbarianConversionPercent>-1 is crashing my game at some point when a missionary moves adjacent to a barbarbian? But that can't be, because those Beliefs are never actually given to a player within the DLL's Belief system, so LandBarbarianConversionPercent is never actually checked by the DLL. (I surmise.)

    Similarly, the reason the second set of Pantheon Beliefs aren't marked as Pantheon, Founder, Follower, Enhancer, or Reformation Beliefs is because I don't want them to actually be choosable as those types of Beliefs. So the worst that could happen by not flagging them as such would that the game simply wouldn't display them as such, right? That couldn't be the cause of ctds?

    Yes, I have a YIELD_FOOD on a few of the Beliefs... I distinctly remember Culture not working (maybe I futzed it somehow?), but I in the end I circumvented this problem by just ignoring it!

    I don't quite understand what you're trying to say here... I'm not trying to stack dummy or regular Buildings, each dummy is only supposed to be added at most once to Cities, and that particular Belief should only provide +2(Primary)/+1(secondary, tertiary, and quaternary). The dummy Buildings are only added by secondary, tertiary, and quaternary Pantheon Beliefs, so they shouldn't be overlapping with the (primary) Pantheon Belief effects.

    Thanks! Must have missed that... is it possible that and that alone was the cause of my CTDs?
     
  8. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    6,279
    Location:
    Illinois, USA
    Belief_BuildingClassYieldChanges is a different table to Building_BuildingClassYieldChanges, but it should still accept all the "standard" types of yield.

    Unmodded Game code:
    Code:
    <Belief_BuildingClassYieldChanges>
    	<Row>
    		<BeliefType>BELIEF_ANCESTOR_WORSHIP</BeliefType>
    		<BuildingClassType>BUILDINGCLASS_SHRINE</BuildingClassType>
    		<YieldType>YIELD_CULTURE</YieldType>
    		<YieldChange>1</YieldChange>
    	</Row>
    	<Row>
    		<BeliefType>BELIEF_FEED_WORLD</BeliefType>
    		<BuildingClassType>BUILDINGCLASS_SHRINE</BuildingClassType>
    		<YieldType>YIELD_FOOD</YieldType>
    		<YieldChange>1</YieldChange>
    	</Row>
    	<Row>
    		<BeliefType>BELIEF_CHORAL_MUSIC</BeliefType>
    		<BuildingClassType>BUILDINGCLASS_TEMPLE</BuildingClassType>
    		<YieldType>YIELD_CULTURE</YieldType>
    		<YieldChange>2</YieldChange>
    	</Row>
    	<Row>
    		<BeliefType>BELIEF_LITURGICAL_DRAMA</BeliefType>
    		<BuildingClassType>BUILDINGCLASS_AMPHITHEATER</BuildingClassType>
    		<YieldType>YIELD_FAITH</YieldType>
    		<YieldChange>1</YieldChange>
    	</Row>
    </Belief_BuildingClassYieldChanges>
    The only yield that "stacks" for multiple copies of a building within the same city for the Belief_BuildingClassYieldChanges table is Faith. So if there are 10 copies of a building called BUILDING_DUMMY_SOMETHING in a single city, each of these ten copies will be affected by the Belief_BuildingClassYieldChanges so long as YIELD_FAITH is the YieldType. If any other YieldType is specified, the YieldChange will only be applied once per city. Blame the Firaxis base DLL for this particular bit of wierdness.


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

    Multiple Cities each getting a copy of BUILDING_DUMMY will cause stacking effects on the Shrine-Class of buildings' yields, but a single city with 15 copies of BUILDING_DUMMY will only add 1 yield to Shrine-Class buildings:
    Code:
    <Building_BuildingClassYieldChanges>
    	<Row>
    		<BuildingType>BUILDING_DUMMY</BuildingType>
    		<BuildingClassType>BUILDINGCLASS_SHRINE</BuildingClassType>
    		<YieldType>YIELD_GOLD</YieldType>
    		<YieldChange>1</YieldChange>
    	</Row>
    </Building_BuildingClassYieldChanges>
    -------

    I would expect Beliefs that are not properly registered as to "type" would be a prime suspect for intermittent / rando CTD.

    I'm also not following what function they would achieve if not selectable, therefore why add to the mix of possible reasons the game is crashing ?
     
    Last edited: May 30, 2019
  9. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    That is some weird **** right there. Thanks for telling me, probably never would have figured that out on my own.
    Well then I guess I know what to begin scrutinizing.
    They are selectable, just not as Primary (Major Deity) Beliefs. Part of my mod allows you to select up to 3 additional, weaker, Pantheon Beliefs before founding a Religion. This part of my also removes the base game's Beliefs, and adds 22 Beliefs that can be chosen as a 1st (Regular Pantheon) Belief, and an additional 22 (Rituals, null-type LandBarbarianConversionPercent -1) Beliefs that are added to the pool of selectable Beliefs when choosing secondary, tertiary, or quaternary Pantheon Beliefs.
     
  10. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    6,279
    Location:
    Illinois, USA
    If it were me I'd create an entirely new table to hold these not-Beliefs rather than trying to subborn the game's Religion systems into using a new system it is not even remotely coded to handle. You're going to have to re-write the religions screen lua files anyway to handle these extra choices, so you may as well remove the potential CTD issue by removing odd-defined "beliefs" from the Beliefs table. And you'd have to write "directing" code for the AI in order for them to use the system anyway, so there again is no real need for the extra issues of having oddball definitions in the Beliefs table.

    The game's religions and belief systems are one of Civ5's "Third Rail" systems -- touch it in order to alter how it works, and your mod dies.
     
  11. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    Actually all the necessary Ui is there to choose additional Beliefs, and I've already rewritten the ReligionOverview files and written the necessary code for the AI to pick 2nd, 3rd, and 4th Beliefs. I've also been extensively testing the Pantheons module for the last couple of days, after 15+ uncrashed games I'm coming to the conclusion that it's not that particular module that's causing CTDs. Frustrating.
     
    Last edited: May 31, 2019
  12. ThanOscar

    ThanOscar Chieftain

    Joined:
    Feb 13, 2019
    Messages:
    41
  13. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    Thanks for the suggestion ThanOscar! That actually looks like something that would be quite useful. I was following this tutorial: https://github.com/LoneGazebo/Community-Patch-DLL/issues/1432
    when I realized that my dll changes are miniscule and Gazebo went through them while incorporating them into the CP and din't find anything horrible, and the mod seemed to be stable with just the DLL modded part, so I just started disabling parts of the mod one by one and running test games.

    I thought I'd caught it here:

    Code:
    function Iska_WaW_HW_CityCaptured(hexPos, playerID, cityID, newPlayerID)
        local pPlot = Map.GetPlot( ToGridFromHex( hexPos.x, hexPos.y ) );
        if pPlot:GetPlotCity() == nil then return end
        local city = pPlot:GetPlotCity()
        --if Iska_HW_Debug then print("Pre-start 0 code Iska_WaW_HW_CityCaptured: city: " ..  city:GetName()) end
        if city:IsHolyCityAnyReligion() then
            if Iska_HW_Debug then print("Pre-start 1 code Iska_WaW_HW_CityCaptured: city: " ..  city:GetName()) end
            local defrel
            for row in GameInfo.Religions() do
                if city:IsHolyCityForReligion(row.ID) then
                    defrel = row.ID
                    break
                end
            end
            --if Iska_HW_Debug then print("Pre-start 2 code Iska_WaW_HW_CityCaptured: city: " ..  city:GetName()) end
            for row in GameInfo.Religions() do
                --if row.ID ~= nil then
                    --if Game.GetFounder(row.ID, -1) ~= nil then
                        if Iska_HW_Debug then print("Start code Iska_WaW_HW_CityCaptured: city: " ..  city:GetName()) end
    
                        if g_PlayerActiveHolyWar[defrel .. "ActiveHolyWarWith" .. row.ID] or g_PlayerActiveHolyWar[row.ID .. "ActiveHolyWarWith" .. defrel] then
                            Iska_WaW_SetValue(defrel .. "ActiveHolyWarWith" .. row.ID, nil)
                            g_PlayerActiveHolyWar[defrel .. "ActiveHolyWarWith" .. row.ID] = nil
                            g_PlayerActiveHolyWar[row.ID .. "ActiveHolyWarWith" .. defrel] = nil
                            Iska_WaW_SetValue(row.ID .. "ActiveHolyWarWith" .. defrel, nil)
                            Iska_WaW_SetValue(Game.GetFounder(defrel, -1) .. "ActiveHolyWar", nil)
                            Iska_WaW_SetValue(Game.GetFounder(row.ID, -1) .. "ActiveHolyWar", nil)
                            g_PlayerActiveHolyWar[Game.GetFounder(defrel, -1)] = nil
                            g_PlayerActiveHolyWar[Game.GetFounder(row.ID, -1)] = nil
    
                            local hplayer = Players[Game.GetActivePlayer()]
                            local player = Players[newPlayerID]
                            local oplayer = Players[playerID]
    
                            if Players[newPlayerID]:GetReligionCreatedByPlayer() == row.ID then
                                local decrel = row.ID
                                if Iska_HW_Debug then print("The Holy Armies of " .. GameInfo.Religions[decrel].IconString .. " " .. Locale.Lookup(GameInfo.Religions[decrel].Description) .. " have captured " .. city:GetName() .. ", the Holy City of  " .. GameInfo.Religions[defrel].IconString .. " " .. Locale.Lookup(GameInfo.Religions[defrel].Description) .. "! The Holy War of " .. GameInfo.Religions[decrel].IconString .. " " .. Locale.Lookup(GameInfo.Religions[decrel].Description) .. " has ended.") end
                                if player == hplayer or oplayer == hplayer or hplayer:HasReligionInMostCities(oplayer:GetReligionCreatedByPlayer()) or hplayer:HasReligionInMostCities(player:GetReligionCreatedByPlayer())
                                or Teams[hplayer:GetTeam()]:IsHasMet(player:GetTeam()) or Teams[hplayer:GetTeam()]:IsHasMet(oplayer:GetTeam()) then
                                    local sTitle = Locale.Lookup("TXT_KEY_ISKA_HOLY_WAR_ENDED_TITLE")
                                    local sText = Locale.ConvertTextKey("TXT_KEY_ISKA_HOLY_WAR_ENDED_CAPTURE_OTHER_DESC", city:GetName(), GameInfo.Religions[defrel].IconString, Locale.Lookup(GameInfo.Religions[defrel].Description), GameInfo.Religions[row.ID].IconString, Locale.Lookup(GameInfo.Religions[row.ID].Description))
                                    player:AddNotification(NotificationTypes.NOTIFICATION_RELIGION_FOUNDED, sText, sTitle)
                                end
                                Players[newPlayerID]:ChangeFaith(1000)
                                Events.AddPopupTextEvent(HexToWorld(ToHexFromGrid(Vector2(Players[newPlayerID]:GetCapitalCity():GetX(),Players[newPlayerID]:GetCapitalCity():GetY()))), Locale.Lookup("TXT_KEY_ISKA_HOLY_WAR_ENDED_CELEBRATIONS") .. 1000 .. " [ICON_PEACE] Faith", 0)
                            else
                                if Iska_HW_Debug then print("The Holy City of " .. Locale.Lookup(GameInfo.Religions[defrel].Description) .. " has fallen! The Holy War of " .. Locale.Lookup(GameInfo.Religions[row.ID].Description) .. " has ended.") end
                                local sTitle = Locale.Lookup("TXT_KEY_ISKA_HOLY_WAR_ENDED_TITLE")
                                local sText = Locale.ConvertTextKey("TXT_KEY_ISKA_HOLY_WAR_ENDED_CAPTURE_PLAYER_DESC", city:GetName(), GameInfo.Religions[defrel].IconString, Locale.Lookup(GameInfo.Religions[defrel].Description), GameInfo.Religions[row.ID].IconString, Locale.Lookup(GameInfo.Religions[row.ID].Description))
                                if player == hplayer or oplayer == hplayer or hplayer:HasReligionInMostCities(oplayer:GetReligionCreatedByPlayer()) or hplayer:HasReligionInMostCities(player:GetReligionCreatedByPlayer())
                                or Teams[hplayer:GetTeam()]:IsHasMet(player:GetTeam()) or Teams[hplayer:GetTeam()]:IsHasMet(oplayer:GetTeam()) then
                                    hplayer:AddNotification(NotificationTypes.NOTIFICATION_RELIGION_FOUNDED, sText, sTitle)
                                end
                                if Players[newPlayerID]:GetCapitalCity():GetReligiousMajority() == row.ID then
                                    Players[newPlayerID]:ChangeFaith(750)
                                    Events.AddPopupTextEvent(HexToWorld(ToHexFromGrid(Vector2(Players[newPlayerID]:GetCapitalCity():GetX(),Players[newPlayerID]:GetCapitalCity():GetY()))), Locale.Lookup("TXT_KEY_ISKA_HOLY_WAR_ENDED_CELEBRATIONS") .. 750 .. " [ICON_PEACE] Faith", 0)
                                end
                            end
                        end
                        if Iska_HW_Debug then print("End Iska_WaW_HW_CityCaptured.") end
                    end
                --end
            --end
        end
     end
     Events.SerialEventCityCaptured.Add(Iska_WaW_HW_CityCaptured)
    with the two bits of code that are commented out, because that almost certainly seemed to be causing a crash. But then I got another crash, so party's still going.
     
  14. Jiska

    Jiska Chieftain

    Joined:
    Apr 23, 2016
    Messages:
    77
    Yes, the other ctd was another use of Game.GetFounder(). Seems to be a buggy lua function. (method? idk what to call this)

    Muahaha my mod is now bug free!!
     

Share This Page