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

Delete Player's Cities via LUA

Discussion in 'Civ5 - Creation & Customization' started by Karatekid5, Jan 10, 2019.

  1. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    I'm working on a rather crazy event to spice up my AI-only games and came up with something extreme. The idea was to make a unit based on the Great Musician function (one copy would be obtainable from a wonder) and when said musician is used in another civ's territory the civ that it was used on loses all of their cities (they'd be deleted), their capital population is set to 1, and their techs are reset to just agriculture.

    I know how to set the population of the capital once the event is done and how to get the owner of the plot the unit was used on, but I am unsure how to check all of the target's cities (would one use Player.GetCityByID?), get all non-capital cities, and then delete them. I don't see a delete function on the Modding Wiki yet In-Game Editor is able to delete cities entirely so this must be possible via LUA.
     
  2. TopHatPaladin

    TopHatPaladin Chieftain

    Joined:
    Nov 5, 2017
    Messages:
    64
    Gender:
    Male
    Location:
    New England
    Try adding this to your function:

    Code:
    for city in player:Cities() do
        if player:GetCapitalCity() ~= city then
            local plot = city:Plot()
            local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
            local cityID = city:GetID()
            city:Kill()
            Events.SerialEventCityDestroyed(hexpos, playerID, cityID, -1)
        end
    end
    player:Cities() is a function that iterates through all the cities of the player object that calls it. city:Kill() is the relevant function that actually destroys the city; the other functions instantiate the necessary variables to fire SerialEventCityDestroyed so the game can react appropriately.

    This code also uses vectors to calculate hexpos, so in order for that to function, add this line at the beginning of the file:
    Code:
    include("FLuaVector.lua")
    And, of course, I don't know what variable names you're using for the player object and its ID, so don't forget to correct those if you named them something different.
     
  3. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,250
    Location:
    Near Portsmouth, UK
    Bear in mind that culture and tech penalties are based on number of cities EVER owned, not just those currently owned. Late game, the AI is going to take an awfully long time to research Mining (or any of the other 1st column techs) due to those penalties.
     
  4. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    I'm glad to see that it's so simple, and knowing that there's a function to cycle through all of a player's cities will be helpful for the future! Thank you!


    This is mainly intended to be a wild joke sort of event for AI-only games so I'm not really worried about balance. Though nonetheless thank you for the warning!


    In the mean time I've been looking through the Mod Wiki for any LUA routines that would help me accomplish the rest. The big roadblock is finding a proper game event to hook this into. I'd simply base it on some of the code from my Pleco mod but I only want it to affect the player the unit performs a concert tour in (the pleco unit destroys resources based on where it ends its' turn and checks the plot owner) and not any civs that the unit is just passing through. I dug through Brave New World's files to see if I could find the LUA used for the Great Musician's functions and check which game event it uses, but I could find nothing at all related to the unit or concert tours in any of the LUA files. I fired up the game and checked the LUA logs to see if any scripts or game events reported anything to the log when a normal musician was used in order to aid my search, but nothing was printed to the log. Is there anywhere else I can look or do I have to just use one of the default GameEvents?
     
  5. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    711
    Gender:
    Male
    Location:
    The Netherlands
    I've used GameEvents.UnitPreKill to track expending great musicians in my achievements-mod (as france, you unlock an achievement when you expend a great musician in the lands of a civ with who you are at war)
    Unfortunately there is no way to find out if the player disbanded or performed a concert tour with the musician, but that's not much of an issue (since you won't be disbanding your musician anyways)


    NOTE: I have snipped some logic used for my mod (such as ActivePlayer checking and Achievement-related methods)
    Spoiler :
    Code:
    local iGreatMusician = GameInfoTypes.UNIT_MUSICIAN;
    local iFrance = GameInfoTypes.CIVILIZATION_FRANCE;
    
    function CheckWarConcertTour(iPlayer,iUnit,_,iX,iY,bDelay,iKiller)
    
            local pPlayer = Players[iPlayer];
            --playing as france and human
            if iKiller == -1 and pPlayer:GetCivilizationType()==iFrance then
                local pUnit = pPlayer:GetUnitByID(iUnit);
                local iPlotOwner = pUnit:GetPlot():GetOwner();
                --no neutral land, great musician expended, and not owning the plot yourself
                if iPlotOwner>=0 and pUnit:GetUnitType()==iGreatMusician and iPlotOwner~=iPlayer then
                    local iPlotTeam = Players[iPlotOwner]:GetTeam();
                    --at war with the plot owner + major civ
                    if Teams[pPlayer:GetTeam()]:IsAtWar(iPlotTeam) and not Players[iPlotOwner]:IsMinorCiv() then
                        --insert city kill logic here
                    end
                end
            end
    end
    
    GameEvents.UnitPrekill.Add(CheckWarConcertTour);
    
    


    As you may notice, many things can be achieved by using the standard GameEvents in interesting ways.
     
  6. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    Thank you very much for the example code! Now that I have an event to hook into I decided to piece together some code and give it a try in-game. The game is running the code with no errors (except if I uncomment the SetPopulation which it then gives me a null/invalid instance error) and it is running the proper checks, but the code itself isn't doing anything its' supposed to. Did I make any mistakes in the code?

    Code:
    include("FLuaVector.lua")
    
    print("Big Chungus")
    
    local iUnitBigChungus = GameInfoTypes.UNIT_BIG_CHUNGUS
    local iChungusUnitClass = GameInfoTypes.UNITCLASS_BIG_CHUNGUS
    
    function ChungusPrimalReversion(iPlayer)
        local pPlayer = Players[iPlayer]
        if (pPlayer:GetUnitClassCount(iChungusUnitClass) > 0) then
          for pUnit in pPlayer:Units() do
            if (pUnit:GetUnitType() == iUnitBigChungus) then
              local pPlot = pUnit:GetPlot()
              local iOriginalPlotOwner = pPlot:GetOwner()
               if (iOriginalPlotOwner ~= -1) and (iOriginalPlotOwner ~= iPlayer) then
                       local pPlotOwnerPlayer = Players[iOriginalPlotOwner]
                       for city in pPlayer:Cities(pPlotOwnerPlayer) do
                          if pPlayer:GetCapitalCity() ~= city then
                            local plot = city:Plot()
                            local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
                            local cityID = city:GetID()
                            city:Kill()
                           Events.SerialEventCityDestroyed(hexpos, playerID, cityID, -1)
                         -- else
                            --City:SetPopulation(1)
                           end
                       end
               end
           end
         end
       end
    end
    GameEvents.UnitPrekill.Add(ChungusPrimalReversion);
     
  7. TopHatPaladin

    TopHatPaladin Chieftain

    Joined:
    Nov 5, 2017
    Messages:
    64
    Gender:
    Male
    Location:
    New England
    To get the most utility out of UnitPrekill, you'll want to use more of its variables*. UnitPrekill gives you seven different variables, of which you'll want four:

    - the first variable: the ID of the player whose unit just died
    - the second variable: the ID of the unit that just died
    - the fourth and fifth variables: the X- and Y-coordinates of the plot where the unit died

    Instead of iterating through the player's units, you can enter the unit ID into Player:GetUnitByID() for the appropriate unit object; then, to find the plot, you can enter the X- and Y-coordinates into Map.GetPlot(). After that, the rest of the function looks like it should work as intended. (The reason the current code isn't working, incidentally, is that when UnitPrekill files the unit is already considered dead; this means that the iterator wouldn't find the unit you're looking for, and even if it did, the game wouldn't know the unit's plot.)

    *: For more information on GameEvents and what you can do with them, I recommend the spreadsheet in post #6 of the linked thread.
     
  8. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    I wasn't sure where to plug in the unit cycle (I tried instead plugging the correct unit ID variable directly into the top of the function), and added the rest of the function's variables based on how Troller used them in his own code, along with trimming some extra unit checks. The code is still nonfunctional but I hope I am currently on the right track. The LUA log produces no errors.

    Code:
    include("FLuaVector.lua")
    
    print("Big Chungus")
    
    local iUnitBigChungus = GameInfoTypes.UNIT_BIG_CHUNGUS
    local iChungusUnitClass = GameInfoTypes.UNITCLASS_BIG_CHUNGUS
    
    
    function ChungusPrimalReversion(iPlayer, iUnitBigChungus,_ iX, iY)
              local pPlayer = Players[iPlayer]        
             local pPlot = Map.GetPlot(iX, iY)
             local iOriginalPlotOwner = pPlot:GetOwner()
              if (iOriginalPlotOwner ~= -1) and (iOriginalPlotOwner ~= iPlayer) then
                      local pPlotOwnerPlayer = Players[iOriginalPlotOwner]
                      for city in pPlayer:Cities(pPlotOwnerPlayer) do
                          if pPlayer:GetCapitalCity() ~= city then
                            local plot = city:Plot()
                            local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
                            local cityID = city:GetID()
                            city:Kill()
                           Events.SerialEventCityDestroyed(hexpos, playerID, cityID, -1)
                        -- else
                            --City:SetPopulation(1)
                          end
                      end
               end
      
    end
    
    GameEvents.UnitPrekill.Add(ChungusPrimalReversion);
     
  9. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,922
    Location:
    Illinois, USA
    Code:
    local pPlotOwnerPlayer = Players[iOriginalPlotOwner]
                      for city in pPlayer:Cities(pPlotOwnerPlayer) do
    the code is incorrect. If you want to run through the cities of the player that owns the plot rather than the cities of the player who owned the dead unit, you need:
    Code:
    
    local pPlotOwnerPlayer = Players[iOriginalPlotOwner]
                      for city in pPlotOwnerPlayer:Cities() do
    What you are attempting is to run through the cities of the player who owned the 'killed' unit. The issue also applies to
    Code:
    pPlayer:GetCapitalCity() 
    Which I would code as
    Code:
    if city:IsCapital() == false then
    rather than comparing one object variable to another. wherever possible avoid comparisons of object variables to other object variables.

    Also, you have undefined variables
    Code:
    local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
    "plot" is not how you have previously defined the plot object where the unit was killed. You defined it as "pPlot". So you are getting a nil value or a runtime error reported in the lua log for
    Code:
    local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
    nevermind that paragraph. I see where you defined the object. But it is also unecessary. "city:GetX()" and "city:GetY()" would work just as well and would not need you to define a second object-variable for the city plot.

    Here you also have an undefined variable
    Code:
    Events.SerialEventCityDestroyed(hexpos, playerID, cityID, -1)
    "playerID" is a nil value because no such variable has been defined.

    This line also does not work because you have an undefined variable-name
    Code:
    City:SetPopulation(1)
    "City" ~= "city".
     
    Last edited: Jan 11, 2019
  10. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    Thank you for the feedback! I fixed the code based on the changes you mentioned. I replaced the playerID value with pPlotOwnerPlayer since this would be the proper player ID to use. Unfortunately the code is still having no effect, and the Lua log still reports no errors. The comment I placed in there to see if the check is working isn't popping up in the Lua log so one of the checks from the first if statement onward seems to be failing. Here is the current code:

    Code:
    include("FLuaVector.lua")
    
    print("Big Chungus")
    
    local iUnitBigChungus = GameInfoTypes.UNIT_BIG_CHUNGUS
    local iChungusUnitClass = GameInfoTypes.UNITCLASS_BIG_CHUNGUS
    
    function ChungusPrimalReversion(iPlayer, iUnitBigChungus,_ iX, iY)
              local pPlayer = Players[iPlayer]        
             local pPlot = Map.GetPlot(iX, iY)
             local iOriginalPlotOwner = pPlot:GetOwner()
              if (iOriginalPlotOwner ~= -1) and (iOriginalPlotOwner ~= iPlayer) then
                      local pPlotOwnerPlayer = Players[iOriginalPlotOwner]
                       for city in pPlotOwnerPlayer:Cities() do
                          if city:IsCapital() == false then
                            local plot = city:Plot()
                            local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
                            local cityID = city:GetID()
                            city:Kill()
                           print("Primal Reverted!")
                           Events.SerialEventCityDestroyed(hexpos, pPlotOwnerPlayer, cityID, -1)
                         else
                            city:SetPopulation(1)
                          end
                      end
               end
      
    end
    
    GameEvents.UnitPrekill.Add(ChungusPrimalReversion);
     
  11. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,922
    Location:
    Illinois, USA
    this
    Code:
    Events.SerialEventCityDestroyed(hexpos, pPlotOwnerPlayer, cityID, -1)
    is incorrect. It needs a player ID# for the second argument rather than a player object-variable. In your case the player ID variable would be "iOriginalPlotOwner".

    Is "Big Chungus" even being printed into the lua.log file when the game loads? If it is not, then you do not have the lua-file set-up correctly.
     
  12. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,922
    Location:
    Illinois, USA
    Code:
    <event name="UnitPrekill" type="Hook">
    	<arg pos="1" type="PlayerTypes" name="ePlayer"/>	--this is the ID# for the player whose unit was killed
    	<arg pos="2" type="int" name="iUnit"/>			--this is the ID# for the individual unit that was killed
    	<arg pos="3" type="UnitTypes" name="eUnit"/>		--this is the ID# for the TYPE of unit from XML table "Units" that was killed
    	<arg pos="4" type="int" name="iPlotX"/>			--this is the plot X gridpoint where the unit was killed
    	<arg pos="5" type="int" name="iPlotY"/>			--this is the plot Y gridpoint where the unit was killed
    	<arg pos="6" type="bool" name="bDelay"/>		--this is boolean for whether the "killing" of the unit is delayed when the event fires
    								--the event can fire twice for every unit killed. When it fires twice the first firing is
    									actually before the unit is killed, and the 'bDelay' argument will be boolean true
    								--you cannot accurately check which units are seen as being on the plot at the passed XY
    									when bDelay is true
    								--when bDealy is false you can check if any victorious-combat units of the "killer" are
    									occupying the plot by iterating through all units currently seen as being on the
    									plot. The killed-off unit will still show in the list of units seen as being on
    									the plot.
    	<arg pos="7" type="PlayerTypes" name="eByPlayer"/>	--this is the ID# of the player who killed the unit. If a player kills his own unit, such
    									as by creating a city with a settler, this argument will pass the same ID # as that
    									which is passed for argument "ePlayer"
    								--this argument only passes a valid player ID# when bDelay is true
    								--when bDelay is false the data for this argument is usually "-1"
    </event>
     
  13. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    I need to get this keyboard fixed... I know I typed a comma between _ and iPlotX yet there isn't one there. Fixed that and now the code runs flawlessly!
    Now to add the tech removal function, I can do that with TeamTechs:SetHasTech() but I'll take care of that myself. Thank you all for everything! :)
     
  14. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    Seems like I'm not out of the woods yet.... : (
    The unit now works 100% as intended, and a copy of the unit spawns with a wonder I added, but.... for some reason this is causing the game to randomly crash on some computers. After the AI builds it the Unit that this code checks against will linger in their civ's territory and after that it will crash on a random turn number on a random player's turn, no matter the map size or amount of players. We were able to pinpoint the issue to this mod, I don't understand what about this is crashing the game. No errors in the logs or anything, just a big boot back to the desktop.

    Code:
    include("FLuaVector.lua")
    
    print("Big Chungus")
    
    local iUnitBigChungus = GameInfoTypes.UNIT_BIG_CHUNGUS
    
    
    function ChungusPrimalReversion(iPlayer,iUnit,_,iPlotX, iPlotY, bDelay)
              local pPlayer = Players[iPlayer]        
             local pPlot = Map.GetPlot(iPlotX, iPlotY)
             local pUnit = pPlayer:GetUnitByID(iUnit);
             local iOriginalPlotOwner = pPlot:GetOwner()
                  
              if (iOriginalPlotOwner ~= -1) and pUnit:GetUnitType()==iUnitBigChungus then -- (iOriginalPlotOwner ~= iPlayer) then
                      local pPlotOwnerPlayer = Players[iOriginalPlotOwner]
                       for city in pPlotOwnerPlayer:Cities() do
                          if city:IsCapital() == false then
                            local plot = city:Plot()
                            local hexpos = ToHexFromGrid(Vector2(plot:GetX(), plot:GetY()));
                            local cityID = city:GetID()
                            city:Kill()
                           print("Primal Reverted!")
                           Events.SerialEventCityDestroyed(hexpos, iOriginalPlotOwner, cityID, -1)
                         else
                            city:SetPopulation(1)
                          end
                      end
    
                      local RevertedTeam = Teams[pPlotOwnerPlayer:GetTeam()]
                      RevertedTeam:SetHasTech(1, false)
                      RevertedTeam:SetHasTech(2, false)
                      RevertedTeam:SetHasTech(3, false)
                      RevertedTeam:SetHasTech(4, false)
                      RevertedTeam:SetHasTech(5, false)
                      RevertedTeam:SetHasTech(6, false)
                      RevertedTeam:SetHasTech(7, false)
                      RevertedTeam:SetHasTech(8, false)
                      RevertedTeam:SetHasTech(9, false)
                      RevertedTeam:SetHasTech(10, false)
                      RevertedTeam:SetHasTech(11, false)
                      RevertedTeam:SetHasTech(12, false)
                      RevertedTeam:SetHasTech(13, false)
                      RevertedTeam:SetHasTech(14, false)
                      RevertedTeam:SetHasTech(15, false)
                      RevertedTeam:SetHasTech(16, false)
                      RevertedTeam:SetHasTech(17, false)
                      RevertedTeam:SetHasTech(18, false)
                      RevertedTeam:SetHasTech(19, false)
                      RevertedTeam:SetHasTech(20, false)
                      RevertedTeam:SetHasTech(21, false)
                      RevertedTeam:SetHasTech(22, false)
                      RevertedTeam:SetHasTech(23, false)
                      RevertedTeam:SetHasTech(24, false)
                      RevertedTeam:SetHasTech(25, false)
                      RevertedTeam:SetHasTech(26, false)
                      RevertedTeam:SetHasTech(27, false)
                      RevertedTeam:SetHasTech(28, false)
                      RevertedTeam:SetHasTech(29, false)
                      RevertedTeam:SetHasTech(30, false)
                      RevertedTeam:SetHasTech(31, false)
                      RevertedTeam:SetHasTech(32, false)
                      RevertedTeam:SetHasTech(33, false)
                      RevertedTeam:SetHasTech(34, false)
                      RevertedTeam:SetHasTech(35, false)
                      RevertedTeam:SetHasTech(36, false)
                      RevertedTeam:SetHasTech(37, false)
                      RevertedTeam:SetHasTech(38, false)
                      RevertedTeam:SetHasTech(39, false)
                      RevertedTeam:SetHasTech(40, false)
                      RevertedTeam:SetHasTech(41, false)
                      RevertedTeam:SetHasTech(42, false)
                      RevertedTeam:SetHasTech(43, false)
                      RevertedTeam:SetHasTech(44, false)
                      RevertedTeam:SetHasTech(45, false)
                      RevertedTeam:SetHasTech(46, false)
                      RevertedTeam:SetHasTech(47, false)
                      RevertedTeam:SetHasTech(48, false)
                      RevertedTeam:SetHasTech(49, false)
                      RevertedTeam:SetHasTech(50, false)
                      RevertedTeam:SetHasTech(51, false)
                      RevertedTeam:SetHasTech(52, false)
                      RevertedTeam:SetHasTech(53, false)
                      RevertedTeam:SetHasTech(54, false)
                      RevertedTeam:SetHasTech(55, false)
                      RevertedTeam:SetHasTech(56, false)
                      RevertedTeam:SetHasTech(57, false)
                      RevertedTeam:SetHasTech(58, false)
                      RevertedTeam:SetHasTech(59, false)
                      RevertedTeam:SetHasTech(60, false)
                      RevertedTeam:SetHasTech(61, false)
                      RevertedTeam:SetHasTech(62, false)
                      RevertedTeam:SetHasTech(63, false)
                      RevertedTeam:SetHasTech(64, false)
                       RevertedTeam:SetHasTech(65, false)
                      RevertedTeam:SetHasTech(66, false)
                      RevertedTeam:SetHasTech(67, false)
                      RevertedTeam:SetHasTech(68, false)
                      RevertedTeam:SetHasTech(69, false)
                      RevertedTeam:SetHasTech(70, false)
                      RevertedTeam:SetHasTech(71, false)
                      RevertedTeam:SetHasTech(72, false)
                      RevertedTeam:SetHasTech(73, false)
               end
      
    end
    
    GameEvents.UnitPrekill.Add(ChungusPrimalReversion);
     
  15. TopHatPaladin

    TopHatPaladin Chieftain

    Joined:
    Nov 5, 2017
    Messages:
    64
    Gender:
    Male
    Location:
    New England
    I'm not sure what might be causing the crash, but— on an unrelated note— you can remove the player's techs more easily if you use a for loop:
    Code:
    for iTech = 1, 73, 1 do
        RevertedTeam:SetHasTech(iTech, false)
    end
     
  16. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    711
    Gender:
    Male
    Location:
    The Netherlands
    You could try adding some print("text here")-statements throughout the code to see which part may cause the crash.
    Also, is your tech tree modified? Perhaps it could be related to you trying to do "RevertedTeam:SetHasTech(ID, false)" for an ID that is not in the technologies table (which may happen when you remove a tech).
     
  17. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,250
    Location:
    Near Portsmouth, UK
    Code:
    for tech in GameInfo.Technologies() do
      if (tech.ID > 0) then
        RevertedTeam:SetHasTech(tech.ID, false)
      end
    end
    
     
    TopHatPaladin likes this.
  18. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    195
    Gender:
    Male
    Location:
    Pennsylvania
    Thank you very much for the loop for the tech removal code, I was wondering if there was a better way to do it when I pasted that long list! xD

    The problem is that the crash doesn't occur when the unit is used (I've tested that many times with no issues). It'll just happen at the start of a random player's turn on a random turn number. The only thing that's consistent is that it happens some time after someone built the wonder and that the unit is on the field, usually in the builder's territory. Though the player who's turn crashes the game isn't even the builder of the unit. For example, Kamehameha could build the wonder and have the unit, yet it's Huey Long's turn that crashes the game. We could then reload a save, delete Huey using IGE, but then say Washington is one or two players afterward. Then the start of Washington's turn would crash the game. It always happens at the beginning of a turn, so none of the logs will tell me exactly what the AI was trying to do when it happened. Is there any way to check this? I noticed it happens more easily on my friend's more heavily-modded setup but it contains no mechanics mods, just custom civs, and it was perfectly fine before we started using this mod. So far I've encountered no crashes on my own setup, but I want to see if the issue is this mod's code. We were able to have a 43-player match on my friend's setup with no crashes before adding this mod.
     
  19. Enginseer

    Enginseer Salientia of the Community Patch Supporter

    Joined:
    Nov 7, 2012
    Messages:
    3,079
    Gender:
    Male
    Location:
    Somewhere in California
    Except Custom Civs are heavily modded.
     
  20. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    5,922
    Location:
    Illinois, USA
    The first thing I would do is as mentioned earlier. Lace print statements into the code to see if any of them are printed into the lua.log as the last thing before the crash.

    As you've currently written your code, however, the owner of the unit can delete their own cities and de-tech themselves if they kill off the unit within their own territory.

    One thing I remember causing one of my games a long time ago to become unrecoverable was using IGE to delete an adversary city that had a trade-route starting from that city. It CTD'd when I progressed turns and if I tried to load a save from the turn when I deleted the city.
     

Share This Page