Fix for tech tree rendering issue :)

Alzara

Emperor
Joined
Jan 2, 2008
Messages
1,214
Location
Florida
Hi all,

I have fixed the Lua code that renders the tech tree incorrectly when two or more techs with different X coordinates all rely on the same prerequisite tech.

This was brought to my attention when I posted my concerns in this thread:
http://forums.civfanatics.com/showthread.php?t=420270

I modified the following file directly: Assets -> UI -> InGame -> TechTree -> TechTree.lua

I haven't thought about how to include it in a mod for now (am quite tired and need to post my magic design tonight for my own mod before I sleep lol).

The fix will work fine though if directly applied to this file (feel free to report any bugs to me ofc :))

The fix is as follows:

Remove the block of code shown below:
Spoiler Old Code To Remove :

-- add the pipes
local techPipes = {};
for row in GameInfo.Technologies() do
techPipes[row.Type] =
{
leftConnectionUp = false;
leftConnectionDown = false;
leftConnectionCenter = false;
leftConnectionType = 0;
rightConnectionUp = false;
rightConnectionDown = false;
rightConnectionCenter = false;
rightConnectionType = 0;
xOffset = 0;
techType = row.Type;
};
end

local cnxCenter = 1
local cnxUp = 2
local cnxDown = 4

-- Figure out which left and right adapters we need
for row in GameInfo.Technology_PrereqTechs() do
local prereq = GameInfo.Technologies[row.PrereqTech];
local tech = GameInfo.Technologies[row.TechType];
if tech and prereq then
if tech.GridY < prereq.GridY then
techPipes[tech.Type].leftConnectionDown = true;
techPipes[prereq.Type].rightConnectionUp = true;
elseif tech.GridY > prereq.GridY then
techPipes[tech.Type].leftConnectionUp = true;
techPipes[prereq.Type].rightConnectionDown = true;
else -- tech.GridY == prereq.GridY
techPipes[tech.Type].leftConnectionCenter = true;
techPipes[prereq.Type].rightConnectionCenter = true;
end

local xOffset = (tech.GridX - prereq.GridX) - 1;
if xOffset > techPipes[prereq.Type].xOffset then
techPipes[prereq.Type].xOffset = xOffset;
end
end
end


and replace it with the following code
Spoiler New Code :

-- add the pipes
local techPipes = {};
local i = 0;

for row in GameInfo.Technology_PrereqTechs() do
local tech = GameInfo.Technologies[row.TechType];
local prereq = GameInfo.Technologies[row.PrereqTech];

if tech and prereq then
local bTechLeftConnUp = false;
local bTechLeftConnDown = false;
local bTechLeftConnCentre = false;
local bPrereqRightConnUp = false;
local bPrereqRightConnDown = false;
local bPrereqRightConnCentre = false;
local nPrereqXOffset = (tech.GridX - prereq.GridX) - 1;
local nTechXOffset = -nPrereqXOffset;

if tech.GridY < prereq.GridY then
bTechLeftConnDown = true;
bPrereqRightConnUp = true;
elseif tech.GridY > prereq.GridY then
bTechLeftConnUp = true;
bPrereqRightConnDown = true;
else -- tech.GridY == prereq.GridY
bTechLeftConnCentre = true;
bPrereqRightConnCentre = true;
end

techPipes =
{
leftConnectionUp = bTechLeftConnUp;
leftConnectionDown = bTechLeftConnDown;
leftConnectionCenter = bTechLeftConnCentre;
leftConnectionType = 0;
rightConnectionUp = false;
rightConnectionDown = false;
rightConnectionCenter = false;
rightConnectionType = 0;
xOffset = nTechXOffset;
techType = tech.Type;
};

i = i + 1;

techPipes =
{
leftConnectionUp = false;
leftConnectionDown = false;
leftConnectionCenter = false;
leftConnectionType = 0;
rightConnectionUp = bPrereqRightConnUp;
rightConnectionDown = bPrereqRightConnDown;
rightConnectionCenter = bPrereqRightConnCentre;
rightConnectionType = 0;
xOffset = nPrereqXOffset;
techType = prereq.Type;
};

i = i + 1;
end
end

local cnxCenter = 1
local cnxUp = 2
local cnxDown = 4


The new code is logically less efficient (as it draws each pipe individually), but there appears to be no significant effect on performance :)

Attached is a picture showing the fix in action (note that both Faith and Calendar both require Writing and have different X coordinates. The branches are now drawn correctly) :)

Hope you all enjoy! :D

Let me know if there are any problems :)

Al
 

Attachments

  • TechTreeLuaFix.jpg
    TechTreeLuaFix.jpg
    224.2 KB · Views: 352
I haven't thought about how to include it in a mod for now

Edits of existing Lua or non-gamedata XML files are handled very simply: you create a file with the exact same name as the original (in this case, TechTree.lua) inside your mod, and set "Import into VFS" flag (in the Properties box for that file) to True. The game will then replace the file named TechTree.lua in its original archive with your altered variant.

There's no way to do partial edits in this sort of system. You MUST replace the entire file at once, and that means that your mod will be incompatible with any other mod that alters TechTree.lua (unless their change was identical to yours, of course). This issue is most common with AssignStartingPlots.lua, which many mods edit (since it handles all resource generation in the game), but many UI Lua and XML files are altered by various mods. In my own mod, for instance, I had to edit TechTree.lua because it hard-codes the number of eras to 7 in one section (a FOR loop that goes 0, 6, 1), and my mod added three more eras to the game. So, as an example, any mod you made that fixes the bug in TechTree.lua would conflict with my own mod.

It also means that every time the game goes through a major patch, you need to make sure that any changes made to the original game's files are copied over to your mod's variants. (Again, very common with AssignStartingPlots.) If they fix this bug then obviously your patch wouldn't be needed, but many other things get tweaked during patches, and you'll have to manually ensure that those changes get included in any altered versions.

If you try editing the game's original version of TechTree.lua, then your changes will be overwritten the next time the game patches itself. It's also just a bad practice in general.
 
So, as an example, any mod you made that fixes the bug in TechTree.lua would conflict with my own mod.

Well that's why I supplied the code. The section that I have changed doesn't deal with the section that you have changed. So you can copy and paste my code to the top of your TechTree.lua mod if you so desire and it should work fine :)

If you try editing the game's original version of TechTree.lua, then your changes will be overwritten the next time the game patches itself. It's also just a bad practice in general.

Well that much is obvious :p

I just hadn't bothered trying to put it into a mod yet as I'm tired and and uploading the magic design for my mod now :)

At least I've fixed it and supplied the code :p

Al
 
Nice job Al! im sure this will help a lot of people out :)
 
Nice job Al! im sure this will help a lot of people out :)

Hehe I hope so too :)

I will make a small enhancement to the code soon. I think I can remove one small element that I suspect is irrelevant :)

Al
 
This fix still works for patch 332 (as the TechTree.lua file changed very little in substance)

There is another error in TechTree.lua in that it assumes that the max Y offset between dependant techs is 4. You can only create a Y offset of 5 by placing a tech in position (1,0) (ie above Pottery) but if you do this, you will need to add

Code:
-- Existing code starts
			if tech.GridY - prereq.GridY == 4 or tech.GridY - prereq.GridY == -4 then
				local vConnection = g_PipeManager:GetInstance();
				vConnection.TechPipeIcon:SetOffsetVal((tech.GridX-1)*blockSpacingX + blockSizeX + 96, ((tech.GridY-5)*blockSpacingY) - (((tech.GridY-prereq.GridY) * blockSpacingY) / 2) + extraYOffset);
				vConnection.TechPipeIcon:SetTexture(vTexture);
				local size = { x = 32; y = blockSpacingY * 3 + 8; };
				vConnection.TechPipeIcon:SetSize(size);
			end
-- Existing code ends
	
-- New code starts
			if tech.GridY - prereq.GridY == 5 or tech.GridY - prereq.GridY == -5 then
				local vConnection = g_PipeManager:GetInstance();
				vConnection.TechPipeIcon:SetOffsetVal((tech.GridX-1)*blockSpacingX + blockSizeX + 96, ((tech.GridY-5)*blockSpacingY) - (((tech.GridY-prereq.GridY) * blockSpacingY) / 2) + extraYOffset);
				vConnection.TechPipeIcon:SetTexture(vTexture);
				local size = { x = 32; y = blockSpacingY * 4 + 8; };
				vConnection.TechPipeIcon:SetSize(size);
			end
-- New code ends

(There are "better" ways of writing that code, but the code given matches the current "pattern")
 
Top Bottom