Lua and the Tech Web

Starrynite120

Prince
Joined
Jul 15, 2015
Messages
472
I'm new to Lua, and I understand the logic behind it and can understand a program when looking at it, but something I'm having trouble with is knowing what terms/commands to use, and how to refer to the correct thing.

Basically what I'm asking is how do I command the computer to count something (I'm guessing by a loop?), how do I refer to researched techs as opposed to unresearched techs (I'm trying to count how many techs you have researched), and how would I refer to what tier of the gird a tech is on? I understand in XML how to set a tech on a specific grid, but I'm having trouble figuring out how to get an lua code to understand what tier of the tech web a tech is on. Any help is greatly appreciated!
 
You'll want to use GameEvents.PlayerCanResearch(playerID, techID) to add extra restrictions to when a player can research a given tech. If you return false it blocks the tech. If you return true than the player can research the tech (assuming no other functions are involved).

The following untested code can give you an example of where to start. I'll try to add more information over the next couple of days.
Code:
function EraTechRequirement(playerID, techID)
  local tech = GameInfo.Technologies[techID];

  if(tech.GridRadius == 0 || tech.GridRadius == 1) then
    return true;
  elseif(tech.GridRadius == 2) then
    -- do stuff, return true or false
  elseif(tech.GridRadius == 3) then
    -- do stuff, return true or false
  elseif(tech.GridRadius == 4) then
    -- do stuff, return true or false
  endif
end
GameEvents.PlayerCanResearch.Add(EraTechRequirement);
 
Wow, thanks so much! It's been driving me crazy trying to figure this out, I'll have to play around with this I'm really excited at the prospect of getting this working. really, thanks so much!
 
Also, if it helps for the example you're giving me, I can give you how many number techs I want for the era requirement. I know off the top of my head that to research gridradius 2 techs I want 4 gridradius 1 techs.
 
Do you think this would work? My real question is on the PlayerHasResearched function, I don't know if that is correct.

Code:
function EraTechRequirement(playerID, techID)
	local Tech1 = GameInfo.Technologies["TECH_PIONEERING"].ID;
	local Tech2 = GameInfo.Technologies["TECH_PLANETARY_SURVEY"].ID;
	local Tech3 = GameInfo.Technologies["TECH_ENGINEERING"].ID;
	local Tech4 = GameInfo.Technologies["TECH_PHYSICS"].ID;
	local Tech5 = GameInfo.Technologies["TECH_BIOLOGY"].ID;
	local Tech6 = GameInfo.Technologies["TECH_ECOLOGY"].ID;
	local Tech7 = GameInfo.Technologies["TECH_CHEMISTRY"].ID;
	local Tech8 = GameInfo.Technologies["TECH_GENETICS"].ID;
--these are all the tier 1 techs
	local requirement = 0

	if techID = Tech1 and PlayerHasResearched = true then
		requirement = requirement + 1
	end
	--do this for every tech, I didn't write it out cause it would take awhile and I don't feel like it if its not going to work

	if tech.GridRadius == 2 and requirement > 3 then
		return true
	elseif tech.GridRadius == 2 and requirement < 4 then
		return false
	end
end
GameEvents.PlayerCanResearch.Add(EraTechRequirement);
[CODE]
 
GameEvents.PlayerCanResearch doesn't work the way we'd like it to work, as discussed in this thread:
http://forums.civfanatics.com/showthread.php?t=476787

All it really does is allowing the player to end the turn without selecting a technology to research, but they can still do so manually.

whoward69 did something similar to what you're trying to do in Civ 5:
http://www.picknmixmods.com/mods/4bac39f7-8315-46b2-a03b-945907fa409a/mod.html

...but it's a lot more complex and doesn't do what you want to do - he has basically creating tech-prerequs for each and every technology in the first era and then just hides most of them by adding a new modifier in the ui-file. Which means it can't even be used in any other scenario than the "research EVERY tech of the previous era"-scenario.

As far as I can tell the techtree.lua in the UI-Folder only handles the UI-Elements of the tech tree (as one would expect), the rest of the techweb-logic seems to be handled in the core files, so I don't think there is any way to do what you want to do.
 
Well that's unfortunate to hear. I'd like to read the thread you mentioned, but the link you provided only leads back to this discussion.
 
So I thought of a workaround. What if I just set research costs absurdly high, like 99999, until you've researched a certain amount of previous tier techs? This would, though sloppier, effectively do the same thing.

Though on second thought this could create a serious problem with the AI. If this were something I could do, I could just restrict it to the human player, as I'm just trying to prevent beelining, which the AI doesn't seem to do anyway.
 
I guess I would like to ask, how would I limit an lua function to only the human player? I'm assuming this would be done by setting playerID as only the human player, I just don't know what the exact words would be for the human player. I'll be using this for more than what I mentioned above, I just figured I'd ask now
 
I guess I would like to ask, how would I limit an lua function to only the human player? I'm assuming this would be done by setting playerID as only the human player, I just don't know what the exact words would be for the human player. I'll be using this for more than what I mentioned above, I just figured I'd ask now

Two ways you can do this, one is to use the IsHuman function:
Code:
if Player:IsHuman() then
	-- do stuff
end

And the other is to check playerID, since the human player (in a singleplayer game at least) is always player 0:
Code:
if playerID == 0 then
	-- do stuff
end

The latter can also be useful for limiting effects to the aliens, since aliens are always playerID 62.
 
Mind if I ask another question? Figured I'd just post it here instead of making another new thread (I've already made enough of those haha). I'm trying to disallow the construction of a building based off of, in this example, how many virtues you have. I used the Old Earth Relic as a test case here. the idea is, for only human players, if you have less than 3 virtues you cannot build the Old Earth Relic (this isn't what I'm actually doing, just a test to try and get the code to work). This is what I wrote, but it doesn't work.

Code:
function CultureVictory (playerID, buildingID)
	local virtue = 0
	local wonderInfo = GameInfo.Buildings["BUILDING_RELIC"]
	local wonderID = wonderInfo.ID

	if playerID = 0 then
		virtue = player:GetNumPolicies()
		buildingID = wonderID
	end

	if virtue < 3 then
		return false
	else
		return true
	end
GameEvents.PlayerCanConstruct.Add(CultureVictory)[CODE]

So what's wrong with it?
 
So I've thought of a possible workaround to this problem. If a tech has no prerequisite, so no line leading to it from another tech, the game does not allow it to be researched. So, via lua, I could remove all connections leading from tier one to tier 2 until you have researched enough techs.

I can see this could be a pain to script, as you'd probably have to do each tech individually, but I'd be alright with that. What I'd like to ask is how I can assign connections via lua, if it is possible at all (which it should be, I just don't know).
 
I have a related question. I want to incorporate a cost penalty to new technologies, proportional to the weighted number of technologies known (i.e. like how virtues work.) Motivation being - I think focusing in a single affinity should be more-encouraged than it is.

Ideally, I'd want the algebra to work out so that you pay the same total research whichever order you do the techs (at least approximately), so the function :GetNumTechsKnown() wouldn't be quite what I wanted, but the deeper issue is - how do I change the lua script that runs when a new tech is researched?

I've got tutorials and examples that explain various parts of it (so if I wanted to write a lua script that calculated something based on how many techs you knew on the first turn, I could do that), but I'm not sure how in principle you figure something like this out. It's not just a function of what I actually write in the .lua code, I'd also need to append something in ModBuddy, a trigger yeah, so that it actually runs?

Or, if I'm just replacing the code for some existing lua function to find tech costs, could I simply redefine the function by reusing the name (which I still have to hunt down?)
 
You may be able to fake increasing the tech costs by:

1) Doubling the cost of all techs
2) Starting every player with a PlayerPerk that reduces tech costs by 50% (cancelling out the increase)
3) Use Lua to over the course of the game swap the PlayerPerk with another PlayerPerk that provides only a 40% reduction to mimic the costs going up

There is a Lua event for when a player researches a technology that you can use to detect when the player has acquired enough techs. I believe it is GameEvents.TeamTechResearched(TeamID team, TechType tech, int change).
 
Back
Top Bottom