Need some help getting these new expedition rewards to work.

Barathor

Emperor
Joined
May 7, 2011
Messages
1,202
I'm not sure what's wrong with this mod and why it's not working correctly.

This is a simple mod (well, was supposed to be simple) which removes the existing affinity reward types from alien skeletons and progenitor ruins, both on land or sea, and replaces them with new ones.

The existing alien skeleton affinity reward was 12-14 XP in a random affinity and the progenitor ruin was a free level in the affinity of your choice (too much, in my opinion).

The new rewards are more "Rising Tide / Hybrid" style and randomly reward a total of 15 XP points either in a single random affinity, 10 XP and 5 XP in two random affinities, or 5 XP in all three affinities. Each of these different instances is its own PlotBonus script. I manipulate the chances of each with the existing weight assignments each expedition site uses to choose a reward.

Skeletons have a greater chance of spreading out the points and Ruins have a greater chance of really pushing a single affinity.

Skeleton weights: 2) single 4) double 4) triple 20) alien unit
(alien unit is 20 to maintain the existing overall balance of the old weights: 1) affinity 2) alien unit.)

Progenitor: 4) single 4) double 2) triple 10) tech
(existing: 1) free level 1) tech.)

I feel by removing the free level reward, randomizing everything, and having a greater chance of spreading out the points, excessive affinity gain through expeditions will be reduced. Spreading out the points instead of just reducing them for a single affinity works better since the reward still feels worthwhile (points are points) and it doesn't shoot a single affinity up too high that often.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

I've attached the mod below. (EDIT: Removed. That was an early development version containing a few additional bugs.)

I checked the database, and all of my new XML entries are being inserted correctly. Also, everything looks like it's tied together correctly.

My three new Lua files look fine, they're nothing very complicated. (Though, once I get this mod working, I'm curious to see how my new text displays in the game, because I've never modded this kind which contains variables.)

This is the error:
Code:
Runtime Error: Assets\DLC\Expansion1\Gameplay\Lua\PlotBonusSystem.lua:144: attempt to index a nil value
stack traceback:
	Assets\DLC\Expansion1\Gameplay\Lua\PlotBonusSystem.lua:144: in function 'PickExpeditionPlotBonus'
	Assets\DLC\Expansion1\Gameplay\Lua\PlotBonusSystem.lua:81: in function 'OnBuildFinished'

This is that part of the code:
Code:
function PickExpeditionPlotBonus(artifactResourceType, plot, player)
	local bonuses = {};
	local resourceInfo = GameInfo.Resources[artifactResourceType];
	if (resourceInfo ~= nil) then
		for plotBonusFromResourceInfo in GameInfo.PlotBonus_ResourceChanceWeights("ResourceType = \"" .. resourceInfo.Type .. "\"") do
			local plotBonusInfo = GameInfo.PlotBonuses[plotBonusFromResourceInfo.PlotBonusType];
			local plotBonusTable = GetPlotBonusTable(plotBonusInfo.ID);
			local valid = true;
			[COLOR="Red"]if (plotBonusTable.IsValidForPlayerAtPlot ~= nil) then[/COLOR]
				if (not plotBonusTable.IsValidForPlayerAtPlot(player, plot)) then
					valid = false;
				end
			end

...

The red line is the line the error is referring to. I assume it has to do with plotBonusTable being nil, but I can't figure out why it would be.

EDIT: Oh, also... initially I just had the Lua files in the mod with VFS set to "true". When I received the error, I tried adding them as a "InGameUIAddin" to see if it made a difference. Which should it be, if the above error is resolved? I assumed the former method.
 
BAM! Got it to work.

I sat down to look at this again and figured out what was wrong. In PlotBonusSystem.lua, the scripts are loaded from a specific path as chunks in a global table:
(this dofile stuff is all new to me; just did a bit of googling)

Code:
do
	for plotBonusInfo in GameInfo.PlotBonuses() do
		local path = [COLOR="Blue"]"assets\\Gameplay\\Lua\\PlotBonuses\\" .. plotBonusInfo.ScriptName .. ".lua"[/COLOR];

		local plotBonusTable = dofile(path);
		if (plotBonusTable ~= nil) then
			-- Add some additional data to the plot bonus table
			plotBonusTable.Info = plotBonusInfo;

			-- Insert the plot bonus into our global list
			[COLOR="red"]g_PlotBonuses[/COLOR][plotBonusInfo.ID] = plotBonusTable;
		end
	end
end

There's also this:

Code:
function GetPlotBonusTable(plotBonusType)
	return [COLOR="Red"]g_PlotBonuses[/COLOR][plotBonusType];
end

So, I was right that "plotBonusTable" in my first post was a nil because the scripts were never loaded into the table and indexed under their ID numbers.

I just plopped my three Lua files into that path and it worked just fine.

Also, I was happy to discover that my text is displaying correctly in the popups and tooltips. :D

Now, the question is:

How can I get this to work without having to make users paste these three files into their game folders? Can I add an alternate path within PlotBonusSystem.lua which utilizes wildcard searches to look into: "\My Games\Sid Meier's Civilization Beyond Earth\MODS\Expedition Affinity Bonus Mod\Lua\"?

I suppose another way (which is probably simpler) would be to override PlotBonusSystem.lua with my own version which contains the three chunks of code within it so that the global table can properly insert them into it.
 
I would look at vice virtuoso's old modular quests/covert ops mod from the code snippets section. You will need to overwrite PlotBonusSystem.lua to read not only scripts on the specific file path but also all Lua files loaded by mods of a particular type. The game has several such types it already looks for (ingameuiaddin, quest, etc.) but the types are largely arbitrary and you can grab files of any label so long as you know what the label is.

EDIT: Here is how QuestSystem.lua does it:

Code:
		-- Check mods first to see if there's a matching scriptname.
		for questScript in Modding.GetActivatedModEntryPoints("Quest") do
			if(questScript.Name == questInfo.ScriptName) then

				local addinFile = Modding.GetEvaluatedFilePath(questScript.ModID, questScript.Version, questScript.File);
				path = addinFile.EvaluatedPath;
							
				break;
			end		
		end
	
		-- Default to explicit path
		if(path == nil) then
			path = "assets\\DLC\\Expansion1\\Gameplay\\Lua\\Quests\\" .. questInfo.ScriptName .. ".lua";
		end

		file = loadfile(path);

So the key is the method Modding.GetActivatedModEntryPoints(sLabel)
 
Awesome, thank you very much, I greatly appreciate it! I'll give this a try when I get a chance to work on it again.
 
It's finished and works well:

http://steamcommunity.com/sharedfiles/filedetails/?id=561829843

Though, you still need to copy and paste the 12 different plot bonus scripts to your game's folder. The number grew to 12 because, the way it's designed, each file refers to a different plot bonus type with its own unique text. I have 3 different affinity reward combinations and 4 types which reward affinity: Alien Skeletons (Land/Ocean), Progenitor Ruins (Land/Ocean), Kraken Nests, and Progenitor Devices.

I'll try to use the modified PlotBonusSystem file again by Vicevirtuoso, so things don't have to be copied/pasted. The first time I tried it, I may have done something wrong because my game went bonkers and the terrain was all screwed up.
 
I strongly suggest using ViceVirtuoso's Modular Script Loading-Mod to circumvent the "EndUser must copy files"-Problem, otherwise you'll probably get like... 10% the subscribers that your mod could get. ^^

There's an (amateurishly ported, but working) Rising Tide Version of it in my Awesome Pods and Ruins-Mod (PlotBonusSystem.lua) if you want an easy copy-paste. Process is the same as explained on the original Modular Script Loading Page.

/edit: Ah, not sure if you edited in that last sentence or if I was just blind. :p Either way, the original version of the mod is outdated (= Lua Errors that will mess up the terrain when used in Rising Tide), but as I said, there is a working port in my mod.
 
I strongly suggest using ViceVirtuoso's Modular Script Loading-Mod to circumvent the "EndUser must copy files"-Problem, otherwise you'll probably get like... 10% the subscribers that your mod could get. ^^

There's an (amateurishly ported, but working) Rising Tide Version of it in my Awesome Pods and Ruins-Mod (PlotBonusSystem.lua) if you want an easy copy-paste. Process is the same as explained on the original Modular Script Loading Page.

/edit: Ah, not sure if you edited in that last sentence or if I was just blind. :p Either way, the original version of the mod is outdated (= Lua Errors that will mess up the terrain when used in Rising Tide), but as I said, there is a working port in my mod.

D'oh, silly me... Yeah, I was using the vanilla PlotBonusSystem Lua file! Haha...

Yeah, I figured it wouldn't be too popular if users had to copy files over. Honestly, I don't blame them, I wouldn't want to do it either.

Thanks, man, I really appreciate it. Everything is working now without having to copy any files!

I think I just leveled up -- I have a good understanding of this new stuff now. Using examples in some of the other "system" Lua files, I wrote a new script loader for plot bonuses:

Code:
do
	for plotBonusInfo in GameInfo.PlotBonuses() do
		local path, file
		-- Check mods first to see if there's a matching scriptname.
		for plotBonusScript in Modding.GetActivatedModEntryPoints("PlotBonusAddin") do
			if(plotBonusScript.Name == plotBonusInfo.ScriptName) then
				local addinFile = Modding.GetEvaluatedFilePath(plotBonusScript.ModID, plotBonusScript.Version, plotBonusScript.File)
				path = addinFile.EvaluatedPath		
				break
			end		
		end
		
		-- Expansion path.
		if (path == nil) then
			path = "assets\\DLC\\Expansion1\\Gameplay\\Lua\\PlotBonuses\\" .. plotBonusInfo.ScriptName .. ".lua"		
		end
		
		file = loadfile(path)
		
		-- Base path.
		if (file == nil) then
			path = "assets\\Gameplay\\Lua\\PlotBonuses\\" .. plotBonusInfo.ScriptName .. ".lua"
			file = loadfile(path)
		end
		
		local plotBonusTable = file()
		if (plotBonusTable ~= nil) then
			-- Add some additional data to the operation table
			plotBonusTable.Info = plotBonusInfo
			-- Insert the operation into our global list
			g_PlotBonuses[plotBonusInfo.ID] = plotBonusTable
		end
	end
end
 
Top Bottom