[GS] How to fix the Runtime Error of Lua?

Lenin1870

Chieftain
Joined
Mar 16, 2013
Messages
50
Runtime Error: C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\JFD_YukinoGermany_Utils.lua:27: operator .. is not supported for table .. string
stack traceback:
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\JFD_YukinoGermany_Utils.lua:27: in function 'Player_GetMilitarizationBalance'
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\YukinoGermany_GamePlay.lua:87: in function 'pPlayerMilitarizationBonus'
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\YukinoGermany_GamePlay.lua:65: in function 'pPlayerOnCombat'
[C]: in function 'func'
[C]: in function '(anonymous)'


JFD_YukinoGermany_Utils
Code:
-- JFD_YukinoGermany_Utils
-- Author: JFD
-- DateCreated: 4/1/2020 8:00:04 PM
--===========================================================================
-- INCLUDES
--===========================================================================
----------------------------------------------------------------------------
include("JFD_YukinoGermany_SaveUtils.lua"); 
--===========================================================================
-- CACHING UTILS
--===========================================================================     
----------------------------------------------------------------------------
local SavePlayerValue;
local LoadPlayerValue;

--JFD_YukinoGermany_InitSaveUtils
function JFD_YukinoGermany_InitSaveUtils()
    SavePlayerValue = ExposedMembers.YukinoGermany.SavePlayerValue;
    LoadPlayerValue = ExposedMembers.YukinoGermany.LoadPlayerValue;
end
JFD_YukinoGermany_InitSaveUtils()
----------------------------------------------------------------------------
-- Militarization YIELD
----------------------------------------------------------------------------
--Player_GetMilitarizationBalance
function Player_GetMilitarizationBalance(iPlayerID)
    return LoadPlayerValue(iPlayerID, iPlayerID .. "_MILITARIZATION") or 0
end     
----------------------------------------------------------------------------
--Player_GetMilitarizationBalanceMax
function Player_GetMilitarizationBalanceMax(iPlayerID)
    local numMax = 100
    return numMax
end   
----------------------------------------------------------------------------
--Player_ChangeMilitarizationBalance
function Player_ChangeMilitarizationBalance(iPlayerID, iNumChange)
    local pPlayer = Players[iPlayerID];
    local numMilitarizationBalance = Player_GetMilitarizationBalance(iPlayerID);
    local numMilitarizationBalanceMax = Player_GetMilitarizationBalanceMax(iPlayerID);
    local newMilitarizationBalance = math.min(numMilitarizationBalanceMax, (numMilitarizationBalance + iNumChange));
    Player_SetMilitarizationBalance(iPlayerID, math.max(newMilitarizationBalance, 0))
end                       
----------------------------------------------------------------------------
--Player_SetMilitarizationBalance
function Player_SetMilitarizationBalance(iPlayerID, iNumSet)
    SavePlayerValue(iPlayerID, iPlayerID .. "_MILITARIZATION", iNumSet)
    LuaEvents.JFD_UpdateTopPanelMilitarization()
end

----------------------------------------------------------------------------
--Player_GetMilitarizationPerTurn
function Player_GetMilitarizationPerTurn(iPlayerID, bReturnsTT)
    local pPlayer = Players[iPlayerID];
    local numGetMilitarizationPerTurn = Player_GetMilitarizationBalance(iPlayerID);
    local strTopPanelTT = "";
    if bReturnsTT then
        strTopPanelTT = Locale.Lookup("LOC_JFD_TOP_PANEL_MILITARIZATION_TT")
        if numGetMilitarizationPerTurn > 0 then
            strTopPanelTT = strTopPanelTT .. Locale.Lookup("LOC_JFD_TOP_PANEL_MILITARIZATION_TT_FROM_CAUSE", "+" .. numGetMilitarizationPerTurn)
        else
            strTopPanelTT = strTopPanelTT .. Locale.Lookup("LOC_JFD_TOP_PANEL_MILITARIZATION_TT_FROM_CAUSE", numGetMilitarizationPerTurn)
        end
    end
    strTopPanelTT = strTopPanelTT .. "[NEWLINE][NEWLINE]" .. Locale.Lookup("LOC_TOP_PANEL_JFD_MILITARIZATION_TOOLTIP_SOURCES_HELP")
    return numGetMilitarizationPerTurn, strTopPanelTT
end


YukinoGermany_GamePlay
Code:
-- YukinoGermany_GamePlay
-- Author: Yukino-Chan
-- DateCreated: 3/30/2020 9:14:40 PM
--------------------------------------------------------------
include("JFD_YukinoGermany_Utils.lua");

local ProjectEncampmentTrainingID = GameInfo.Projects["PROJECT_ENHANCE_DISTRICT_ENCAMPMENT"].Index;

function pPlayerUnitsGetOrLoseMilitarizationYield(iKilledPlayerID, iKilledUnitID, iPlayerID, iUnitID)
    local pKilledPlayer = Players[iKilledPlayerID];
    local pKilledPlayerConfig = PlayerConfigurations[iKilledPlayerID];
    local pKilledUnit = pKilledPlayer:GetUnits():FindID(iKilledUnitID);
    local pPlayer = Players[iPlayerID];
    local pPlayerConfig = PlayerConfigurations[iPlayerID];
    local pUnit = pPlayer:GetUnits():FindID(iUnitID);
    if pPlayer:IsAlive() and pPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" and pKilledPlayer:IsAlive() then
        if pUnit ~= pKilledUnit and UnitManager.Kill(pKilledUnit) then
            Player_ChangeMilitarizationBalance(iPlayerID, 1)
        end
    elseif pPlayer:IsAlive() and pKilledPlayer:IsAlive() and pKilledPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        if pUnit ~= pKilledUnit and UnitManager.Kill(pKilledUnit) then
            Player_ChangeMilitarizationBalance(iPlayerID, 1)
        end
    end
end
Events.UnitKilledInCombat.Add(pPlayerUnitsGetOrLoseMilitarizationYield);

function pPlayerCityGetOrLoseMilitarizationYield(iNewPlayerID, iOldPlayerID, iNewCityID, iCityX, iCityY)
    local pNewPlayer = Players[iNewPlayerID];
    local pNewPlayerConfig = PlayerConfigurations[iNewPlayerID];
    local pOldPlayer = Players[iOldPlayerID];
    local pOldPlayerConfig = PlayerConfigurations[iOldPlayerID];
    if pNewPlayer:IsAlive() and pNewPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" and pOldPlayer:IsAlive() then
        Player_ChangeMilitarizationBalance(iPlayerID, -1)
    elseif pOldPlayer:IsAlive() and pOldPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" and pNewPlayer:IsAlive() then
        Player_ChangeMilitarizationBalance(iPlayerID, -1)
    end
end
GameEvents.CityConquered.Add(pPlayerCityGetOrLoseMilitarizationYield);

function pPlayerEncampmentTrainingCompleteGetMilitarizationYield(iPlayerID, iCityID, iProjectID, iBuildingIndex, iX, iY, bCancelled)
    local pPlayer = Players[iPlayerID];
    local pPlayerConfig = PlayerConfigurations[iPlayerID];
    local pCity = pPlayer:GetCities():FindID(iCityID);
    if pPlayer:IsAlive() and pPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        if iProjectID == ProjectEncampmentTrainingID and bCancelled == false and pCity == pPlayer:GetCities():Members() then
            Player_ChangeMilitarizationBalance(iPlayerID, 5)
        end
    end
end
Events.CityProjectCompleted.Add(pPlayerEncampmentTrainingCompleteGetMilitarizationYield);

function pPlayerDeficitLoseMilitarizationYield(iPlayerID, iGoldPerTurn, iCurrentTreasury)
    local pPlayer = Players[iPlayerID];
    local pPlayerConfig = PlayerConfigurations[iPlayerID];
    if pPlayer:IsAlive() and pPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" and iGoldPerTurn < 0 then
        Player_ChangeMilitarizationBalance(iPlayerID, -1)
    end
end
Events.TreasuryChanged.Add(pPlayerDeficitLoseMilitarizationYield);

function pPlayerOnCombat(m_CombatResults)
    local attacker = m_CombatResults[CombatResultParameters.ATTACKER]
    local defender = m_CombatResults[CombatResultParameters.DEFENDER]
    pPlayerMilitarizationBonus(attacker, defender)
    pPlayerKillBonus(attacker, defender)
end
Events.Combat.Add(pPlayerOnCombat);

function pPlayerMilitarizationBonus(attacker, defender)
    local attackerID = attacker[CombatResultParameters.ID];
    local pAttackingPlayer = Players[attackerID.player];
    local pAttackingPlayerConfig = PlayerConfigurations[attackerID.player];
    local pAttackingPlayerUnits = pAttackingPlayer:GetUnits();
    local defenderID = defender[CombatResultParameters.ID];
    local pDefendingPlayer = Players[defenderID.player];
    local pDefendingPlayerConfig = PlayerConfigurations[defenderID.player];
    local pDefendingPlayerUnits = pDefendingPlayer:GetUnits();
    local iAttackerCombatStrength    = attacker[CombatResultParameters.COMBAT_STRENGTH];
    local iDefenderCombatStrength    = defender[CombatResultParameters.COMBAT_STRENGTH];
    local iAttackerBonus            = attacker[CombatResultParameters.STRENGTH_MODIFIER];
    local iDefenderBonus            = defender[CombatResultParameters.STRENGTH_MODIFIER];
    local iPlayerUnitExperienceBonus = MilitarizationPerTurn;

    if pAttackingPlayer:IsAlive() and pAttackingPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        for i, pAttackingPlayerUnit in pAttackingPlayerUnits:Members() do
            iAttackerBonus = iAttackerBonus + iAttackerCombatStrength * 0.01 * Player_GetMilitarizationBalance(attackerID, "_MILITARIZATION")
            pAttackingPlayerUnit:ChangeDamage(iAttackerBonus)
            pAttackingPlayerUnit:GetExperience():ChangeExperience(iPlayerUnitExperienceBonus)
        end
    elseif pDefendingPlayer:IsAlive() and pDefendingPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        for i, pDefendingPlayerUnit in pDefendingPlayerUnits:Members() do
            iDefenderBonus = iDefenderBonus + iDefenderCombatStrength * 0.01 * Player_GetMilitarizationBalance(defenderID, "_MILITARIZATION")
            pDefendingPlayerUnit:ChangeDamage(iDefenderBonus)
            pDefendingPlayerUnit:GetExperience():ChangeExperience(iPlayerUnitExperienceBonus)
        end
    end
end

function pPlayerKillBonus(attacker, defender)
    local attackerID = attacker[CombatResultParameters.ID];
    local pAttackingPlayer = Players[attackerID.player];
    local pAttackingPlayerConfig = PlayerConfigurations[attackerID.player];
    local pAttackingPlayerUnits = pAttackingPlayer:GetUnits();
    local defenderID = defender[CombatResultParameters.ID];
    local pDefendingPlayer = Players[defenderID.player];
    local pDefendingPlayerConfig = PlayerConfigurations[defenderID.player];
    local pDefendingPlayerUnits = pDefendingPlayer:GetUnits();

    if pAttackingPlayer:IsAlive() and pAttackingPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        local pkAttacker = UnitManager.GetUnit(attackerID.player, attackerID.id);
        local pPlayerEnemyUnitsKillRate = 0.1 * Player_GetMilitarizationBalance(attackerID, "_MILITARIZATION");
        if Automation.GetRandomNumber(100) <= pPlayerEnemyUnitsKillRate then
            for i, pDefendingPlayerUnit in pDefendingPlayerUnits:Members() do
                pkAttacker.Kill(pDefendingPlayerUnit)
            end
        end
    elseif pDefendingPlayer:IsAlive() and pDefendingPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        local pkDefender = UnitManager.GetUnit(defenderID.player, defenderID.id);
        local pPlayerEnemyUnitsKillRate = 0.1 * Player_GetMilitarizationBalance(defenderID, "_MILITARIZATION");
        if Automation.GetRandomNumber(100) <= pPlayerEnemyUnitsKillRate then
            for i, pAttackingPlayerUnit in pAttackingPlayerUnits:Members() do
                 pkDefender.Kill(pAttackingPlayerUnit)
            end
        end
    end
end
return LoadPlayerValue(iPlayerID, iPlayerID .. "_MILITARIZATION") or 0 - I don't know why this sentense has an issue. I have no idea on the error. I've tried many things, but it has not work in any case, and the militarization value of the top panel is not changed. Is there a way to solve this issue?
 
Last edited:
attackerID in your code here
Code:
local attackerID = attacker[CombatResultParameters.ID];
is a table, to get the Id, use attackerID.id like in
Code:
local pkAttacker = UnitManager.GetUnit(attackerID.player, attackerID.id)

so change
Code:
Player_GetMilitarizationBalance(attackerID, "_MILITARIZATION");
to
Code:
Player_GetMilitarizationBalance(attackerID.id, "_MILITARIZATION");
 
attackerID in your code here
Code:
local attackerID = attacker[CombatResultParameters.ID];
is a table, to get the Id, use attackerID.id like in
Code:
local pkAttacker = UnitManager.GetUnit(attackerID.player, attackerID.id)

so change
Code:
Player_GetMilitarizationBalance(attackerID, "_MILITARIZATION");
to
Code:
Player_GetMilitarizationBalance(attackerID.id, "_MILITARIZATION");

Runtime Error: C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\JFD_YukinoGermany_SaveUtils.lua:27: attempt to index a nil value
stack traceback:
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\JFD_YukinoGermany_SaveUtils.lua:27: in function 'GetPlayerValue'
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\JFD_YukinoGermany_Utils.lua:27: in function 'Player_GetMilitarizationBalance'
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\YukinoGermany_GamePlay.lua:83: in function 'pPlayerMilitarizationBonus'
C:\Users\Partiya\Documents\My Games\Sid Meier's Civilization VI\Mods\YukinoGermany\Core\Lua\YukinoGermany_GamePlay.lua:65: in function 'pPlayerOnCombat'


JFD_YukinoGermany_SaveUtils

Code:
-- JFD_YukinoGermany_SaveUtils
-- Author: JFD
-- DateCreated: 2/15/2018 1:48:03 AM
--===========================================================================
-- CORE UTILS
--===========================================================================
----------------------------------------------------------------------------
--GetGameProperty
function GetGameProperty(strKey)
    return Game.GetProperty(strKey)
end
----------------------------------------------------------------------------
--GetGameValue
function GetGameValue(strKey)
    return GameConfiguration.GetValue(strKey)
end
----------------------------------------------------------------------------
--GetPlayerProperty
function GetPlayerProperty(playerID, strKey)
    local player = Players[playerID]
    return player:GetProperty(strKey)
end
----------------------------------------------------------------------------
--GetPlayerValue
function GetPlayerValue(playerID, strKey)
    local playerConfig = PlayerConfigurations[playerID]
    return playerConfig:GetValue(strKey)
end
----------------------------------------------------------------------------
--SetGameProperty
function SetGameProperty(strKey, value)
    Game.SetProperty(strKey, value)
end
----------------------------------------------------------------------------
--SetGameValue
function SetGameValue(strKey, value)
    GameConfiguration.SetValue(strKey, value)
end
----------------------------------------------------------------------------
--SetPlayerProperty
function SetPlayerProperty(playerID, strKey, value)
    local player = Players[playerID]
    player:SetProperty(strKey, value)
end
----------------------------------------------------------------------------
--SetPlayerValue
function SetPlayerValue(playerID, strKey, value)
    local playerConfig = PlayerConfigurations[playerID]
    playerConfig:SetValue(strKey, value)
end
----------------------------------------------------------------------------
--JFD_YukinoGermany_InitCachingFunctions
function JFD_YukinoGermany_InitCachingFunctions()
    if (not ExposedMembers.YukinoGermany) then
        ExposedMembers.YukinoGermany = {}
    end
      
    ExposedMembers.YukinoGermany.SaveGameProperty = SetGameProperty
    ExposedMembers.YukinoGermany.SaveGameValue = SetGameValue
    ExposedMembers.YukinoGermany.SavePlayerProperty  = SetPlayerProperty
    ExposedMembers.YukinoGermany.SavePlayerValue = SetPlayerValue

    ExposedMembers.YukinoGermany.LoadGameProperty = GetGameProperty
    ExposedMembers.YukinoGermany.LoadGameValue = GetGameValue
    ExposedMembers.YukinoGermany.LoadPlayerProperty = GetPlayerProperty
    ExposedMembers.YukinoGermany.LoadPlayerValue = GetPlayerValue
end
JFD_YukinoGermany_InitCachingFunctions()
--===========================================================================
--===========================================================================

I fixed that part, but new error has arisen.
--GetPlayerValue
function GetPlayerValue(playerID, strKey)

local playerConfig = PlayerConfigurations[playerID]
return playerConfig:GetValue(strKey)

end

I think there is an error here. The strKey clearly means to insert string in the argument of function, but I don't know why string key is dealt with nil.
 
The error can be anywhere in the functions listed in the report, you have to track the parameters used to call GetPlayerValue in those functions to find where playerID is not a player ID, the problem is at the line with PlayerConfigurations[playerID], and so playerConfig = nil, which give the error at the next line.
 
The error can be anywhere in the functions listed in the report, you have to track the parameters used to call GetPlayerValue in those functions to find where playerID is not a player ID, the problem is at the line with PlayerConfigurations[playerID], and so playerConfig = nil, which give the error at the next line.
The same part causes "function expected instead of nil" error. What is this error? I just change blablaID.id of Player_GetMilitarizationBalance argument to blablaID.player in YukinoGermany_GamePlay, because it is cause of attempt to index a nil value error.
 
Somewhere you try to call a function but that function doesn't exist. Could be a typo (changing a letter in the function name by mistake), or could happen when you try to call a function directly at line 10 while the function itself is defined at line 20 for example.
 
Somewhere you try to call a function but that function doesn't exist. Could be a typo (changing a letter in the function name by mistake), or could happen when you try to call a function directly at line 10 while the function itself is defined at line 20 for example.
Now all issues in Lua.log resolves. But militarization facility does not still work. This problem is complex, because it is not written by Lua.log.
20200413161311_1.jpg

For example, in the script, the calculation of militarization should be changed due to the encampment training, a district project, but it does not. It continues to mark zero, the city completes encampment training project though.
Code:
function pPlayerEncampmentTrainingCompleteGetMilitarizationYield(iPlayerID, iCityID, iProjectID, iBuildingIndex, iX, iY, bCancelled)
    local pPlayer = Players[iPlayerID]; 
    local pPlayerConfig = PlayerConfigurations[iPlayerID];
    local pCity = pPlayer:GetCities():FindID(iCityID);
    if pPlayer:IsAlive() and pPlayerConfig:GetCivilizationTypeName() == "CIVILIZATION_GERMANY" then
        if iProjectID == ProjectEncampmentTrainingID and bCancelled == false and pCity == pPlayer:GetCities():Members() then
            Player_ChangeMilitarizationBalance(iPlayerID, 5)
        end
    end
end
Events.CityProjectCompleted.Add(pPlayerEncampmentTrainingCompleteGetMilitarizationYield);
The corresponding code seems right. But I think Player_ChangeMilitarizationBalance(iPlayerID, 5) does not work. I uploaded the Luas involved in this. I'd appreciate it if you could check the scripts.
 

Attachments

  • Lua.zip
    4.9 KB · Views: 32
Top Bottom