[BNW] Broke my buildings xml

DrSpongey

Chieftain
Joined
Oct 22, 2020
Messages
2
Hi, I'm currently making my first mod for civ5 (or any other civ for that matter). My goal is to add eight new civs, which was going very well. Unfortunately, when adding the most recent of them (Alarm Wood), I must have broken something, because not only is Alarm Woods' unique building not functioning, but all the buildings in the mod are no longer appearing. I've been struggling to find whatever I did for six hours- I took out everything I knew I'd changed when adding Alarm Woods and it's still broken, so I put it back in. It's 2am now, I have work tomorrow morning, and I'm distraught. If anyone with more experience can spot what's broken, I would be extremely grateful. I am operating solely in xml. I'll attach the mod file below.
 

Attachments

Undefined BuildingClass BUILDINGCLASS_TUNGI. This will generally cause the game to CTD during the dawn of man screens, but the fatal syntax errors elsewhere in the Buildings file are "covering" this error.

Table Civilization_BuildingClassOverrides has no column called MaxPlayerInstances. This is a fatal syntax error which results in the game rejecting the entire contents of the XML file.

Duplicate Columns
Code:
		<Row>
			<Type>BUILDING_BOBSERVATORY</Type>
			<BuildingClass>BUILDINGCLASS_OBSERVATORY</BuildingClass>
			<Cost>200</Cost>
			<Description>TXT_KEY_BUILDING_BOBSERVATORY</Description>
			<Civilopedia>TXT_KEY_CIV5_BUILDINGS_OBSERVATORY_TEXT</Civilopedia>
			<Strategy>TXT_KEY_BUILDING_BOBSERVATORY_HELP</Strategy>
			<Help>TXT_KEY_BUILDING_BOBSERVATORY_HELP</Help>
			<EnhancedYieldTech>TECH_POTTERY</EnhancedYieldTech>
			<ArtDefineTag>ART_DEF_BUILDING_OBSERVATORY</ArtDefineTag>
			<MinAreaSize>-1</MinAreaSize>
			<EnhancedYieldTech>TECH_ASTRONOMY</EnhancedYieldTech>
			<ConquestProb>66</ConquestProb>
			<HurryCostModifier>15</HurryCostModifier>
			<IconAtlas>BW_ATLAS_1</IconAtlas>
			<PortraitIndex>42</PortraitIndex>
		</Row>
EnhancedYieldTech twice in the same Row statement. Duplicate columns is a fatal syntax error which results in the game rejecting the entire contents of the XML file.

No Default Buildings specified for the Building Class in both cases, which generally will lead to CTD at some point during gameplay
Code:
	<BuildingClasses>
		<Row>
			<Type>BUILDINGCLASS_COTTAGE</Type>
			<Description>TXT_KEY_BUILDING_COTTAGE</Description>
		</Row>
		<Row>
			<Type>BUILDINGCLASS_FRIAR</Type>
			<Description>TXT_KEY_BUILDING_FRIAR</Description>
		</Row>
		</BuildingClasses>

See this tutorial and follow the instructions on enabling the game's built-in error logging system: whoward69's enable error logging tutorial
 
No Default Buildings specified for the Building Class in both cases, which generally will lead to CTD at some point during gameplay

Not true; it will just make them unbuildable except for civs for which the nonexistent default building is overwritten with a building that isn't nonexistent, which is a handy way to make a UB that "doesn't replace anything".
 
Thank you (both) so much, my headache has been lifted. And thank you for the link to the tutorial on error logging- I'm sure that will shorten the next headache. For all my belly-aching, I'm loving modding!
 
Not true; it will just make them unbuildable except for civs for which the nonexistent default building is overwritten with a building that isn't nonexistent, which is a handy way to make a UB that "doesn't replace anything".
I suppose you could quibble with the word "generally" in my previous post (but given my experience with buildings code I will stand by the word usage), but there are game-tables / columns wherein the game first looks up the default building from within the class, even when the given data is not a Building-Class but rather a BuildingType. If no DefaultBuilding is stated for that BuildingClass, the result in such cases is always CTD.

Even in the case of Dummy Buildings it is better to always provide a DefaultBuilding for the BuildingClass, and in this specific usage the Dummy should always be the Default within its class.

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

And to do what you are after it is far better in my opinion to give the UB that does not replace anything as the Default Building within its BuildingClass and then disable it for all other players with an lua script.
Code:
local iBuildingType = GameInfoTypes.BUILDING_CHESSEBURGER
local iRequiredCiv = GameInfoTypes.CIVILIZATION_X
function PlayerCanBuildCheeseburgers(iPlayer, BuildingType)
	if (BuildingType == iBuildingType) then
		return (Players[iPlayer]:GetCivilizationType() == iRequiredCiv)
	end
	return true
end
GameEvents.PlayerCanConstruct.Add(PlayerCanBuildCheeseburgers)
 
Last edited:
We can also do like this:

SQL code
Code:
CREATE TABLE IF NOT EXISTS 
	NonReplacerUniqueBuildings (
	BuildingType		TEXT REFERENCES Buildings(Type) NOT NULL,
	CivilizationType	TEXT REFERENCES Civilizations(Type) NOT NULL );

INSERT INTO NonReplacerUniqueBuildings (BuildingType, CivilizationType) VALUES ('BUILDING_CHESSEBURGER', 'CIVILIZATION_X');
Lua code
Code:
local tNonReplacerUniqueBuildings = {}
for row in GameInfo.NonReplacerUniqueBuildings() do
	tNonReplacerUniqueBuildings[GameInfoTypes[row.BuildingType]] = GameInfoTypes[row.CivilizationType]
end
function PlayerCanBuildBuildings(iPlayer, BuildingType)
	if tNonReplacerUniqueBuildings[BuildingType] then
		return (Players[iPlayer]:GetCivilizationType() == tNonReplacerUniqueBuildings[BuildingType])
	end
	return true
end
GameEvents.PlayerCanConstruct.Add(PlayerCanBuildBuildings)
  1. It doesn't matter how many different Building/Civilization combinations we add to the SQL table, the lua code will handle them all.
  2. It does not matter how many different mods we make using the same lua code because once the first lua script returns a boolean false, the game will no longer querry any of the other lua scripts that may contain the same code -- once false is returned by any lua script, the game enacts that false value and does not look further into other lua PlayerCanConstruct functions for that particular building.
  3. Using a CREATE TABLE IF NOT EXISTS method in SQL means that once one mod adds the new table to the game, all other mods using the same table will not attempt to add it again, and all the INSERT INTO commands will operate on the same database table regardless of the number of mods that are writing data to the new Database table.
 
Back
Top Bottom