[NFP] Why won't the DiplomacyDeclareWar event register?

DeckerdJames

Warlord
Joined
Nov 1, 2019
Messages
235
I was having a problem. I wanted to register for an event in my lua file. I put the following into my lua file that is in a UIContext. The game would hang while it was trying to load a new game.
Code:
function OnDiplomacyDeclareWar(FirstID, SecondID)
    print("OnDiplomacyDeclareWar")
end
Events.DiplomacyDeclareWar(OnDiplomacyDeclareWar)

It would hang when the game was loading at the last line of this, in the lua console of Firetuner. The leader description page was displayed but the button to enter the new game had not come up yet.
Code:
 TutorialUIRoot: Tutorial: Firaxis in game tutorial prompts.
 TutorialUIRoot: Version: 1
 TutorialUIRoot: Loading bank of items for tutorial scenario: 'BASE'

so I sought to register the event during the LoadGameViewStateDone event, which is the last line in the lua console output when loading a new game. Like this:
Code:
function OnLoadGameViewStateDone()
    Events.DiplomacyDeclareWar(OnDiplomacyDeclareWar)
end
Events.LoadGameViewStateDone( OnLoadGameViewStateDone )

this caused the game to get a little further, but still, it had an error before the game was ready to be entered and it bounced me back to the main menu. In the lua log it had some errors but I do not have a copy of them. Essentially it said (i think) that it was trying to use a nil string as an operator which was not allowed in two of the official Firaxis UI assets. They were:
...\Sid Meier's Civilization VI\Base\Assets\UI\DiplomacyRibbon.lua
...\Sid Meier's Civilization VI\DLC\Expansion2\UI\Replacements\DiplomacyRibbon_Expansion2.lua

the error was either in the UpdateLeaders() function below: from ...\Sid Meier's Civilization VI\Base\Assets\UI\DiplomacyRibbon.lua

Code:
function UpdateLeaders()

    ResetLeaders();   

    m_ribbonStats = Options.GetUserOption("Interface", "RibbonStats");


    -- Add entries for everyone we know (Majors only)
    local kPlayers        :table = PlayerManager.GetAliveMajors();
    local kMetPlayers    :table = {};
    local kUniqueLeaders:table = {};

    local localPlayerID:number = Game.GetLocalPlayer();
    local pPlayer : table = PlayerConfigurations[localPlayerID];
    if localPlayerID ~= -1 then
        local localPlayer    :table = Players[localPlayerID];
        local localDiplomacy:table = localPlayer:GetDiplomacy();
        table.sort(kPlayers, function(a:table,b:table) return localDiplomacy:GetMetTurn(a:GetID()) < localDiplomacy:GetMetTurn(b:GetID()) end);
                
        AddLeader("ICON_"..PlayerConfigurations[localPlayerID]:GetLeaderTypeName(), localPlayerID, {});        --First, add local player.
        kMetPlayers, kUniqueLeaders = GetMetPlayersAndUniqueLeaders();                                        --Fill table for other players.
    else
        -- No local player so assume it's auto-playing, or local player is dead and observing; show everyone.
        for _, pPlayer in ipairs(kPlayers) do
            local playerID:number = pPlayer:GetID();
            kMetPlayers[ playerID ] = true;
            if (kUniqueLeaders[playerID] == nil) then
                kUniqueLeaders[playerID] = true;
            else
                kUniqueLeaders[playerID] = false;
            end   
        end
    end

    --Then, add the leader icons.
    for _, pPlayer in ipairs(kPlayers) do
        local playerID:number = pPlayer:GetID();
        if(playerID ~= localPlayerID) then
            local isMet            :boolean = kMetPlayers[playerID];
            local pPlayerConfig    :table = PlayerConfigurations[playerID];
            local isHumanMP        :boolean = (GameConfiguration.IsAnyMultiplayer() and pPlayerConfig:IsHuman());
            if (isMet or isHumanMP) then
                local leaderName:string = pPlayerConfig:GetLeaderTypeName();
                local isMasked    :boolean = (isMet==false) and isHumanMP;    -- Multiplayer human but haven't met
                local isUnique    :boolean = kUniqueLeaders[leaderName];
                local iconName    :string = "ICON_LEADER_DEFAULT";
                
                -- If in an MP game and a player leaves the name returned will be NIL.               
                if isMet and (leaderName ~= nil) then
                    iconName = "ICON_"..leaderName;
                end
                
                AddLeader(iconName, playerID, {
                    isMasked=isMasked,
                    isUnique=isUnique
                    }
                );
            end
        end
    end

    RealizeSize();
end

or the error was in the one from the expansion from ...\Sid Meier's Civilization VI\DLC\Expansion2\UI\Replacements\DiplomacyRibbon_Expansion2.lua
Code:
function UpdateLeaders()
    -- Create and add World Congress button if one was allocated (based on capabilities)
    if m_kCongressButtonIM then
        if Game.GetEras():GetCurrentEra() >= GlobalParameters.WORLD_CONGRESS_INITIAL_ERA then       
            m_kCongressButtonIM:ResetInstances();
            local pPlayer:table = PlayerConfigurations[Game.GetLocalPlayer()];
            if(pPlayer ~= nil and pPlayer:IsAlive())then
                m_oCongressButton = CongressButton:GetInstance( m_kCongressButtonIM );
                m_congressButtonWidth = m_oCongressButton.Top:GetSizeX();
            else
                m_congressButtonWidth = 0;
            end
        end
    end

    BASE_UpdateLeaders();   
end

or the error was in both files, or perhaps neither files, and the cause is something else.

Well, I have just not tried anything further with this particular event, but I was wondering if anyone knows what is happening. Does this particular event need a gameplay context lua file rather than a UI context lua file?
 
I also tried registering the event when the load screen close event triggers
Code:
Events.LoadScreenClose( OnLoadScreenClose)

but it doesn't work. It actually causes an error and it jumps past the part where it puts the button on the loading screen. Instead, it abruptly enters the game without centering on the starting settler and doesn't execute the code.

On a side note: I wanted to setup some variables before the player's first turn.
I tried initialize() but that is executed far too early. I don't know if the game is fully setup because a function which should work says the function is nil. (this might be my lua code, for I am a novice at this too)
Initialize() is executed when it loads the InGame UI. Mine seems to always be the last to load. I think this is a good place to setup my variables and anything that doesn't require game data.
Code:
MapPinPopup: Selected 16 columns
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/DedicationPopup
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/DisloyalCityChooser
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/EraProgressPanel
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/EraReviewPopup
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/ExpansionIntro
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/GovernorAssignmentChooser
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/GovernorPanel
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/HistoricMoments
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/WorldCrisisPopup
 InGame: Loading InGame UI - C:/Users/james_5icmd0a/Documents/My Games/Sid Meier's Civilization VI/Mods/Camera/Camera
 TutorialUIRoot: Tutorial: Firaxis in game tutorial prompts.

I was able to run some different code on the PreTurnBegin Event.

Code:
Events.PreTurnBegin.Add( OnPreTurnBegin )

Using this event configured my variables before I moved anything. I think it is sub-optimal for game initialization meant to only run once because I have to check the turn number or it will run every turn. That is good for some things but not for a game initialization. It is usable and a single conditional check is not that big of a deal though. I think that PreTurnBegin is a good place to run something before the turn begins because when the turn begins, the computer may do some updating. So it is a time between the end of one turn and the beginning of the next. It is just guess, but it seems a logical time to get ahead of any new updates the computer will do when the new turn starts.

EDIT:Tried this again the next day, but now PreTurnBegin doesn't seem to trigger before the first turn, so I am confused. Either I was mistaken or there is something I don't know.

I am still very new at this, so if anyone can help with the gaps in my understanding of the architecture, any pointers will be appreciated. I am still working my way through various guides and the forums.
 
Last edited:
I do not think that I made a mistake about not being able to get the data I wanted while executing Initialize(). I wanted to get the player list and set some custom properties up on them. I can do it during the PreTurnBegin. It seems like this is the order of events, from what I can see in the lua console before the main game loop:

--happens right after it hides the main menu
--I assume this is part of the front end
This first one happens before the UI Context are loaded but I don't know if they can happen during a game but this first one probably couldn't trigger anything in my UI script because it isn't loaded yet.
Code:
Events.FinishedGameplayContentConfigure()

--then the Initialization() functions are run in the UI Context scripts

Code:
InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/DedicationPopup
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/DisloyalCityChooser
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/EraProgressPanel
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/EraReviewPopup
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/ExpansionIntro
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/GovernorAssignmentChooser
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/GovernorPanel
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/HistoricMoments
 InGame: Loading InGame UI - ../../../DLC/Expansion2/UI/Additions/WorldCrisisPopup
 InGame: Loading InGame UI - C:/Users/james_5icmd0a/Documents/My Games/Sid Meier's Civilization VI/Mods/Camera/Camera

then
Code:
Events.LoadGameViewStateDone(LoadGameViewStateDone)
Events.LoadScreenClose( OnLoadScreenClose )
Events.PreTurnBegin(OnPreTurnBegin)

those are the events that happen before the game loop starts with PreTurnBegin(). (afaik - but i don't know much) They are all I know about so far, but I know I saw a thread in here where some of the very active members had the main game loop worked out, to some degree at least. I will have to look at it.

If the setup phase and game loop were clearly outlined, people could get up and running with a great deal more speed. I don't mind doing it but I don't have the information pulled together.

I don't know how much game data is available at each of those stages though so perhaps not the entire API is usable yet. For example, I couldn't get a player list in the Initialize() stage because of either poor coding skills or the list hasn't been created yet. Also, subscribing to some of those events and putting even minor code in the callled functions caused some problems for me, so I don't know if they are intended to be used for much, or like I said, I can't code well.
 
Last edited:
Top Bottom