View Full Version : [MODCOMP] Doviello Icehouse


Vehem
Feb 09, 2008, 07:18 PM
Doviello Icehouse Release 1 (http://forums.civfanatics.com/downloads.php?do=file&id=8369)

The MODCOMP adds one new unique building to the Doviello civilization, replacing the Smokehouse. Named an "Icehouse", this building fulfills all the normal roles of a Smokehouse, but has an additional ability when the city containing it is built in Tundra or Snow/Ice terrain.

In that case, the city will become immune to the effects of starvation. You may effectively grow the city to whatever size you can achieve in the tundra (using farms/agriculture, deer-camps etc), then switch from food production to working other tiles without losing population. This allows more viable tundra-based cities, although Tundra still remains quite poor in terms of it's yields and improvement potential.

The Icehouse has no additional benefits if the city is built in any other type of terrain - it only works for Tundra/Ice based cities.

The original suggestion for this came from Cephalo in [this thread] (http://forums.civfanatics.com/showpost.php?p=6455598&postcount=1). I adapted it slightly and used a building to implement the ability as seems to be the trend with Civ-specific buildings (Svaltafar Hunting Lodges, Ljosofar Archery Ranges, Bannor Training Yards, Lanun Harbours etc).

==

The MODCOMP is a combined SDK/Python/XML mod, with two new functions exposed to Python "cannotGrow" and "cannotStarve". These are called whenever a city is due to change population due to food and can block the population change if the function returns true. The XML changes implement the Icehouse as an example usage.


------------------ Assets/XML/Buildings/CIV4BuildingInfos.xml ------------------
index 63acdc0..d0f3a6a 100644
@@ -30245,6 +30245,237 @@
</SpecialistCommerceChanges>
</BuildingInfo>
<BuildingInfo>
+ <BuildingClass>BUILDINGCLASS_SMOKEHOUSE</BuildingClass>
+ <Type>BUILDING_DOVIELLO_SMOKEHOUSE</Type>
+ <SpecialBuildingType>NONE</SpecialBuildingType>
+ <Description>TXT_KEY_BUILDING_DOVIELLO_SMOKEHOUSE</Description>
+ <Civilopedia>TXT_KEY_BUILDING_DOVIELLO_SMOKEHOUSE_PEDIA</Civilopedia>
+ <Strategy>TXT_KEY_BUILDING_DOVIELLO_SMOKEHOUSE_STRATEGY</Strategy>
+ <Help></Help>
+ <Advisor>ADVISOR_GROWTH</Advisor>
+ <ArtDefineTag>ART_DEF_BUILDING_SMOKEHOUSE</ArtDefineTag>
+ <MovieDefineTag>NONE</MovieDefineTag>
+ <HolyCity>NONE</HolyCity>
+ <ReligionType>NONE</ReligionType>
+ <StateReligion>NONE</StateReligion>
+ <bStateReligion>0</bStateReligion>
+ <PrereqReligion>NONE</PrereqReligion>
+ <PrereqCorporation>NONE</PrereqCorporation>
+ <FoundsCorporation>NONE</FoundsCorporation>
+ <GlobalReligionCommerce>NONE</GlobalReligionCommerce>
+ <GlobalCorporationCommerce>NONE</GlobalCorporationCommerce>
+ <VictoryPrereq>NONE</VictoryPrereq>
+ <FreeStartEra>NONE</FreeStartEra>
+ <MaxStartEra>NONE</MaxStartEra>
+ <ObsoleteTech>NONE</ObsoleteTech>
+ <PrereqTech>TECH_ANIMAL_HUSBANDRY</PrereqTech>
+ <TechTypes>
+ </TechTypes>
+ <Bonus>NONE</Bonus>
+ <PrereqBonuses>
+ </PrereqBonuses>
+ <ProductionTraits>
+ </ProductionTraits>
+ <HappinessTraits>
+ </HappinessTraits>
+ <NoBonus>NONE</NoBonus>
+ <PowerBonus>NONE</PowerBonus>
+ <FreeBonus>NONE</FreeBonus>
+ <iNumFreeBonuses>0</iNumFreeBonuses>
+ <FreeBuilding>NONE</FreeBuilding>
+ <FreePromotion>NONE</FreePromotion>
+ <CivicOption>NONE</CivicOption>
+ <GreatPeopleUnitClass>NONE</GreatPeopleUnitClass>
+ <iGreatPeopleRateChange>0</iGreatPeopleRateChange>
+ <iHurryAngerModifier>0</iHurryAngerModifier>
+ <bBorderObstacle>0</bBorderObstacle>
+ <bTeamShare>0</bTeamShare>
+ <bWater>0</bWater>
+ <bRiver>0</bRiver>
+ <bPower>0</bPower>
+ <bDirtyPower>0</bDirtyPower>
+ <bAreaCleanPower>0</bAreaCleanPower>
+ <DiploVoteType>NONE</DiploVoteType>
+ <bForceTeamVoteEligible>0</bForceTeamVoteEligible>
+ <bCapital>0</bCapital>
+ <bGovernmentCenter>0</bGovernmentCenter>
+ <bGoldenAge>0</bGoldenAge>
+ <bAllowsNukes>0</bAllowsNukes>
+ <bMapCentering>0</bMapCentering>
+ <bNoUnhappiness>0</bNoUnhappiness>
+ <bNoUnhealthyPopulation>0</bNoUnhealthyPopulation>
+ <bBuildingOnlyHealthy>0</bBuildingOnlyHealthy>
+ <bNeverCapture>0</bNeverCapture>
+ <bNukeImmune>0</bNukeImmune>
+ <bPrereqReligion>0</bPrereqReligion>
+ <bCenterInCity>0</bCenterInCity>
+ <iAIWeight>0</iAIWeight>
+ <iCost>120</iCost>
+ <iHurryCostModifier>0</iHurryCostModifier>
+ <iAdvancedStartCost>100</iAdvancedStartCost>
+ <iAdvancedStartCostIncrease>0</iAdvancedStartCostIncrease>
+ <iMinAreaSize>-1</iMinAreaSize>
+ <iConquestProb>25</iConquestProb>
+ <iCitiesPrereq>0</iCitiesPrereq>
+ <iTeamsPrereq>0</iTeamsPrereq>
+ <iLevelPrereq>0</iLevelPrereq>
+ <iMinLatitude>0</iMinLatitude>
+ <iMaxLatitude>90</iMaxLatitude>
+ <iGreatPeopleRateModifier>0</iGreatPeopleRateModifier>
+ <iGreatGeneralRateModifier>0</iGreatGeneralRateModifier>
+ <iDomesticGreatGeneralRateModifier>0</iDomesticGreatGeneralRateModifier>
+ <iGlobalGreatPeopleRateModifier>0</iGlobalGreatPeopleRateModifier>
+ <iAnarchyModifier>0</iAnarchyModifier>
+ <iGoldenAgeModifier>0</iGoldenAgeModifier>
+ <iGlobalHurryModifier>0</iGlobalHurryModifier>
+ <iExperience>0</iExperience>
+ <iGlobalExperience>0</iGlobalExperience>
+ <iFoodKept>20</iFoodKept>
+ <iAirlift>0</iAirlift>
+ <iAirModifier>0</iAirModifier>
+ <iAirUnitCapacity>0</iAirUnitCapacity>
+ <iNukeModifier>0</iNukeModifier>
+ <iNukeExplosionRand>0</iNukeExplosionRand>
+ <iFreeSpecialist>0</iFreeSpecialist>
+ <iAreaFreeSpecialist>0</iAreaFreeSpecialist>
+ <iGlobalFreeSpecialist>0</iGlobalFreeSpecialist>
+ <iMaintenanceModifier>0</iMaintenanceModifier>
+ <iWarWearinessModifier>0</iWarWearinessModifier>
+ <iGlobalWarWearinessModifier>0</iGlobalWarWearinessModifier>
+ <iEnemyWarWearinessModifier>0</iEnemyWarWearinessModifier>
+ <iHealRateChange>0</iHealRateChange>
+ <iHealth>0</iHealth>
+ <iAreaHealth>0</iAreaHealth>
+ <iGlobalHealth>0</iGlobalHealth>
+ <iHappiness>0</iHappiness>
+ <iAreaHappiness>0</iAreaHappiness>
+ <iGlobalHappiness>0</iGlobalHappiness>
+ <iStateReligionHappiness>0</iStateReligionHappiness>
+ <iWorkerSpeedModifier>0</iWorkerSpeedModifier>
+ <iMilitaryProductionModifier>0</iMilitaryProductionModifier>
+ <iSpaceProductionModifier>0</iSpaceProductionModifier>
+ <iGlobalSpaceProductionModifier>0</iGlobalSpaceProductionModifier>
+ <iTradeRoutes>0</iTradeRoutes>
+ <iCoastalTradeRoutes>0</iCoastalTradeRoutes>
+ <iGlobalTradeRoutes>0</iGlobalTradeRoutes>
+ <iTradeRouteModifier>0</iTradeRouteModifier>
+ <iForeignTradeRouteModifier>0</iForeignTradeRouteModifier>
+ <iGlobalPopulationChange>0</iGlobalPopulationChange>
+ <iFreeTechs>0</iFreeTechs>
+ <iDefense>0</iDefense>
+ <iBombardDefense>0</iBombardDefense>
+ <iAllCityDefense>0</iAllCityDefense>
+ <iEspionageDefense>0</iEspionageDefense>
+ <iAsset>3</iAsset>
+ <iPower>0</iPower>
+ <fVisibilityPriority>9</fVisibilityPriority>
+ <SeaPlotYieldChanges>
+ </SeaPlotYieldChanges>
+ <RiverPlotYieldChanges>
+ </RiverPlotYieldChanges>
+ <GlobalSeaPlotYieldChanges>
+ </GlobalSeaPlotYieldChanges>
+ <YieldChanges>
+ </YieldChanges>
+ <YieldModifiers>
+ </YieldModifiers>
+ <CommerceChanges>
+ </CommerceChanges>
+ <ObsoleteSafeCommerceChanges>
+ </ObsoleteSafeCommerceChanges>
+ <CommerceChangeDoubleTimes>
+ </CommerceChangeDoubleTimes>
+ <CommerceModifiers>
+ </CommerceModifiers>
+ <GlobalCommerceModifiers>
+ </GlobalCommerceModifiers>
+ <SpecialistExtraCommerces>
+ </SpecialistExtraCommerces>
+ <StateReligionCommerces>
+ </StateReligionCommerces>
+ <CommerceHappinesses>
+ </CommerceHappinesses>
+ <ReligionChanges>
+ </ReligionChanges>
+ <SpecialistCounts>
+ </SpecialistCounts>
+ <FreeSpecialistCounts>
+ </FreeSpecialistCounts>
+ <CommerceFlexibles>
+ </CommerceFlexibles>
+ <CommerceChangeOriginalOwners>
+ </CommerceChangeOriginalOwners>
+ <ConstructSound>AS2D_BUILD_GRANARY</ConstructSound>
+ <BonusHealthChanges>
+ <BonusHealthChange>
+ <BonusType>BONUS_COW</BonusType>
+ <iHealthChange>1</iHealthChange>
+ </BonusHealthChange>
+ <BonusHealthChange>
+ <BonusType>BONUS_PIG</BonusType>
+ <iHealthChange>1</iHealthChange>
+ </BonusHealthChange>
+ <BonusHealthChange>
+ <BonusType>BONUS_SHEEP</BonusType>
+ <iHealthChange>1</iHealthChange>
+ </BonusHealthChange>
+ <BonusHealthChange>
+ <BonusType>BONUS_TOAD</BonusType>
+ <iHealthChange>1</iHealthChange>
+ </BonusHealthChange>
+ </BonusHealthChanges>
+ <BonusHappinessChanges>
+ </BonusHappinessChanges>
+ <BonusProductionModifiers>
+ </BonusProductionModifiers>
+ <UnitCombatFreeExperiences>
+ </UnitCombatFreeExperiences>
+ <DomainFreeExperiences>
+ </DomainFreeExperiences>
+ <DomainProductionModifiers>
+ </DomainProductionModifiers>
+ <BuildingHappinessChanges>
+ </BuildingHappinessChanges>
+ <PrereqBuildingClasses>
+ </PrereqBuildingClasses>
+ <BuildingClassNeededs>
+ </BuildingClassNeededs>
+ <SpecialistYieldChanges>
+ </SpecialistYieldChanges>
+ <BonusYieldModifiers>
+ </BonusYieldModifiers>
+ <ImprovementFreeSpecialists>
+ </ImprovementFreeSpecialists>
+ <Flavors>
+ <Flavor>
+ <FlavorType>FLAVOR_GROWTH</FlavorType>
+ <iFlavor>10</iFlavor>
+ </Flavor>
+ </Flavors>
+ <HotKey></HotKey>
+ <bAltDown>0</bAltDown>
+ <bShiftDown>0</bShiftDown>
+ <bCtrlDown>0</bCtrlDown>
+ <bGraphicalOnly>0</bGraphicalOnly>
+ <iHotKeyPriority>0</iHotKeyPriority>
+ <bApplyFreePromotionOnMove>0</bApplyFreePromotionOnMove>
+ <bEquipment>0</bEquipment>
+ <bNoCivicAnger>0</bNoCivicAnger>
+ <bRequiresCaster>0</bRequiresCaster>
+ <bUnhappyProduction>0</bUnhappyProduction>
+ <iCrime>0</iCrime>
+ <iFreePromotionPick>0</iFreePromotionPick>
+ <iModifyGlobalCounter>0</iModifyGlobalCounter>
+ <iPlotRadius>0</iPlotRadius>
+ <iResistMagic>0</iResistMagic>
+ <FreeBonus2>NONE</FreeBonus2>
+ <FreeBonus3>NONE</FreeBonus3>
+ <PrereqTrait>NONE</PrereqTrait>
+ <RemovePromotion>NONE</RemovePromotion>
+ <SpecialistCommerceChanges>
+ </SpecialistCommerceChanges>
+ </BuildingInfo>
+ <BuildingInfo>
<BuildingClass>BUILDINGCLASS_SMUGGLERS_PORT</BuildingClass>
<Type>BUILDING_SMUGGLERS_PORT</Type>
<SpecialBuildingType>NONE</SpecialBuildingType>

-------------- Assets/XML/Civilizations/CIV4CivilizationInfos.xml --------------
index 7369b36..5c042a3 100644
@@ -3607,6 +3607,10 @@
<BuildingType>NONE</BuildingType>
</Building>
<Building>
+ <BuildingClassType>BUILDINGCLASS_SMOKEHOUSE</BuildingClassType>
+ <BuildingType>BUILDING_DOVIELLO_SMOKEHOUSE</BuildingType>
+ </Building>
+ <Building>
<BuildingClassType>BUILDINGCLASS_BOWYER</BuildingClassType>
<BuildingType>NONE</BuildingType>
</Building>

------------------------- Assets/python/CvGameUtils.py -------------------------
index d8bd006..b8c047f 100644
@@ -567,6 +567,17 @@ class CvGameUtils:
pCity = argsList[0]
return False

+ def cannotGrow(self,argsList):
+ pCity = argsList[0]
+ return False
+
+ def cannotStarve(self,argsList):
+ pCity = argsList[0]
+ if pCity.getNumRealBuilding(gc.getInfoTypeForString(' BUILDING_DOVIELLO_SMOKEHOUSE')) > 0:
+ if (pCity.plot().getTerrainType()==gc.getInfoTypeForS tring('TERRAIN_TUNDRA')) or (pCity.plot().getTerrainType()==gc.getInfoTypeForS tring('TERRAIN_SNOW')):
+ return True;
+ return False
+
def doProduction(self,argsList):
pCity = argsList[0]
return False

----------------- Assets/python/entrypoints/CvGameInterface.py -----------------
return gameUtils().doGoody(argsList)

def doGrowth(argsList):
#CvUtil.pyPrint( "CvGameInterface.doGrowth" )
return gameUtils().doGrowth(argsList)

+def cannotGrow(argsList):
+ #CvUtil.pyPrint( "CvGameInterface.cannotGrow" )
+ return gameUtils().cannotGrow(argsList)
+
+def cannotStarve(argsList):
+ #CvUtil.pyPrint( "CvGameInterface.cannotStarve" )
+ return gameUtils().cannotStarve(argsList)
+
+
def doProduction(argsList):
#CvUtil.pyPrint( "CvGameInterface.doProduction" )
return gameUtils().doProduction(argsList)




void CvCity::doGrowth()
{
int iDiff;

CyCity* pyCity = new CyCity(this);
CyArgsList argsList;
argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity)); // pass in city class
long lResult=0;
gDLL->getPythonIFace()->callFunction(PYGameModule, "doGrowth", argsList.makeFunctionArgs(), &lResult);
delete pyCity; // python fxn must not hold on to this pointer
if (lResult == 1)
{
return;
}

iDiff = foodDifference();

changeFood(iDiff);
changeFoodKept(iDiff);

setFoodKept(range(getFoodKept(), 0, ((growthThreshold() * getMaxFoodKeptPercent()) / 100)));

if (getFood() >= growthThreshold())
{
+ CyCity* pyCity = new CyCity(this);
+ CyArgsList argsList;
+ argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity)); // pass in city class
+ long lResult=0;
+ gDLL->getPythonIFace()->callFunction(PYGameModule, "cannotGrow", argsList.makeFunctionArgs(), &lResult);
+ delete pyCity; // python fxn must not hold on to this pointer
+ if (lResult==1)
+ {
+ setFood(growthThreshold());
+ return;
+ }

if (AI_isEmphasizeAvoidGrowth())
{
setFood(growthThreshold());
}
else
{
changeFood(-(std::max(0, (growthThreshold() - getFoodKept()))));
changePopulation(1);

// ONEVENT - City growth
gDLL->getEventReporterIFace()->cityGrowth(this, getOwnerINLINE());
}
}
else if (getFood() < 0)
{
changeFood(-(getFood()));
+ CyCity* pyCity = new CyCity(this);
+ CyArgsList argsList;
+ argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity)); // pass in city class
+ long lResult=0;
+ gDLL->getPythonIFace()->callFunction(PYGameModule, "cannotStarve", argsList.makeFunctionArgs(), &lResult);
+ delete pyCity; // python fxn must not hold on to this pointer
+ if (lResult==1)
+ {
+ return;
+ }

if (getPopulation() > 1)
{
changePopulation(-1);
}
}

MagisterCultuum
Feb 09, 2008, 07:58 PM
How do you make a city immune to the effects of starvation? Can it be done with only xml/python? Also, would it be possible to make the building also slow the rate at which a city continues to grow?

I would really like to know, because I was thinking of adding a Ice House type building (probably with the same name) either as a temporary building granted by an Ice sphere spell, or possible a normal building requiring ice mana (which I've already added to my modmod and given to the Illians and Doviello palaces, and made the Letum Frigus provide it, and I also already the ice sphere promotions and made them be given out to adepts appropriately, and started witting the spells. But I just realized I haven't added the node yet...now I have.)



I don't think that I'm the one you were thinking of, but I had proposed something similar as what I considered a far-fetched idea for a possible divine ice spell (thus available only to Illian UUs) in my modmod thread a couple of days before I came across the post we are both thinking of. I didn't say no starvation, just slower population growth and shrinkage.

Edit: I think I found it. It isn't a building, but cephalo proposed the general idea of it here:http://forums.civfanatics.com/showpost.php?p=6455598&postcount=1
I do think that the Illians should get this ability/building too, not just the Doviello.

Vehem
Feb 09, 2008, 08:12 PM
I can't see an easy way of doing it without the SDK, unless you decide to override the whole of the "doGrowth" behaviour which is already exposed to Python. I'll be adding the DLL and source changes to the post however, and there's not much to it.

As for the other part, it's easy enough to add a percentage chance to the "cannotGrow" and "cannotStarve" functions (these are what the SDK mod creates - new places for Python checks). For example, an earlier version I was toying with made the city only starve if (a) it had a negative amount of food and (b) it passed a random check at 20%. The result would mean it (on average) starved 5 times more slowly once the food store was depleted.

Same can apply to growth in reverse. You could add a 10% chance to grow (so 90% chance of not growing) on any turn that the food is at maximum if you wanted to really slow down the growth rate.

--

The conditions can be pretty much anything - all that matters is that if you return 1 to "cannotStarve" you won't starve this turn. Same for "cannotGrow". If the functions return 0, the normal behaviour applies.

MagisterCultuum
Feb 09, 2008, 09:15 PM
:(

I've never tried editing the SDK or any C++ files myself, and, while I'd eventually like to learn, I was hoping I could add this building/spell sooner than that.

I also assume that your changes would probably not be easily combined with the changes in the unit statistics FfH modmod, which I decided to base the next version of Magister Modmod on.

Where would I find this doGrowth code to edit?
Edit: I think I found it in CvDameUtils.py, but I don't know what in def doGrowth(self,argsList):
pCity = argsList[0]
return False can be changed to do what I want.

xienwolf
Feb 09, 2008, 10:03 PM
Man, how lucky is that :) MC is aiming to try and make something happen and you come along and do all the work for him, even making it general enough that ANY building/spell/whatever can incorporate the functions :)

So, does the City Tile itself have to be Tundra/Ice, or a certain percentage of the BFC?

Vehem
Feb 10, 2008, 04:10 AM
:(

I've never tried editing the SDK or any C++ files myself, and, while I'd eventually like to learn, I was hoping I could add this building/spell sooner than that.

I also assume that your changes would probably not be easily combined with the changes in the unit statistics FfH modmod, which I decided to base the next version of Magister Modmod on.

Where would I find this doGrowth code to edit?
Edit: I think I found it in CvDameUtils.py, but I don't know what in def doGrowth(self,argsList):
pCity = argsList[0]
return False can be changed to do what I want.

Unless the UnitStatistics mod changed CvCity.cpp, it is very easy to combine (just drop the IceHouse CvCity.cpp over the original before compiling). Even if it did, I doubt they modified this function so a cut-and-paste job should suffice.

==

The python you quoted is indeed the right place to look. If that function returns "true" - the rest of the growth code in the DLL is completely ignored. It won't check to see if the food is over the threshold or negative - it will just do nothing. That means that if you make changes in Python there, you have to handle *all* of the growth code for that case. I added the other two checks so that I could let the C++ handle it as far as the special cases (growing/starving) and then just deal with that behaviour as I wanted.

In other words...


def doGrowth(self,argsList):
pCity = argsList[0]
if pCity.someAttribute == someCondition
pCity.changePopulation(5)
pCity.changeFood(-(pCity.getFood())
return True
return False


...would look at pCity, check if the Condition is met, if so - changes the population by 5 and then resets the food store before returning "True". Because it returns true, the C++ code will not do anything further to handle growth for this city. [The above is purely pseudo-code before someone tells me "it doesn't work" :P]

If pCity does not meet that condition, the function will return False, so the C++ will continue to handle the growth behaviour as normal.

==

@xienwolf

So, does the City Tile itself have to be Tundra/Ice, or a certain percentage of the BFC?


Just the City Tile. Admittedly can be quite potent after Druids make an appearance but that tends to be quite a late game event anyway. Genesis is also an issue, but only if the city is founded on Ice tiles (if it was founded on Tundra, Genesis would upgrade that to Plains and remove the effect).

The conditions for the effect are all in Python however, so it's easy enough to alter the behaviour to match however you'd like it. The "percentage of the fat cross" is a little process intensive for such a common event (i.e. growth/starving) and I went with the simple option for the sake of speed. It would simply be a case of iterating over the workable tiles of the city and counting how many Tundra/Ice are present however. Once it meets the threshold, return True.

it-ogo
Feb 10, 2008, 04:42 AM
As I understand code only tile of city is accounted for. It looks insanely overpowered in the late game. You need only one tile with tundra or ice. Others can be vitalized to plains/grassland and filled with cottages/workshops. Finally all the population can be made specialists, and no influence of plague.

MagisterCultuum
Feb 10, 2008, 07:17 AM
Thats one reason why I think that Ice mana is a better requirement than ice/tundra terrain.

Hmm, if I just modified a few C++ files, do I have to compile the whole .dll over again the whole thing in my modmod or not? I assumed I would, but I noticed that the files the Unit Statistics mod changed seem to be not in a custom .dll but just in an SDK files folder (containing CvGlobals.cp, CvGlobals.h, CvUnit.cpp, and CvUnit.h) found in the main mod folder. Also, I had an error when I first tried compiling the SDK last night (i.e., early this morning), even before making any changes. If I can just load a couple of changed files into a folder, then I may go ahead and add your code (and also allow HN units to capture units, which appears to only involve deleting/commenting out about 3 lines inCvUNit.cpp)

Vehem
Feb 10, 2008, 10:49 AM
Hmm, if I just modified a few C++ files, do I have to compile the whole .dll over again the whole thing in my modmod or not?

You do need to compile it - the source directories are normally included to allow others to see the changes and compile them into their own projects.

The best way I've found to setup a compiler for it so far is to follow the guide Kael posted (HERE (http://forums.civfanatics.com/showthread.php?t=166933)) to the letter. Look at the pictures and make sure everything is exactly as needed. Codeblocks is actually a very nice little editor once it's up and running. I have also managed to compile it in VisualStudio 2008, but it had some serious stability issues that suggested something went awry. The version using Codeblocks however has been solid.

xienwolf
Feb 10, 2008, 11:44 AM
Tied to ice mana could be interesting. Would you limit the size of population that can be kept from starving to the amount of Ice Mana available? (like say 3 population per Ice Node. So with just the Ice from the Palace they can have size 3 cities without starvation, but to get size 12 cities they would need the Palace + 3 nodes)

I agree that Vitalize comes late enough not to worry too much about them creating cities with tundra only on the base square. And yes, Genesis will typically kill off more Ice Houses than it "super-promotes."

Pretty sure that I would tend to grow as much as I can manage, then swap to pure specialists if I have the buildings for it. Could make for some small, but strong, Ice cities.

MagisterCultuum
Feb 10, 2008, 12:49 PM
Tied to ice mana could be interesting. Would you limit the size of population that can be kept from starving to the amount of Ice Mana available? (like say 3 population per Ice Node. So with just the Ice from the Palace they can have size 3 cities without starvation, but to get size 12 cities they would need the Palace + 3 nodes)

I hadn't thought if that particular implementation, but I quite like it.

Pretty sure that I would tend to grow as much as I can manage, then swap to pure specialists if I have the buildings for it. Could make for some small, but strong, Ice cities.

That sounds especially appropriate for the Illians to me.

"Once you had been the greatest of scholars and priests, tributes were paid to you by all nations." -Auric Ulvin to the Illians, when he emerged from the Letum Frigus and became their leader

Sounds like Mulcarn may have followed this same strategy, which hurt the Ilians one they lost the "ice mana" his presence gave them, and began to starve and fall into barbarism. But Auric's return will reverse this...

Vehem
Feb 10, 2008, 01:54 PM
Tied to ice mana could be interesting. Would you limit the size of population that can be kept from starving to the amount of Ice Mana available? (like say 3 population per Ice Node. So with just the Ice from the Palace they can have size 3 cities without starvation, but to get size 12 cities they would need the Palace + 3 nodes)

That sounds like an excellent one for the Illians. I'd like to try to keep the mechanics distinct (one for the Doviello and a slightly different one for the Illians) and this would be the perfect way to do that. Doviello survive through hunting, Illians survive through their affinity with the Ice. It also allows the Illians to grow their ice-cities in a manner dependent on mana, which "feels" right.


I agree that Vitalize comes late enough not to worry too much about them creating cities with tundra only on the base square. And yes, Genesis will typically kill off more Ice Houses than it "super-promotes."

Pretty sure that I would tend to grow as much as I can manage, then swap to pure specialists if I have the buildings for it. Could make for some small, but strong, Ice cities.

I'm hoping that's the case - I tried a run through before release where I attempted to exploit the ability in the worst ways I could find (including rushing toward Druids and creating super-specialist cities in terraformed areas). To be honest, I've had more successful games where I simply tech-along the Melee line at a steady rate and warmonger. I could feasibly have warmongered to a solid lead by the time druids were researched, but as my combat-techs were still relatively poor - at that point I had relatively few cities and a lack of space.

Most of the cities were size 3 or 4 for most of the game, but producing well with a mixture of specialists (teching toward Guilds would have allowed better specialist production - but again, Doviello tend to skimp on that branch). The lack of library reduced the potential for sages, so most ran priest-sage-engineer using Elder Council, Pagan Temple and Forge. After the druids came through, the cities did become much more powerful, but the amount of tundra on the map was small enough that relatively few of these cities could be produced. It didn't feel overpowered, at least when compared to some of the other "power-combinations" (Elves and Fellowship in a forest city etc). The great-person production was nice for a while, but the diminishing returns meant that it self-regulated to an extent.

But that's based off of one game's worth of testing - if you decide to play through with them, let me know how they work. Any suggestions and comments will be appreciated.

Vehem
Feb 10, 2008, 01:57 PM
Hmm, if I just modified a few C++ files...

As an afterthought - if you just want to merge an existing DLL-mod with another and you can point me in the direction of the source files for each, I can recompile them together for you easily enough (provided they don't conflict horribly) and just give you the DLL...?

Really only an option for existing DLL-mods however, as if you can't compile your code, there's not really anyway for you to make sure your changes work before sending them to be compiled.

xienwolf
Feb 10, 2008, 02:53 PM
Here is UnitStats (http://forums.civfanatics.com/showthread.php?t=261642) that he bases off of for next release, and here is the Random Event fix (http://forums.civfanatics.com/showthread.php?t=260419) that I want him to incorporate (DLL actually uploaded in post 15).

MagisterCultuum
Feb 10, 2008, 03:54 PM
I don' think that UnitStats actually uses a different compiled .dll, since the files are found uncompiled in a SDK file. I could probably combine these alright on my own, but feel free to do it for me if you want.

I don't really want to have a whole new .dll, at least this soon, since it would make my overall modmod much larger (quite possibly so large I'd need to find a host like gameflood, instead of being able to just upload a zip of it to my account here); including only the needed uncompiled files seems fine. Also, I thought I was following Kael's instructions to the letter when I tried compiling the .dll, but perhaps I missed something (the error seems related to EHsc or /EHsc)

I also tried to allow HN units to capture other units (but still not cities) by commenting out the code in CvUnit.cpp that seemed to handle it, but none of the 3 sections of code that looked like they might be responsible for this made any difference when I commented them out. I want HN units belong to civs running slavery to be able to capture slaves without declaring their identity or going to war, and for HN giant spiders and werewolves to still spawn ravenous werewolves and baby spiders, respectively. I also want these captured/spawned units to get the HN promotion if the unit that made them had it. I also want the summons of HN summoners to have this status though the promotion instead of as an intrinsic quality of the unit (I can easily make the promotion grant itself to summons using only XML, but without changing some C++ they would still be HN once they declared nationality)

Also, I'm planning on implementing weapons promotions differently, where they are handled though spells and have different strengths, weaknesses, requirements, and gold costs (although I am a little concerned about this slowing down the game, and more importantly, about the AI never giving their units weapons). The main barrier to this is that the weapons promotions are still being granted in the SDK. I could probably just change the defines in GlobalDefinesAlt.xml, but I think I'd rather have the C++ code commented out too so that it doesn't run checks it doesn't have to do.


Also, I'd like it if the elven civs could clear jungles (their inability to clear forests and ability to build on top of them currently applies to all features, I believe), and if Orcs could build on Jungles without needing to clear them/needing Sanitation.

Combining all of these would be appreciated.

Vehem
Feb 10, 2008, 04:14 PM
Here is UnitStats (http://forums.civfanatics.com/showthread.php?t=261642) that he bases off of for next release, and here is the Random Event fix (http://forums.civfanatics.com/showthread.php?t=260419) that I want him to incorporate (DLL actually uploaded in post 15).

Done. Used the source as provided, with the exception of the Random Event fix where I also added the exact same fix to "PickTriggerCity" .

The DLL now contains the changes from IceHouse, UnitStats and the PickTrigger fix.

The testing I have done is limited to (a) Loading Civ4 (b) Starting a game and (c) Holding down Shift-Enter for 100 turns to check for any obvious instability. So far all looks fine.

Disclaimer: Vehem accepts no responsibility for the performance of the code provided and assumes it was all working to begin with. In the event of fire, the DLL should not be applied directly to the flame. Keep out of direct sunlight. Do not taunt the happy fun ball. Phone your mother, she misses you.

[Download Here] (http://forums.civfanatics.com/uploads/71205/Magister_Mod_-_CvGameCoreDLL.rar)

Vehem
Feb 10, 2008, 04:20 PM
I don' think that UnitStats actually uses a different compiled .dll, since the files are found uncompiled in a SDK file. I could probably combine these alright on my own, but feel free to do it for me if you want.

It does have one, and the uncompiled .cpp and .h files will do nothing on their own. It's a fairly easy merge once you've managed to convince a compiler to do its thing, but as you've probably found out - that's the real trick. If you get it working once, you're probably set for life.

The DLL also compresses to less than 1MB as a RAR and about 1.5MB as a ZIP - it's not going to bankrupt the bandwidth for now.

MagisterCultuum
Feb 10, 2008, 04:26 PM
Hmm. That file is smaller than I expected, less than a megabyte compressed and less than 5 uncompressed. I may go ahead and include the compressed form with my modmod. I guess it is Pak0.FPK, not CvGameCoreDLL.dll that makes the game so big. I certainly don't plan to include a whole new custom Pak0.FPK (especially since I have better examples of how to just put the art files in uncompressed, and can in fact can borrow entire units straight from AoI, which doesn;t use a Pak0.FPK at all)

I'd like it much better if you could allow HN units to capture/spawn other units (and the other changes I requesting in my last post) but this is good for now.

Thank you!


So far, it almost looks like this thread would be better called "Magister Modmod SDK development." Ignoring the one post by it-ogo, it would appear to be a private development thread for the team of my modmod (assuming such a team existed)

xienwolf
Feb 10, 2008, 05:53 PM
Can we get our own Magi-Mod subforum in the Maps & Scenarios subform of the FfH subforum of the....

Nested folders are a blast :P


While speaking of compilling the DLL though, where does it put the thing? As I read through Kael's post it sounded like it will place it right where the current DLL is, which would mean I sure better make a backup before I make my first attempt (and failure) at compiling my own.

MagisterCultuum
Feb 10, 2008, 06:06 PM
Yeah, I'm pretty sure it goes in the same place. I'd just move the old .dll to a new folder first.

I'm using the .dll now, but I think I made a mistake in the xml or forgot to write a python prereq so I couldn't test the new spells. I added the Icehouse in worldbuilder, but hadn't gotten into a position to see if it was working. The game worked fine for about 30 turns (it actually seemed to run faster than normal), but them I had a CTD.

I'd forgotten to turn on debugging (actually, I'd deleted the old .ini and was waiting for it to make a new one), so I'm not sure if it would have revealed a python or C++ bug. I added pyPerturn python defines to several promotions which may have been the problem, or it could have been that it was time for an event, or some problem with the cannot grow function (I think the city was just reaching size 3, and it had an ice house, so it would ave to start comparing the amount of ice mana and the size of the city, although it shouldn't have actually done anything yet. I suspect the problem was the pyPerTurn function for the tutor promotion (I had given this to the archmage I gave myself in worldbuilder), which I wrote rather hurriedly and was planning to revise.

echinococcus
Feb 10, 2008, 06:20 PM
Excellent. Will the AI understand to use this though?

MagisterCultuum
Feb 10, 2008, 07:37 PM
I just had a CTD again, and this time I'm fairly sure it was from the Icehouse; it happened as soon as I cast "icehouse" in a size city that I had just made go into starvation by making none of its citizens work any tiles. The problem might be in the code you added to the SDK.

here is the code I added to CvUtils.py:


def cannotGrow(self,argsList):
pCity = argsList[0]
if pCity.getNumRealBuilding(gc.getInfoTypeForString(' BUILDING_ICEHOUSE')) > 0:
if pCity.getNumBonuses(gc.getInfoTypeForString('BONUS _MANA_ICE')) *4 > pCity.getPopulation():
return True
return False

def cannotStarve(self,argsList):
pCity = argsList[0]
if pCity.getNumRealBuilding(gc.getInfoTypeForString(' BUILDING_ICEHOUSE')) > 0:
if pCity.getNumBonuses(gc.getInfoTypeForString('BONUS _MANA_ICE')) > 4 * pCity.getPopulation():
return True
return False



Edit: It happened again as soon as casting the spell, this time when the city was not starving (it was 3 turns away from growing)

xienwolf
Feb 10, 2008, 08:23 PM
When you are testing for instability, you ought to go into the BtS Global Defines and set the Event Roll to an insanely high number to block out events, or to 2 to test for problems with them. Nice quick way to toggle them on/off. Just search for _ROLL twice and it hits you at the right entry :)

MagisterCultuum
Feb 10, 2008, 10:29 PM
I don't get it. I commented out the only python code dealing with the Icehouse, and it still isn't working. I guess this means that veham is off the hook, his .dll doesn't seem relevant.


I don't get it. I copied the icehouse spell code (pure xml) from the another building granting spell that is working fine. Why does this spell cause a crash?

Edit: I found the problem. It is always something stupid, isn't it. I had changed the name of the building's art file without creating such a file (I copied the smokehouse xml, then replaced smokehouse with icehouse everywere I saw it). It is working fine now. It seems vehem's .dll did not cause the crash, now lets see if it actually works.

Vehem
Feb 11, 2008, 02:18 AM
Edit: I found the problem. It is always something stupid, isn't it. I had changed the name of the building's art file without creating such a file

Heh - the sections of the code that handle the artwork are notoriously poor for their error-tolerance. If it gets anything that it doesn't expect, it just falls over without any indication of why. If I get a CtD, the artwork is always the first suspect.

While speaking of compilling the DLL though, where does it put the thing? As I read through Kael's post it sounded like it will place it right where the current DLL is, which would mean I sure better make a backup before I make my first attempt (and failure) at compiling my own.

Depending on the compiler, either you set the target directory yourself or it will default to a sub directory of where you have the source-code. In the case of CodeBlocks (assuming the source directory is \FFH030hSource) it puts it in \FFH30hSource\FinalRelease\.

Final Release is the build-type you want for the released DLL. You can also build Debug versions that include other "Debug Symbols" which may be useful for testing, though I haven't had to use those with FFH so far. "Final Release" is generally better optimized and so a smaller filesize/quicker performance.

==

The final DLL does have to replace the one in FFH\Assets though, so a backup is a good plan anyway. I've actually made a backup of the whole Patch-h directory so I can revert any given file to the official version. Also, if you can get it working, a source versioning package (like GIT) is pretty damned useful. Every change that you make to the mod is tracked, can be reverted or merged and the files involved are listed as .diffs (I used it to produce the DIFF's in my first post).

xienwolf
Feb 11, 2008, 07:22 AM
Nice, something to track my changes for me is a dream come true ;) I am horrible at documenting my work, generally anything I remember to write down is doomed to be removed quickly.

Xenomorph
Apr 08, 2008, 03:10 PM
Could someone reupload this? And would anyone be willing to make this a standalone modcomp that can be integrated into BtS?

Vehem
Apr 08, 2008, 04:54 PM
Could someone reupload this? And would anyone be willing to make this a standalone modcomp that can be integrated into BtS?

Which part of it are you after? The Python/XML components are erm... somewhere around here - just not anywhere I can lay hands on them quickly. The useful part though is the DLL changes and those are available in the other thread (though as part of a FFH DLL).

Also - what would the BtS modcomp do? This was specific to the FfH races and relied on terrain types. It is possible to limit the population increase/decrease using any set of factors that you can write python code to describe..

Xenomorph
Apr 08, 2008, 10:13 PM
I was interested in making this a "national wonder" kind of building in my mod, so the python and SDK changes were the main thing I was after (and any changes that have to be made in the XML for all that to work with the assigned building).

MagisterCultuum
Apr 08, 2008, 10:36 PM
Those changes can be copied and pasted from within the spoilers on the first post into the appropriate python files and file in the uncompiled BtS dll

Vehem
Apr 09, 2008, 07:52 AM
I was interested in making this a "national wonder" kind of building in my mod, so the python and SDK changes were the main thing I was after (and any changes that have to be made in the XML for all that to work with the assigned building).

As Magister said, if you can compile the DLL already, the changes are listed in the first post. The Python would need adjusting to refer to your National Wonder rather than "BUILDING_ICEHOUSE" and you can remove any reference to the terrain types.

If you can't compile the DLL, let me know and I'll either try to help you through it or can recompile a one off version with this change in it.

Xenomorph
Apr 09, 2008, 10:36 PM
As Magister said, if you can compile the DLL already, the changes are listed in the first post. The Python would need adjusting to refer to your National Wonder rather than "BUILDING_ICEHOUSE" and you can remove any reference to the terrain types.
Well, I still want it to only work when there's tundra nearby. I've managed to get the SDK and python code inserted, thanks for pointing out the spoiler stuff. I don't suppose you would happen to know how to prevent the building from being built in the first place if the city isn't built within range of the tundra, would you?

MagisterCultuum
Apr 09, 2008, 10:44 PM
I would probably just put a python block in the def cannotConstruct(self,argsList): define of CvGaneUtils.py, similar to how the Shrine of the Champion works, but of course with different requirements (checking the terrain type of pCity.plot(), and maybe other tiles nearby)

Vehem
Apr 10, 2008, 04:15 AM
Well, I still want it to only work when there's tundra nearby. I've managed to get the SDK and python code inserted, thanks for pointing out the spoiler stuff. I don't suppose you would happen to know how to prevent the building from being built in the first place if the city isn't built within range of the tundra, would you?

As Magister said - "CannotConstruct" is the easiest way and already exists in Python. You can make it such that you must have Tundra in the city square (quite cheap processorwise) or a do a search over nearby tiles (which is more expensive given the code is run a fair bit).

Xenomorph
Apr 11, 2008, 12:09 AM
I'm trying to model this after the Machu Picchu mod, but I'm having trouble finding the correct function of pPlot to use. I've highlighted the part that I'm pretty sure I have wrong.

if ( eBuilding == gc.getInfoTypeForString("BUILDING_ICEHOUSE") ):

### find taiga within the city radius controlled by your team ###
pPlayer = gc.getPlayer(pCity.plot().getOwner())
iPID = pPlayer.getID()
iTID = pPlayer.getTeam()
iX = pCity.getX()
iY = pCity.getY()
for iXLoop in range(iX - 2, iX + 3, 1):
for iYLoop in range(iY - 2, iY + 3, 1):
pPlot = CyMap().plot(iXLoop, iYLoop)
if ( pPlot.isPlayerCityRadius(iPID)==true ):
if ( pPlot.getTeam()==iTID ):
if ( pPlot.isTundra()==true ):
return False
return True

Vehem
Apr 11, 2008, 04:55 AM
I'm trying to model this after the Machu Picchu mod, but I'm having trouble finding the correct function of pPlot to use. I've highlighted the part that I'm pretty sure I have wrong.

if ( eBuilding == gc.getInfoTypeForString("BUILDING_ICEHOUSE") ):

### find taiga within the city radius controlled by your team ###
pPlayer = gc.getPlayer(pCity.plot().getOwner())
iPID = pPlayer.getID()
iTID = pPlayer.getTeam()
iX = pCity.getX()
iY = pCity.getY()
for iXLoop in range(iX - 2, iX + 3, 1):
for iYLoop in range(iY - 2, iY + 3, 1):
pPlot = CyMap().plot(iXLoop, iYLoop)
if ( pPlot.isPlayerCityRadius(iPID)==true ):
if ( pPlot.getTeam()==iTID ):
if ( pPlot.isTundra()==true ):
return False
return True


pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_TUNDRA')

getTerrainType returns an integer value that represents the Terrain Type.
getInfoTypeForString finds the integer value that has been assigned to the "Info" with the XML-name "TERRAIN_TUNDRA".

If they're the same, the plot is TERRAIN_TUNDRA.

====

The same is true of pPlot.getFeatureType() and pPlot.getImprovementType() (gc.getInfoTypeForString('FEATURE_FOREST') and gc.getInfoTypeForString('IMPROVEMENT_FARM') respectively).

====

The only "isSomething" methods that pPlot has (related to the actual map rather than the game) are
bool isWater ()
bool isFlatlands ()
bool isHills ()
bool isPeak ()

Xenomorph
Apr 11, 2008, 10:28 AM
Ah, Ok. So, using that, would I be correct with this code?
if ( eBuilding == gc.getInfoTypeForString("BUILDING_ICEHOUSE") ):

### find taiga within the city radius controlled by your team ###
pPlayer = gc.getPlayer(pCity.plot().getOwner())
iPID = pPlayer.getID()
iTID = pPlayer.getTeam()
iX = pCity.getX()
iY = pCity.getY()
for iXLoop in range(iX - 2, iX + 3, 1):
for iYLoop in range(iY - 2, iY + 3, 1):
pPlot = CyMap().plot(iXLoop, iYLoop)
if ( pPlot.isPlayerCityRadius(iPID)==true ):
if ( pPlot.getTeam()==iTID ):
if ( pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_TUNDRA' ):
return False
return True

And thanks for all the assistance you've been providing. :)

Vehem
Apr 11, 2008, 11:02 AM
Ah, Ok. So, using that, would I be correct with this code?

And thanks for all the assistance you've been providing. :)

Looks like it should work, though I'd be tempted to use

if (pCity.canWork(pPlot)):

instead of

if ( pPlot.isPlayerCityRadius(iPID)==true ):
if ( pPlot.getTeam()==iTID ):


as if I remember correctly, "canWork()" requires that it be (a) in the city radius and (b) accessible to your team. I suspect either would work fine.

EDIT: Hmm - seems that "canWork()" may also rely on not being under siege by an enemy. The original way may be better depending on how you want it to behave.

Xenomorph
Apr 14, 2008, 03:14 PM
Damn, it seems my code causes an OOS error in multiplayer. Any idea how to get around this?

Vehem
Apr 14, 2008, 03:49 PM
Damn, it seems my code causes an OOS error in multiplayer. Any idea how to get around this?

Whereabouts is it placed? In CannotBuild()? If so, I'm not really sure how it can be causing a problem as all it does is check a set of conditions and returns True/False (doesn't change the gamestate itself).

The only thing that may be an issue is when pPlot is not a valid plot (the iX or iY that it's checking is too high/low for the map), but I'd expect that to be a Python error rather than a OoS.

EDIT: Or is this part of your CannotStarve() function?

Xenomorph
Apr 14, 2008, 09:56 PM
Whereabouts is it placed? In CannotBuild()? If so, I'm not really sure how it can be causing a problem as all it does is check a set of conditions and returns True/False (doesn't change the gamestate itself).

It's part of the cannotConstruct() function, does that make that much of a difference? We get the error as soon as it is possible to build the structure (i.e. get the tech that allows it). I've included the version of CvGameUtils.py that I am using.

Vehem
Apr 15, 2008, 02:44 AM
It's part of the cannotConstruct() function, does that make that much of a difference? We get the error as soon as it is possible to build the structure (i.e. get the tech that allows it). I've included the version of CvGameUtils.py that I am using.


Not sure how this would cause an OoS, but it's worth trying anyway (and needs to be done to avoid possible problems elsewhere)

### find taiga within the city radius controlled by your team ###
pPlayer = gc.getPlayer(pCity.plot().getOwner())
iPID = pPlayer.getID()
iTID = pPlayer.getTeam()
iX = pCity.getX()
iY = pCity.getY()
for iXLoop in range(iX - 2, iX + 3, 1):
for iYLoop in range(iY - 2, iY + 3, 1):
pPlot = CyMap().plot(iXLoop, iYLoop)
if pPlot.isNone() == False:
if ( pPlot.isPlayerCityRadius(iPID)==true ):
if ( pPlot.getTeam()==iTID ):
if ( pPlot.getTerrainType() == gc.getInfoTypeForString('TERRAIN_TUNDRA') ):
return False

This will deal with the cases that pPlot is "off the map"/null.

===

The other thing worth trying is to remove each of the last 3 if conditions in turn (The Tundra Check - which should be fine, then the Team Check - more likely, then the PlayerCityRadius check - again, possible) to see which is causing the OoS.

It's an odd one though, as I've never come across an OoS caused by anything that doesn't alter the gamestate directly.

Xenomorph
Apr 17, 2008, 12:11 AM
After further testing, I've confirmed that you are right. The problem arises when the building is actually built. It would seem that because I forgot to set the AdvancedStartCost to -1, the AI was building it. :p

Vehem
Apr 17, 2008, 04:00 AM
After further testing, I've confirmed that you are right. The problem arises when the building is actually built. It would seem that because I forgot to set the AdvancedStartCost to -1, the AI was building it. :p

Pesky AI's :)

Good luck with the rest of this - I'll keep an eye out for the release - sounds interesting :)

Xenomorph
Apr 17, 2008, 04:18 PM
Well, that's the thing. I have only figured out that building it causes the OOS, not how to prevent it. From my understanding, OOS's like this are usually caused in Python, and seeing how my python skills are lackluster, I really don't know how to fix it.

Vehem
Apr 17, 2008, 04:55 PM
Well, that's the thing. I have only figured out that building it causes the OOS, not how to prevent it. From my understanding, OOS's like this are usually caused in Python, and seeing how my python skills are lackluster, I really don't know how to fix it.

If both players have the same Python and DLL, I'm struggling to see how it can cause an OoS. If one player didn't have the DLL, it almost certainly would (likewise if both didn't have the python) - but in that case it likely wouldn't allow you to start a game either.