1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  3. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  4. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  5. Dismiss Notice
  6. Forum account upgrades are available for ad-free browsing.
    Dismiss Notice

Utilities -- Modular Script Loading

Discussion in 'CivBE - Code Snippets' started by Vicevirtuoso, Oct 31, 2014.

  1. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    Download:
    Steam Workshop
    Mediafire

    Replaces the following base game files:
    • CovertOperationsSystem.lua
    • MinorPowersSystem.lua
    • PersonalitySystem.lua
    • PlotBonusSystem.lua
    • QuestSystem.lua*

      * no longer necessary, and is only included for backwards compatibility with non-updated mods

    While Firaxis allowed for significantly more modularity with systems such as Quests and Covert Operations due to most of their logic being handled through Lua, there is a critical issue with the implementation. By default, the game only checks for scripts in the game's assets folder and does not check for mods to add scripts to these systems. This mod replaces the core files such that mods are able to add new scripts to the above systems without requiring the Lua files to be placed in the game's assets folder.

    How to implement in your mods:
    • In your mod, either add a dependency to this mod, or copy all of this mod's replacement Lua files to your mod and set them to VFS = true.
    • When defining a new item, such as a new Covert Operation, make sure the <ScriptName> tag is set to be your Lua filename without its extension.
    • Ensure your Lua file is set to VFS = true, but you must also add the Lua file through the Content tab, and you must use a Type appropriate to the type of content you are adding. Note that you must manually enter in the Types listed below, as they are not part of the default types in ModBuddy. The Types are:
      • Covert Operations: CovertOperationsAddin
      • Minor Power Scripts: MinorPowersAddin
      • Personality Scripts: PersonalityAddin
      • Plot Bonus Scripts: PlotBonusAddin
     
  2. lilgamefreek

    lilgamefreek Chieftain

    Joined:
    Oct 30, 2014
    Messages:
    229
    I would love for my mod to be as independent and non-conflicting as possible. It's a faction and modifies some functions in the CovertOperationSystem.lua. I'm having a little trouble understanding the intents and limitations of your framework. Is it possible for me to implement a CovertOperationAddin that overloads a function in original CovertOperationSystem? Thanks for any help you can provide. I attempted to add you on steam to ask this question.
     
  3. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    First, you'll want to update the entry for the Covert Operation in the <CovertOperations> table so that the <ScriptName> tag is the filename of your new script minus extension. For example, let's say you're replacing the script for the Dirty Bomb operation with a script you've named MyScript_DirtyBomb.lua:

    Code:
    <GameInfo>
      <CovertOperations>
        <Update>
          <Where Type="COVERT_OPERATION_DIRTY_BOMB"/>
          <Set ScriptName="MyScript_DirtyBomb"/>
        </Update>
      <CovertOperations>
    </Update>

    Then, in your mod properties, in the Content tab, you would insert your MyScript_DirtyBomb.lua file as a CovertOperationsAddin type (manually enter this into the type field). Additionally, set MyScript_DirtyBomb.lua to be VFS = true.
     
  4. lilgamefreek

    lilgamefreek Chieftain

    Joined:
    Oct 30, 2014
    Messages:
    229
    So from what I can tell, this is for changes and additions to individual covertop.luas, but not for changes to CovertOperationsSystem.lua itself?
     
  5. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    Yes, it's only for new scripts to be loaded by CovertOperationsSystem and the other mentioned files. The mod itself replaces CovertOperationsSystem.lua, but the only change made to it is the search for ScriptNames in loaded mods prior to looking in the game's Assets folder.
     
  6. lilgamefreek

    lilgamefreek Chieftain

    Joined:
    Oct 30, 2014
    Messages:
    229
    Got it. Thanks for the info and the hard work!
     
  7. Leugi

    Leugi Supreme Libertador

    Joined:
    Jan 25, 2013
    Messages:
    1,673
    Location:
    Bolivia
    There has to be a way of using the Personality scripts... I wonder if they could have been used to make an AI insta war a player when it kills an alien or something? Scripted personalities would add much to the leaders.
     
  8. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    It really seems like it was an idea they planned on implementing, but scrapped due to time constraints and left the skeleton code in.

    It's far past time I went back to working on my Civ 5 mods. Otherwise, I'd play around with it myself.
     
  9. Lord Shadow

    Lord Shadow General

    Joined:
    Oct 14, 2005
    Messages:
    1,817
    Location:
    Buenos Aires
    I've been trying to use this utility to have the game recognize and implement my slightly different version of KillSiegeWormQuest.lua, for Alien Strains, but so far to no avail. I've grabbed only QuestSystem.lua and PlotBonusSystem.lua from this mod, and had to modify the latter a bit so that the death of any type of Siege Worm could generate an Alien Skeleton. I haven't really tested that, but the main problem for me is still the quest, which doesn't trigger and in the best of cases just somehow has QuestSystem.lua produce a lot of errors.

    I have QuestSystem.lua plugged in via VFS = true, as indicated, and KillSiegeWormQuest_AST.lua via VFS = True and QuestAddin. If I make a separate entry for the quest in <Quests>, it gets me a lot of errors on my Lua.log. If I instead Update the original quest entry to point to my own Lua, then the game just doesn't run the script at all.
     
  10. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    I've heard that scripts won't load unless they're in the root directory of your mod (which is something I'm going to be looking into). Is your Lua script in the root of your mod folder?
     
  11. Lord Shadow

    Lord Shadow General

    Joined:
    Oct 14, 2005
    Messages:
    1,817
    Location:
    Buenos Aires
    It was in a Lua subfolder, but I moved it to root and the whole thing worked. Well, partially.

    The quest activates whenever one of the three Siege Worm strains is spotted, as expected. However, I have to make the objective look something like this:
    Code:
    local objective = AddObjective(quest, "QUEST_OBJECTIVE_KILL_UNIT_TYPE", WORM_UNIT_TYPE[1] or WORM_UNIT_TYPE[2] or WORM_UNIT_TYPE[3], 1);
    ...And the script, I theorize, seems to relay only a single WORM_UNIT_TYPE (the first) to KillUnitTypeQuestObjective.lua, which only seems to contemplate a single, fixed UnitType for its calculations, instead of one out of n possible. Therefore, only killing a particular Siege Worm type completes the quest. The "any of three" issue has been my bane as far as this quest is concerned, and the reason why I've been struggling to make all these modifications to the vanilla version.

    I realize this post goes off-topic, since the utility's now working correctly and the aforementioned problem is unrelated. So we can continue this via PM or on Steam, if you'd like. Any help would be appreciated.
     
  12. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    Most likely, you'd need to edit KillUnitTypeQuestObjective.lua to allow for it to be passed multiple values. That or have three separate quests.
     
  13. Lord Shadow

    Lord Shadow General

    Joined:
    Oct 14, 2005
    Messages:
    1,817
    Location:
    Buenos Aires
    Three separate yet almost identical quests would be messy. I'll look into tweaking KillUnitTypeQuestObjective.lua.

    Thank you for your life-saving utility. :)
     
  14. Ryoga

    Ryoga Chieftain

    Joined:
    Oct 12, 2010
    Messages:
    993
    Basically the problem is that the "Addin" content system uploads the files including in its data their paths.
    When your script compares that data with the script names in the Database they do not match (because one is the name of the file without the extension and the other is the name of a file without extension and its path in the mod folder) so the check fails.

    This is however an issue that can be easily overcome without the need to put everything in the main directory.

    All you need to do is to include the same path in the XML that redirects to the script.
    For example:

    Code:
    	<QuestObjectives>
    		<Update>
    			<Where Type="QUEST_OBJECTIVE_CLEAR_FOREST_FROM_PLOTS" />
    			<Set ScriptName="[B]Quests/QuestObjectives/ClearForestFromPlotsQuestObjective_fix[/B]" />
    		</Update>
    	</QuestObjectives>
    In other words the same thing that you find in the modinfo file

    Code:
        <EntryPoint type="QuestObjectiveAddin" file="[B]Quests/QuestObjectives/ClearForestFromPlotsQuestObjective_fix[/B].lua">
    minus the extension.

    As long as those two match, your script works fine.
     
  15. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    I'd like to avoid that if at all possible, to make it easier and more flexible for the mod authors.

    Here's where the major problem comes in. For some reason, Path isn't defined in any of these scripts. Path APIs work fine in other contexts, but not any of the ones replaced in this mod. It's preventing me from using the critical GetFileNameWithoutExtension function I'd need to make this easier.

    It's a really clunky way of going about it, but I suppose I could have a secondary script as an InGameUIAddin for the sole purpose of adding GetFileNameWithoutExtension as a LuaEvent.
     
  16. Ryoga

    Ryoga Chieftain

    Joined:
    Oct 12, 2010
    Messages:
    993
    Well one way that I thought of solving the problem, before finding the simple solution above, was to modify your code so that it splits the path+file into tokens and take only the last one.

    Example:

    Code:
    local file;
    local line = "Quests/QuestObjectives/ClearForestFromPlotsQuestObjective_fix.lua"; 
    for token in string.gmatch(line, "[^/]+") do 
    file = token;
    end
    At the end of the cycle "file" will be equal to "ClearForestFromPlotsQuestObjective_fix.lua"
     
  17. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    I ended up doing it this way since I didn't take a look at the thread while I was working on it:

    Code:
    function VVGetScriptName(arg)
    	--First get rid of the .lua file extension
    	local str = string.sub(arg, 1, string.find(arg, ".lua") - 1)
    	--Then get rid of the path by reversing the string and deleting everything past the slash
    	str = string.reverse(str)
    	str = string.sub(str, 1, string.find(str, "/") - 1)
    	--Re-reverse it and we should have our filename minus path and extension
    	str = string.reverse(str)
    	return str
    end
    
    Appreciate the suggestion, though. I'll be publishing an update which does this plus adds more verbose logging.



    EDIT: I didn't take into consideration that it would break files which already specify an exact path, and would also remove the ability of the user to specify a path if desired. Perhaps I'll just check for the ScriptName to be contained in the entire Path.


    EDIT 2: Update posted.
     
  18. Ryoga

    Ryoga Chieftain

    Joined:
    Oct 12, 2010
    Messages:
    993
    All right good job!
    I've been trying your updated version while testing another mod I'm currently developing. Everything is working fine.
     
  19. Ryoga

    Ryoga Chieftain

    Joined:
    Oct 12, 2010
    Messages:
    993
    I've noticed this error happening several times:

    Code:
     Runtime Error: bad argument #1 to 'func' (Argument 1 for Event.Remove must NOT be nil.)
    stack traceback:
    	[C]: in function 'func'
    	assets\Gameplay\Lua\Quests\HostileTakeoverStationQuest.lua:145: in function 'QuestScript.OnUnregisterListeners'
    	C:\Users\Mir\Documents\My Games\Sid Meier's Civilization Beyond Earth\MODS\Utilities -- Modular Script Loading (v 1)\QuestSystem.lua:534: in function 'OnQuestComplete'
    	[C]: in function '(anonymous)'
    It systematically occurs almost everytime this line is involved:

    Code:
    questScript.OnUnregisterListeners(wrapper);
    This occurs for various quests in various situations that call the OnUnregesterListeners function.
    I am using a modified quest, but so far firetuner only shows me errors about quests that have been untouched.

    It seems that "wrapper" is nil when it's supposed to contain data.

    I'm not quite sure if it is an error due to your script or from the default file.
     
  20. Vicevirtuoso

    Vicevirtuoso The Modetta Man

    Joined:
    May 14, 2013
    Messages:
    775
    Location:
    The Wreckage, Brother
    I'm not sure how my mod would affect that function for the default quests. Would have to see if the same error happens without my mod loaded.
     

Share This Page

Ebates: Get Paid to Shop