Lua Objects

are GameEvents valid anymore in civ6?

everything I've seen in the Firaxis lua is Events or LuaEvents.

The only place I even find GameEvents is in C:\Program Files (x86)\Steam\SteamApps\common\Sid Meier's Civilization VI\Base\Assets\UI\Tuner\AI_Diplomacy.lua and it's questionable whether the file is even used given these entire contents:
Code:
GameEvents.DiploSurpriseDeclareWar.Add(function( mainPlayer, opponentPlayer )
--	local player = Players[mainPlayer];
--	if ( player ~= nil ) then
--		Print(player);
--		local ai = player:GetAi_Military();
--		Print(ai);
--		ai:PrepareForWarWith(opponentPlayer);
--		if ( ai:HasOperationAgainst( opponentPlayer, true ) ) then
--			return true;
--		end
--	end
	return false;
end );
 
Interesting. So the only predefined LuaEvents are those that you can already find Lua files, there are none provided by the core engine.
They should've used more of them, to make it easier to hook into the code, instead of having to replace whole interface files.

Just to make sure you're aware, the events provided by the core engine are off Events, not LuaEvents. I posted a link to all of them at the time at Lua Objects, though I haven't checked to see if the Winter patch added more.

But yeah, in general, we need more events, especially ones we can return values to for changing the cost of items, etc., dynamically in Lua functions.
 
Am sorry if I have missed it but does any one happen to know of a way to pass our own made variables from the UI context to the Gamescript context (or perhaps a hacky way)? I havn't found a way yet, we can't even set things like faith and gold in the UI to act as temporary variables but that seems like a bad way of doing it anyway.
 
With civ5 we used existing tables (like MapModData) to share variables, tables or functions between contexts, in Civ6 MapModData is only visible in a script context, some shared tables are read only, but it seems that ExposedMembers is both shared and not read-only

In a script context :
>ExposedMembers.myValue = 3

In a UI context:
>ExposedMembers.myValue
3

So for example this should still work (by putting it at the top of both Lua files) to initialize and share a table between a gameplay script and an UI context:
Code:
ExposedMembers.myTable = ExposedMembers.myTable or {}

No idea how hacky (or safe) this is, IIRC some values in mods were broken when you tried to reload a game in an active session without quitting to the main menu first.
 
Thanks, I can confirm that it works but only when sending variables from the script to the UI, not the UI to the script (any ideas for this?). The table worked the same way too.

I'll be using this and I'll do some tests eventually on the load game to see what the case is and post on here if someone else doesn't before. If I can pass UI variables to the script then I could technically store them in invisible UI elements (at least for the mod im working on) which will be fine on save/loads if ExposedMembers has problems.
 
@Ewok-Bacon-Bits and @Gedemon

If you're just trying to share globals between the scripting and UI contexts, just using LuaEvents to return a global table as a field in a passed in table works for me:

Test2.Lua in <GameplayScripts>:
Code:
local m_MyGlobals : table = {};

function GetMyGlobals( MyGlobalsRef : table )
    MyGlobalsRef.MyGlobals = m_MyGlobals;
end

function OnPlayerTurnEnd()
    m_MyGlobals.TestValue = m_MyGlobals.TestValue + 100;
    print(m_MyGlobals.TestValue);
end;

LuaEvents.GetMyGlobals.Add(GetMyGlobals);
Events.LocalPlayerTurnEnd.Add(OnPlayerTurnEnd);
m_MyGlobals.TestValue = 0;

DiplomacyActionView.lua at line 1642 in <Imports>:
Code:
function SelectPlayer(playerID, mode, refresh, allowDeadPlayer)
--Begin Test2
        local MyGlobalsRef : table = {};
        LuaEvents.GetMyGlobals(MyGlobalsRef);
        MyGlobalsRef.MyGlobals.TestValue = MyGlobalsRef.MyGlobals.TestValue + 1;
        print(MyGlobalsRef.MyGlobals.TestValue);
--EndTest2
    if (mode == nil) then
...

FiraxisLiveTuner output:
Code:
DiplomacyActionView: 1
DiplomacyActionView: 2
DiplomacyActionView: 3
Test2: 103
DiplomacyActionView: 104
DiplomacyActionView: 105
Test2: 205

You could even use it to expose script context only game globals to the UI, I think.

Or are you trying to save the values in a table that would get saved with the game?
 
Last edited:
^ ya that works thanks, it allows me to pass variables both ways.

Saved variables would be nice to know though I don't need it immediately but it sounds like ExposedMembers works for that but I never tested it. So I will probably end up using both to work with eachother.
 
I've not tried this yet, but loading/saving custom values is something else.
 
About saving, for something simple (long integer or string), you may be able to use SetValue (not available in script context) and GetValue in the configurations tables.

for example

>GameConfiguration.SetValue ("myValue", 25)

save/load game

>GameConfiguration.GetValue ("myValue")
25

Note that you can't use this to pass a value between contexts, GameConfiguration.GetValue ("myValue") return the same value in all context after reloading a game, but if you set another value from a context, GameConfiguration.GetValue ("myValue") will still see the previous value in other contexts until you save and reload.

There are also serialize.persist(table, value) and serialize.unpersist(?) functions available, but I have no idea how to use them.


Edit: after some quick tests with a small table serialization utility for Lua it seems that we can use GameConfiguration.SetValue / GameConfiguration.GetValue to save tables, it will need some more tests to check the size and performance
 
Last edited:
This may not be the right place to ask, but is there a lua function to add a Modifier to a player (or to a city/unit/etc?) I've searched through every tab of the Excel spreadsheet and looked at the lua code in all the Firaxis scenarios and can't seem to find it. Maybe it's very obvious and I'm just missing it. Can anyone point me to it?
 
This may not be the right place to ask, but is there a lua function to add a Modifier to a player (or to a city/unit/etc?) I've searched through every tab of the Excel spreadsheet and looked at the lua code in all the Firaxis scenarios and can't seem to find it. Maybe it's very obvious and I'm just missing it. Can anyone point me to it?
Not that I'm aware of.

Lua and the Modifiers system are in practical terms "competing systems" attempting to accomplish the same sort of tasks.
 
Not that I'm aware of.

Lua and the Modifiers system are in practical terms "competing systems" attempting to accomplish the same sort of tasks.


That's really bad news if it's true. :( Modifiers are such a central part of the game and a "clean" way to track effects. There's also a whole panel in FireTuner dedicated to tracking them. I hope there's a function in there we just haven't found yet.
 
AFAIK there are just "Get" function like GameEffects.GetRequirementDefinition(requirementID)

And I have no idea why there is no "Set", as it force us to use alternative tables and coding to set ours.


Code:
            GameEffects
                GetRequirementDefinition
                GetRequirementReferenceCount
                GetRequirementSetState
                GetObjectName
                GetObjectsPlayerId
                GetRequirementCount
                GetModifierDefinition
                GetModifierTrackedObjectCount
                GetModifierText
                GetModifiers
                GetModifierTextKey
                GetRequirements
                GetRequirementSetContext
                GetModifierTrackedObjects
                GetModifierSubjects
                GetModifierArgumentString
                GetObjectType
                GetModifierTrackedOjectRequirementSet
                GetRequirementState
                GetRequirementSetInnerRequirements
                GetRequirementSetSubject
                GetRequirementSetReferenceCount
                GetObjectReferenceCount
                GetRequirementSets
                GetRequirementContext
                GetRequirementText
                GetModifierActive
                GetRequirementSetDefinition
                GetRequirementSetCount
                GetRequirementTextKey
                GetModifierSubjectCount
                GetModifierReferenceCount
                GetRequirementInnerRequirements
                GetModifierOwnerRequirementSet
                GetObjectString
                GetRequirementSubject
                GetModifierOwner
                GetModifierCount
 
Thanks Gedemon. At least there are functions for determining if a modifier exists.

We know the DLL must be able to apply modifiers on some level, because a Modifier can be applied in-game when a player constructs a Building. It's a shame that function isn't shared with Lua. I understand why they won't let us build an entirely new Modifier from scratch, but it does feel like if one already exists in the database, applying it should be as easy as a quick Set function

FWIW the thing I'm trying to do is add options to the Advanced Options screen. I've got the drop-down for the Option created. In SQL, I have the Modifier set up to add 200% Culture (this is a long-term feature of the mod I am only just now trying to make an option due to many players asking for it). SQL code looks like this:

Code:
INSERT INTO Modifiers
    (ModifierID,             ModifierType,                     RunOnce,     Permanent,     OwnerRequirementSetId,     SubjectRequirementSetId)
VALUES    ('QUO_CULTURE_BORDER_DISCOUNT', 'MODIFIER_ALL_CITIES_CULTURE_BORDER_EXPANSION', 0,         0,         NULL,            NULL) ;


INSERT INTO ModifierArguments
    (ModifierID,            Name,        Type,             Value,    Extra)
VALUES    ('QUO_CULTURE_BORDER_DISCOUNT', 'Amount',     'ARGTYPE_IDENTITY',     '200',    NULL) ;


INSERT INTO TraitModifiers
    (TraitType,        ModifierID)
VALUES    ('TRAIT_LEADER_MAJOR_CIV',     'QUO_CULTURE_BORDER_DISCOUNT') ;


What I need to be able to do is remove that INSERT INTO TraitModifiers and apply QUO_CULTURE_BORDER_DISCOUNT to each player at run-time using Lua.

A second option that would actually be cleaner, but as far as I have seen does not exist, would be to just code the .modinfo not to run the portion of the SQL that creates the borders effect if the right speed isn't selected. That works for Rulesets, but I haven't seen any examples of it working with other settings.


20170217212852_1.jpg
 
If I were to provide lua hooks into the modifier system, I'd design extensibility into GameEffects. Custom requirements, collections, adjustments, etc. are far more flexible (and, through FireTuner, debuggable) than hard-coding the same in lua.
 
The thing that's kind of frustrating is that I could probably make this work by just hooking the Modifier onto a Technology or Civic and just awarding that tech or civic to the player, which would apply the modifier... but then the tech or civic would show up on the tech trees. There isn't any way to make a tech or civic unlearnable. This would be easily modded in if we had DLL access and is probably one of the more ideal ways to handle this.

A better way of course would be if we could just assign Modifiers directly. The more I think about it, the more I think the reason we can't is Modifiers don't get turned into live objects like Techs/Civics/Buildings do, so Lua can't access them.

I guess if I'm forced to I can do the old "dummy building" trick, but, blah. ;p
 
Changing my thinking on this a little. Maybe what I could do is set the Modifier to appear on all Players, but have a SubjectRequirementSetId that only turns it under certain conditions. I have very little experience with Lua. Can anyone think of a condition that could easily be applied that would flip a Requirement from Unmet to Met with minimal disruption to the game?

One that stands out to me as a possibility is REQUIREMENT_PLAYER_HAS_COMPLETED_PROJECT. Can you force project completion with Lua?

Of course if Projects can be forced with Lua, I could also tie the modifier directly to the Project. Since Projects, unlike Buildings, disappear after being completed, there would be no issue of them clogging up the city screen.
 
Top Bottom