Half-tradeable tech.

Yakk

Cheftan
Joined
Mar 6, 2006
Messages
1,288
This is just a plan as yet. I have it partially written currently.

The idea is a python script that takes a tech tree and breaks each tech into a tradeable and non-tradeable half. The tradeable half will be the THEORY of or the IDEA of the technology: the non-tradeable half is integrating it into your society effectively.

The tradeable half gives no in-game benefit other than being the one and only prerequisite for the non-tradeable half.

The impact on games is that everyone has to put in half of the required effort to advance in technology themselves.

It also has some side effects: vassals are harder to catch up tech-wise, great people only give the application half of a technology, and goodie huts only give half of a technology when you walk on them.

This change is inspired by playing fractal maps both with and without tech trading. Civilizations on the larger continents gain an insane tech edge with tech trading on, and without tech trading the size of your continent really doesn't matter to your tech development. This change aims at a happy medium between these two endpoints: having access to multiple civilizations will at best double your technological growth rate, instead of it scaling with the number of civilizations.

It also makes teching up vassals harder: you can give them the tradeable component, but they have to research the other half themselves.

Currently, I have a python script that can take a tech from the CIV4TechInfos.xml file and parse out the single-line XML entries. Next, I have to write the logic to split each tech entry into theory and practice, each with half of the research cost.

The practical tech will be exactly like the current tech, except:
1> The prereqs will be the theory and only the theory.
2> bTrade will be off.
3> The horizontal position will be doubled plus 1
4> The cost will be half.
5> iAsset and iPower will be halved

The theoretical tech will be a "blank" tech with some features taken from the original:
1> Half cost
2> Name changed to original_THEORY
3> Horizonal position will be double original
4> Prereqs will be original prereqs
5> bGoodie will be original (why not)
6> Era, Civilopedia, Help, Strategy, Description, Advisor, AI weights, AI trade, Sound, SoundMP, Quote, and Button will be the original.
7> iPower, iAsset will be half of original

Lastly, the script will take a list of techs that it should leave "unsplit" from the user. These techs will have their horizontal position doubled, but no other changes. This is useful for future tech and starting techs, or any other tech that the user doesn't think should be split.

Do you think I missed anything?

Btw, here is the code to match single-line XML tags in python:
Code:
   generic_pattern = re.compile("<(?P<Tag>.*)>(.*)<\/(?P=Tag)>")
    for generic_match in generic_pattern.finditer(tech):
        if generic_match == None:
            print "generic pattern failed"
        else:
            print "the pattern tagged", generic_match.group(1), "as", generic_match.group(2), "."

Practically, the idea is that I'll use the above as a "filter" on the practical half of the tech, and meanwhile gathering up information to build the theoretical half. Once I have the information needed for the theoretical half, I can dump it out followed by the "filtered" pratical half.

I do have some concerns -- will civ4 like it when more than 1 tech have the same civopedia entry?
 
I would LOVE to be able to use this for Pitboss games. We often have to decide between trading (insane tech rate which is murderous to isolated starts) or no trading (less diplomatic "glue" in the human-only environment). This medium would be perfect in that environment.
 
Progress:
I convinced the python to produce the application half of fusion.

Code:
		<TechInfo>
			<Type>TECH_FUSION</Type> 
			<Description>TXT_KEY_TECH_FUSION</Description> 
			<Civilopedia>TXT_KEY_TECH_FUSION_PEDIA</Civilopedia> 
			<Help/>
			<Strategy>TXT_KEY_TECH_FUSION_STRATEGY</Strategy> 
			<Advisor>ADVISOR_SCIENCE</Advisor> 
			<iAIWeight>0</iAIWeight> 
			<iAITradeModifier>10</iAITradeModifier> 
			<iCost>4000</iCost> 
			<Era>ERA_MODERN</Era> 
			<FirstFreeUnitClass>UNITCLASS_ENGINEER</FirstFreeUnitClass> 
			<iFeatureProductionModifier>0</iFeatureProductionModifier> 
			<iWorkerSpeedModifier>0</iWorkerSpeedModifier> 
			<iTradeRoutes>0</iTradeRoutes> 
			<iHealth>0</iHealth> 
			<iHappiness>0</iHappiness> 
			<iFirstFreeTechs>0</iFirstFreeTechs> 
			<iAsset>24</iAsset> 
			<iPower>0</iPower> 
			<bRepeat>0</bRepeat> 
			<bTrade>0</bTrade> 
			<bDisable>0</bDisable> 
			<bGoodyTech>0</bGoodyTech> 
			<bExtraWaterSeeFrom>0</bExtraWaterSeeFrom> 
			<bMapCentering>0</bMapCentering> 
			<bMapVisible>0</bMapVisible> 
			<bMapTrading>0</bMapTrading> 
			<bTechTrading>0</bTechTrading> 
			<bGoldTrading>0</bGoldTrading> 
			<bOpenBordersTrading>0</bOpenBordersTrading> 
			<bDefensivePactTrading>0</bDefensivePactTrading> 
			<bPermanentAllianceTrading>0</bPermanentAllianceTrading> 
			<bVassalTrading>0</bVassalTrading> 
			<bBridgeBuilding>0</bBridgeBuilding> 
			<bIrrigation>0</bIrrigation> 
			<bIgnoreIrrigation>0</bIgnoreIrrigation> 
			<bWaterWork>0</bWaterWork> 
			<iGridX>39</iGridX> 
			<iGridY>5</iGridY> 
			<DomainExtraMoves/>
			<CommerceFlexible/>
			<TerrainTrades/>
			<Flavors>
				<Flavor>
					<FlavorType>FLAVOR_PRODUCTION</FlavorType> 
					<iFlavor>3</iFlavor> 
				</Flavor>
				<Flavor>
					<FlavorType>FLAVOR_SCIENCE</FlavorType> 
					<iFlavor>8</iFlavor> 
				</Flavor>
			</Flavors>
			<OrPreReqs>
				<PrereqTech>TECH_FUSION_THEORY</PrereqTech>

			</OrPreReqs>
			<AndPreReqs>
				
			</AndPreReqs>
			<Quote>TXT_KEY_TECH_FUSION_QUOTE</Quote> 
			<Sound>AS2D_TECH_FUSION</Sound> 
			<SoundMP>AS2D_TECH_MP_FUSION</SoundMP> 
			<Button>,Art/Interface/Buttons/TechTree/Fusion.dds,Art/Interface/Buttons/TechTree_Atlas.dds,1,4</Button> 
		</TechInfo>

The formatting isn't quite perfect -- I hope the civ4 XML parser isn't too picky.

Here is the code that dumped the above (it is pretty much a hack):
Code:
def theory( tech, skips = [], ratio = 0.5 ):
    some_keys = {}
    name_pattern = re.compile("<Type>(\w*)<\/Type>")
    name_match = re.search(name_pattern, tech)
    if name_match == None:
        print "did not find a name for the tech!"
    else:
        print "the name of the tech is", name_match.group(1)

    generic_pattern = re.compile("<(?P<Tag>.*)>(.*)<\/(?P=Tag)>")
    last_match = 0
    InPreOr = 0
    InPreAnd = 0
    for generic_match in generic_pattern.finditer(tech):
        if generic_match is None:
            print "generic pattern failed"
        else:
            skiptag = 0
            start_match = generic_match.start()
            between = tech[last_match:start_match]
            last_match = generic_match.end()
            tag = generic_match.group(1)
            contents = generic_match.group(2)

            if tag in some_keys:
                if some_keys[tag] is list:
                    some_keys[tag].append(contents)
                else:
                    some_keys[tag] = [some_keys[tag], contents]
            else:
                some_keys[tag]=contents
            if tag == 'iCost':
                contents = "&#37;d"%(int(contents) * (1-ratio))
            if tag == 'bTrade':
                contents = '0'
            if tag == 'iGridX':
                contents = "%d"%(int(contents) * 2 + 1)
            if tag in ['iAsset', 'iPower']:
                contents = "%d"%(int(contents) / 2)
            PreOr = re.compile("<OrPreReqs>").search(between)
            PreAnd = re.compile("<AndPreReqs>").search(between)
            if not (PreOr is None):
                InPreOr = 1
                InPreAnd = 0
            elif not (PreAnd is None):
                InPreOr = 0
                InPreAnd = 1
            if tag == 'PrereqTech' and InPreOr:
                skiptag = 1
            elif tag == 'PrereqTech' and InPreAnd:
                skiptag = 1
            elif tag == 'PrereqTech':
                print "ERROR ERROR ERROR"
                print "Prereq tech found not in a PreAnd or PreOr!"
                
            print between,
            if not skiptag:
                print "<%s>%s</%s>"%(tag, contents, tag),

            if not (PreOr is None):
                print "<%s>%s</%s>"%(tag, "%s%s"%(some_keys['Type'], '_THEORY'), tag)

    between = tech[last_match:]
    print between,
    
    print "we have a theory:"

    print_theory( some_keys, ratio )

The dictionary "some_keys" has enough information in it to build the _THEORY version: it contains all of the single-line XML data and tags.

Here is a partially finished computer-generated theory:
Code:
		<TechInfo>
			<Type>TECH_FUSION_THEORY</Type>
			<Description>TXT_KEY_TECH_FUSION</Description>
			<Civilopedia>TXT_KEY_TECH_FUSION_PEDIA</Civilopedia>
			<Help/>
			<Strategy>TXT_KEY_TECH_FUSION_STRATEGY</Strategy>
			<Advisor>ADVISOR_SCIENCE</Advisor>
			<iAIWeight>0</iAIWeight>
			<iAITradeModifier>10</iAITradeModifier>
			<iCost>4000</iCost>
			<Era>ERA_MODERN</Era>
			<FirstFreeUnitClass>None</FirstFreeUnitClass> 
			<iFeatureProductionModifier>0</iFeatureProductionModifier> 
			<iWorkerSpeedModifier>0</iWorkerSpeedModifier> 
			<iTradeRoutes>0</iTradeRoutes> 
			<iHealth>0</iHealth> 
			<iHappiness>0</iHappiness> 
			<iFirstFreeTechs>0</iFirstFreeTechs>
			<iAsset>24</iAsset>
			<iPower>0</iPower>
			<bRepeat>0</bRepeat> 
			<bTrade>1</bTrade> 
			<bDisable>0</bDisable> 
			<bGoodyTech>0</bGoodyTech> 
			<bExtraWaterSeeFrom>0</bExtraWaterSeeFrom> 
			<bMapCentering>0</bMapCentering> 
			<bMapVisible>0</bMapVisible> 
			<bMapTrading>0</bMapTrading> 
			<bTechTrading>0</bTechTrading> 
			<bGoldTrading>0</bGoldTrading> 
			<bOpenBordersTrading>0</bOpenBordersTrading> 
			<bDefensivePactTrading>0</bDefensivePactTrading> 
			<bPermanentAllianceTrading>0</bPermanentAllianceTrading> 
			<bVassalTrading>0</bVassalTrading> 
			<bBridgeBuilding>0</bBridgeBuilding> 
			<bIrrigation>0</bIrrigation> 
			<bIgnoreIrrigation>0</bIgnoreIrrigation> 
			<bWaterWork>0</bWaterWork>
			<iGridX>38</iGridX>
			<iGridY>5</iGridY>
			<DomainExtraMoves/>
			<CommerceFlexible/>
			<TerrainTrades/>
Not done yet:
			<Flavors>
				<Flavor>
					<FlavorType>$CONTENTS*</FlavorType> 
					<iFlavor>$CONTENTS*</iFlavor> 
				</Flavor>
			</Flavors>
			<OrPreReqs>
				$OR_TECHS
			</OrPreReqs>
			<AndPreReqs>
				$AND_TECHS
			</AndPreReqs>
			<Quote>$CONTENTS</Quote> 
			<Sound>$CONTENTS</Sound> 
			<SoundMP>$CONTENTS</SoundMP> 
			<Button>$CONTENTS</Button> 
		</TechInfo>

The hard parts (the and techs, the or techs, and the flavours) have yet to be done. The "$CONTENTS" are just placeholders to remind me what should go there.

I'm off to bed and/or to game for the night (and maybe the weekend). Thought I'd post my progress.
 
You could make it so each tech only enables you to build an improvement or national wonder that actually puts the technology into effect.

That would have the additional effect of making the benefits of a technology limited to the city that has the improvement, and also making it possible to "bomb people back to the stone age." FFH2 already does this to some extent.

Of course that might make the game a bit improvement-heavy.
 
Back
Top Bottom