diff --git a/src/js/economyJS.js b/src/js/economyJS.js
index a6e9b76205442ddeaa7d30dae1acddfb548e8af2..ce667235c7ff3bb19fb6db825c75a5926135dff9 100644
--- a/src/js/economyJS.js
+++ b/src/js/economyJS.js
@@ -38,9 +38,15 @@ window.PersonalAttention = Object.freeze({
 	HACKING: 'hacking'
 });
 
-window.predictCost = function() {
-	let totalCosts = (
-		getBrothelCosts() +
+window.calculateCosts = (function() {
+	return {
+		predict: predictCost,
+		bill: getCost,
+	};
+
+	function predictCost() {
+		let totalCosts = (
+			getBrothelCosts() +
 	getBrothelAdsCosts() +
 	getArcadeCosts() +
 	getClubCosts() +
@@ -66,512 +72,481 @@ window.predictCost = function() {
 	getPCTrainingCosts() +
 	getPCCosts() +
 	predictTotalSlaveCosts()
-	);
-
-	// these two apply a multiplicative effect to all costs so far.
-	totalCosts = getEnvironmentCosts(totalCosts);
-	totalCosts = getPCMultiplierCosts(totalCosts);
-
-	// in the old order these were applied after multiplication. Not sure if deliberate, but I'm leaving it for now.
-	totalCosts += (
-		getSFCosts() +
-		getWeatherCosts()
-	);
-	/*
-	// clean up
-	if (totalCosts > 0) {
-		totalCosts = 0;
-	} else {
-		totalCosts = Math.ceil(totalCosts);
+		);
+
+		// these two apply a multiplicative effect to all costs so far.
+		totalCosts = getEnvironmentCosts(totalCosts);
+		totalCosts = getPCMultiplierCosts(totalCosts);
+
+		// in the old order these were applied after multiplication. Not sure if deliberate, but I'm leaving it for now.
+		totalCosts += getSFCosts() + getWeatherCosts();
+		/*
+		// clean up
+		if (totalCosts > 0) {
+			totalCosts = 0;
+		} else {
+			totalCosts = Math.ceil(totalCosts);
+		}
+		*/
+		return totalCosts;
+	}
+
+	function getCost() {
+		const oldCash = State.variables.cash;
+		cashX(forceNeg(getBrothelCosts()), "brothel");
+		cashX(forceNeg(getBrothelAdsCosts()), "brothelAds");
+		cashX(forceNeg(getArcadeCosts()), "arcade");
+		cashX(forceNeg(getClubCosts()), "club");
+		cashX(forceNeg(getClubAdsCosts()), "brothelAds");
+		cashX(forceNeg(getDairyCosts()), "dairy");
+		cashX(forceNeg(getIncubatorCosts()), "incubator");
+		cashX(forceNeg(getServantsQuartersCosts()), "servantsQuarters");
+		cashX(forceNeg(getMasterSuiteCosts()), "masterSuite");
+		cashX(forceNeg(getNurseryCosts()), "nursery");
+		cashX(forceNeg(getFarmyardCosts()), "farmyard");
+		cashX(forceNeg(getSecurityExpansionCost()), "securityExpansion");
+		cashX(forceNeg(getLifestyleCosts()), "personalLivingExpenses");
+		cashX(forceNeg(getFSCosts()), "futureSocieties");
+		cashX(forceNeg(getCitizenOrphanageCosts()), "citizenOrphanage");
+		cashX(forceNeg(getPrivateOrphanageCosts()), "privateOrphanage");
+		cashX(forceNeg(getPeacekeeperCosts()), "peacekeepers");
+		cashX(forceNeg(getMercenariesCosts()), "mercenaries");
+		cashX(forceNeg(getMenialRetirementCosts()), "menialRetirement");
+		cashX(forceNeg(getRecruiterCosts()), "recruiter");
+		cashX(forceNeg(getSchoolCosts()), "schoolBacking");
+		cashX(forceNeg(getPolicyCosts()), "policies");
+		cashX(forceNeg(getProstheticsCosts()), "lab");
+		cashX(forceNeg(getPCTrainingCosts()), "PCtraining");
+		cashX(forceNeg(getPCCosts()), "PCmedical");
+		getTotalSlaveCosts();
+
+
+		// these two apply a multiplicative effect to all costs so far.
+		// Calculate what the deduced expenses would be, then subtract
+		let costSoFar = (oldCash - State.variables.cash); // How much we have spent by this point; expected to be positive.
+		cashX(costSoFar - getEnvironmentCosts(costSoFar), "environment"); // getEnv takes total costs and makes it worse. Figure out how much worse and record it
+
+		costSoFar = (oldCash - State.variables.cash);
+		cashX(costSoFar - getPCMultiplierCosts(costSoFar), "PCskills");
+
+		// in the old order these were applied after multiplication. Not sure if deliberate, but I'm leaving it for now.
+		cashX(forceNeg(getSFCosts()), "specialForces");
+		cashX(forceNeg(getWeatherCosts()), "weather");
+		return (oldCash - State.variables.cash);
 	}
-*/
-	return totalCosts;
-};
 
-window.getCost = function() {
-	const oldCash = State.variables.cash;
-	let costSoFar = 0;
-	cashX(forceNeg(getBrothelCosts()), "brothel");
-	cashX(forceNeg(getBrothelAdsCosts()), "brothelAds");
-	cashX(forceNeg(getArcadeCosts()), "arcade");
-	cashX(forceNeg(getClubCosts()), "club");
-	cashX(forceNeg(getClubAdsCosts()), "brothelAds");
-	cashX(forceNeg(getDairyCosts()), "dairy");
-	cashX(forceNeg(getIncubatorCosts()), "incubator");
-	cashX(forceNeg(getServantsQuartersCosts()), "servantsQuarters");
-	cashX(forceNeg(getMasterSuiteCosts()), "masterSuite");
-	cashX(forceNeg(getNurseryCosts()), "nursery");
-	cashX(forceNeg(getFarmyardCosts()), "farmyard");
-	cashX(forceNeg(getSecurityExpansionCost()), "securityExpansion");
-	cashX(forceNeg(getLifestyleCosts()), "personalLivingExpenses");
-	cashX(forceNeg(getFSCosts()), "futureSocieties");
-	cashX(forceNeg(getCitizenOrphanageCosts()), "citizenOrphanage");
-	cashX(forceNeg(getPrivateOrphanageCosts()), "privateOrphanage");
-	cashX(forceNeg(getPeacekeeperCosts()), "peacekeepers");
-	cashX(forceNeg(getMercenariesCosts()), "mercenaries");
-	cashX(forceNeg(getMenialRetirementCosts()), "menialRetirement");
-	cashX(forceNeg(getRecruiterCosts()), "recruiter");
-	cashX(forceNeg(getSchoolCosts()), "schoolBacking");
-	cashX(forceNeg(getPolicyCosts()), "policies");
-	cashX(forceNeg(getProstheticsCosts()), "lab");
-	cashX(forceNeg(getPCTrainingCosts()), "PCtraining");
-	cashX(forceNeg(getPCCosts()), "PCmedical");
-	getTotalSlaveCosts();
-
-
-	// these two apply a multiplicative effect to all costs so far.
-	// Calculate what the deduced expenses would be, then subtract
-	costSoFar = (oldCash - State.variables.cash); // How much we have spent by this point; expected to be positive.
-	cashX(costSoFar - getEnvironmentCosts(costSoFar), "environment"); // getEnv takes total costs and makes it worse. Figure out how much worse and record it
-
-	costSoFar = (oldCash - State.variables.cash);
-	cashX(costSoFar - getPCMultiplierCosts(costSoFar), "PCskills");
-
-	// in the old order these were applied after multiplication. Not sure if deliberate, but I'm leaving it for now.
-	cashX(forceNeg(getSFCosts()), "specialForces");
-	cashX(forceNeg(getWeatherCosts()), "weather");
-	return (oldCash - State.variables.cash);
-};
-
-// slave expenses
-window.predictTotalSlaveCosts = function() {
-	let loopCosts = 0;
 	// slave expenses
-	for (const slave of State.variables.slaves) {
-		loopCosts += getSlaveCost(slave);
-		loopCosts += getSlaveMinorCosts(slave);
+	function predictTotalSlaveCosts() {
+		let loopCosts = 0;
+		for (const slave of State.variables.slaves) {
+			loopCosts += getSlaveCost(slave);
+			loopCosts += getSlaveMinorCosts(slave);
+		}
+		return loopCosts;
 	}
-	return loopCosts;
-};
 
-window.getTotalSlaveCosts = function() {
-	let slaveCost = 0;
-	let slaveCostMinor = 0;
-	for (const slave of State.variables.slaves) {
-		slaveCost = getSlaveCost(slave);
-		cashX(forceNeg(slaveCost), "slaveUpkeep", slave);
-		slaveCostMinor = getSlaveMinorCosts(slave);
-		cashX(Math.abs(slaveCostMinor), "houseServant", slave);
-	}
+	function getTotalSlaveCosts() {
+		let slaveCost = 0;
+		let slaveCostMinor = 0;
+		for (const slave of State.variables.slaves) {
+			slaveCost = getSlaveCost(slave);
+			cashX(forceNeg(slaveCost), "slaveUpkeep", slave);
+			slaveCostMinor = getSlaveMinorCosts(slave);
+			cashX(Math.abs(slaveCostMinor), "houseServant", slave);
+		}
 	// nothing to return, cashX already billed.
-};
-
-// facility expenses
-window.getBrothelCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const brothel = State.variables.brothel;
-	let costs = (brothel * facilityCost);
-	costs += (0.1 * State.variables.brothelUpgradeDrugs * brothel * facilityCost);
-	return costs;
-};
+	}
 
-window.getBrothelAdsCosts = function() {
-	const brothel = State.variables.brothel;
-	let costs = 0;
-	if (brothel > 0) {
-		costs += State.variables.brothelAdsSpending;
+	// facility expenses
+	function getBrothelCosts() {
+		const V = State.variables;
+		return (1 + 0.1 * V.brothelUpgradeDrugs) * (V.brothel * V.facilityCost);
 	}
-	return costs;
-};
 
-window.getArcadeCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const arcade = State.variables.arcade;
-	let costs = (arcade * facilityCost * 0.05);
-	costs += (0.02 * State.variables.arcadeUpgradeInjectors * arcade * facilityCost) + (0.05 * State.variables.arcadeUpgradeCollectors * arcade * facilityCost) + (0.02 * State.variables.arcadeUpgradeHealth * arcade * facilityCost);
-	return costs;
-};
+	function getBrothelAdsCosts() {
+		return (State.variables.brothel > 0) ? State.variables.brothelAdsSpending : 0;
+	}
 
-window.getClubCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const club = State.variables.club;
-	let costs = (club * facilityCost);
-	costs += (0.2 * State.variables.clubUpgradePDAs * club * facilityCost);
-	if (club > 0) {
-		costs += State.variables.clubAdsSpending;
+	function getArcadeCosts() {
+		const V = State.variables;
+		return (0.05 + 0.02 * V.arcadeUpgradeInjectors + 0.05 * V.arcadeUpgradeCollectors + 0.02 * V.arcadeUpgradeHealth) * (V.arcade + V.facilityCost);
 	}
-	return costs;
-};
 
-window.getClubAdsCosts = function() {
-	const club = State.variables.club;
-	let costs = 0;
-	if (club > 0) {
-		costs += State.variables.clubAdsSpending;
+	function getClubCosts() {
+		const V = State.variables;
+		const initCosts = (V.club * V.facilityCost) + (0.2 * V.clubUpgradePDAs * V.club * V.facilityCost);
+		return (V.club > 0) ? initCosts + V.clubAdsSpending : initCosts;
 	}
-	return costs;
-};
 
-window.getDairyCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const dairy = State.variables.dairy;
-	let costs = (dairy * facilityCost) + (0.2 * State.variables.dairyFeedersUpgrade * dairy * facilityCost) +
-		(0.1 * State.variables.dairyPregUpgrade * dairy * facilityCost) +
-		(0.2 * State.variables.dairyStimulatorsUpgrade * facilityCost);
-	if (dairy > 0) {
-		costs += ((State.variables.bioreactorsXY + State.variables.bioreactorsXX + State.variables.bioreactorsHerm + State.variables.bioreactorsBarren) * 100);
+	function getClubAdsCosts() {
+		return (State.variables.club > 0) ? State.variables.clubAdsSpending : 0;
 	}
-	return costs;
-};
 
-window.getIncubatorCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const incubator = State.variables.incubator;
-	let costs = (State.variables.incubator * facilityCost * 10);
-	costs += (0.2 * State.variables.incubatorUpgradeWeight * incubator * facilityCost) +
-		(0.2 * State.variables.incubatorUpgradeMuscles * incubator * facilityCost) +
-		(0.2 * State.variables.incubatorUpgradeReproduction * incubator * facilityCost) +
-		(0.2 * State.variables.incubatorUpgradeGrowthStims * incubator * facilityCost) +
-		(0.5 * State.variables.incubatorUpgradeSpeed * incubator * facilityCost);
-	if (incubator > 0) {
-		costs += ((State.variables.incubatorWeightSetting + State.variables.incubatorMusclesSetting + State.variables.incubatorReproductionSetting + State.variables.incubatorGrowthStimsSetting) * 500);
-	}
-	return costs;
-};
+	function getDairyCosts() {
+		const V = State.variables;
+		const facDairyMultiplier = V.facilityCost * V.dairy;
+		let costs = facDairyMultiplier + (0.2 * V.dairyFeedersUpgrade + 0.1 * V.dairyPregUpgrade) * facDairyMultiplier + (0.2 * V.dairyStimulatorsUpgrade * V.facilityCost);
+		if (V.dairy > 0) {
+			costs += ((V.bioreactorsXY + V.bioreactorsXX + V.bioreactorsHerm + V.bioreactorsBarren) * 100);
+		}
+		return costs;
+	}
 
-window.getServantsQuartersCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const servantsQuarters = State.variables.servantsQuarters;
-	const costs = (0.2 * State.variables.servantsQuartersUpgradeMonitoring * servantsQuarters * facilityCost);
-	return costs;
-};
+	function getIncubatorCosts() {
+		const V = State.variables;
+		const facIncMultiplier = V.facilityCost * V.incubator;
+		let costs = (facIncMultiplier * 10);
+		costs += (0.2 * V.incubatorUpgradeWeight + 0.2 * V.incubatorUpgradeMuscles +
+			0.2 * V.incubatorUpgradeReproduction + 0.2 * V.incubatorUpgradeGrowthStims +
+			0.5 * V.incubatorUpgradeSpeed) * facIncMultiplier;
+		if (V.incubator > 0) {
+			costs += ((V.incubatorWeightSetting + V.incubatorMusclesSetting + V.incubatorReproductionSetting + V.incubatorGrowthStimsSetting) * 500);
+		}
+		return costs;
+	}
 
-window.getMasterSuiteCosts = function() {
-	let costs = 0;
-	if (State.variables.masterSuitePregnancySlaveLuxuries === 1) {
-		costs += 500;
+	function getServantsQuartersCosts() {
+		const V = State.variables;
+		return (0.2 * V.servantsQuartersUpgradeMonitoring * V.servantsQuarters * V.facilityCost);
 	}
-	if (State.variables.masterSuitePregnancyFertilitySupplements === 1) {
-		costs += 1000;
+
+	function getMasterSuiteCosts() {
+		let costs = 0;
+		if (State.variables.masterSuitePregnancySlaveLuxuries === 1) {
+			costs += 500;
+		}
+		if (State.variables.masterSuitePregnancyFertilitySupplements === 1) {
+			costs += 1000;
+		}
+		return costs;
 	}
-	return costs;
-};
 
-window.getNurseryCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const nursery = State.variables.nursery;
-	return (nursery * facilityCost);
-};
+	function getNurseryCosts() {
+		return (State.variables.nursery * State.variables.facilityCost);
+	}
 
-window.getFarmyardCosts = function() {
-	const facilityCost = State.variables.facilityCost;
-	const farmyard = State.variables.farmyard;
-	return (farmyard * facilityCost);
-};
+	function getFarmyardCosts() {
+		return (State.variables.farmyard * State.variables.facilityCost);
+	}
 
-window.getSecurityExpansionCost = function() {
 	// security expansion
-	let secExpCost = 0;
-	let soldierMod = 0;
-	if (State.variables.secExp === 1) {
-		if (State.variables.edictsUpkeep > 0) {
-			secExpCost += State.variables.edictsUpkeep;
-		}
-		if (State.variables.SFSupportUpkeep > 0) {
-			secExpCost += State.variables.SFSupportUpkeep;
-		}
-		if (State.variables.propHub > 0) {
-			secExpCost += State.variables.propHubUpkeep;
-		}
-		if (State.variables.secHQ > 0) {
-			secExpCost += State.variables.secHQUpkeep + 20 * State.variables.secMenials;
-		}
-		if (State.variables.secBarracks > 0) {
-			secExpCost += State.variables.secBarracksUpkeep;
-		}
-		if (State.variables.riotCenter > 0) {
-			secExpCost += State.variables.riotUpkeep;
-		}
-		if (State.variables.soldierWages === 0) {
-			soldierMod = 1;
-		} else if (State.variables.soldierWages === 1) {
-			soldierMod = 1.5;
-		} else {
-			soldierMod = 2;
-		}
-		if (State.variables.militiaUnits !== null) {
-			for (let i = 0; i < State.variables.militiaUnits.length; i++) {
-				if (State.variables.militiaUnits[i] !== null) {
-					secExpCost += State.variables.militiaUnits[i].troops * State.variables.soldierUpkeep * soldierMod;
+	function getSecurityExpansionCost() {
+		const V = State.variables;
+		let secExpCost = 0;
+		let soldierMod = 0;
+		if (V.secExp === 1) {
+			if (V.edictsUpkeep > 0) {
+				secExpCost += V.edictsUpkeep;
+			}
+			if (V.SFSupportUpkeep > 0) {
+				secExpCost += V.SFSupportUpkeep;
+			}
+			if (V.propHub > 0) {
+				secExpCost += V.propHubUpkeep;
+			}
+			if (V.secHQ > 0) {
+				secExpCost += V.secHQUpkeep + 20 * V.secMenials;
+			}
+			if (V.secBarracks > 0) {
+				secExpCost += V.secBarracksUpkeep;
+			}
+			if (V.riotCenter > 0) {
+				secExpCost += V.riotUpkeep;
+			}
+			if (V.soldierWages === 0) {
+				soldierMod = 1;
+			} else if (V.soldierWages === 1) {
+				soldierMod = 1.5;
+			} else {
+				soldierMod = 2;
+			}
+			const militiaUnits = V.militiaUnits.length, slaveUnits = V.slaveUnits.length, mercUnits = V.mercUnits.length; //predefined for optimization
+			if (V.militiaUnits !== null) {
+				for (let i = 0; i < militiaUnits; i++) {
+					if (V.militiaUnits[i] !== null) {
+						secExpCost += V.militiaUnits[i].troops * V.soldierUpkeep * soldierMod;
+					}
 				}
 			}
-		}
-		if (State.variables.slaveUnits !== null) {
-			for (let i = 0; i < State.variables.slaveUnits.length; i++) {
-				if (State.variables.slaveUnits[i] !== null) {
-					secExpCost += State.variables.slaveUnits[i].troops * State.variables.soldierUpkeep * 0.5 * soldierMod;
+			if (V.slaveUnits !== null) {
+				for (let i = 0; i < slaveUnits; i++) {
+					if (V.slaveUnits[i] !== null) {
+						secExpCost += V.slaveUnits[i].troops * V.soldierUpkeep * 0.5 * soldierMod;
+					}
 				}
 			}
-		}
-		if (State.variables.mercUnits !== null) {
-			for (let i = 0; i < State.variables.mercUnits.length; i++) {
-				if (State.variables.mercUnits[i] !== null) {
-					secExpCost += State.variables.mercUnits[i].troops * State.variables.soldierUpkeep * 1.5 * soldierMod;
+			if (V.mercUnits !== null) {
+				for (let i = 0; i < mercUnits; i++) {
+					if (V.mercUnits[i] !== null) {
+						secExpCost += V.mercUnits[i].troops * V.soldierUpkeep * 1.5 * soldierMod;
+					}
 				}
 			}
 		}
+		return secExpCost;
 	}
-	return secExpCost;
-};
 
-// general arcology costs
+	// general arcology costs
 
-window.getLifestyleCosts = function() {
-	return (State.variables.girls * (250 + (50000 / State.variables.localEcon)));
-};
-
-window.getFSCosts = function() {
-	let costs = State.variables.FSSpending;
-	if (State.variables.arcologies[0].FSRepopulationFocusLaw === 1 && State.variables.PC.pregKnown === 1) {
-		costs -= 500;
+	function getLifestyleCosts() {
+		return (State.variables.girls * (250 + (50000 / State.variables.localEcon)));
 	}
-	return costs;
-};
-
-window.getCitizenOrphanageCosts = function() {
-	return State.variables.citizenOrphanageTotal * 100;
-};
 
-window.getPrivateOrphanageCosts = function() {
-	const costs = State.variables.privateOrphanageTotal * 500;
-	return costs + (State.variables.breederOrphanageTotal > 0) ? 50 : 0;
-};
-
-window.getPeacekeeperCosts = function() {
-	return (State.variables.peacekeepers !== 0 && State.variables.peacekeepers.undermining !== 0) ? State.variables.peacekeepers.undermining : 0;
-};
-
-window.getMercenariesCosts = function() {
-	let costs = 0;
-	let mercCosts = State.variables.mercenaries * 2000;
-	if (State.variables.mercenaries > 0) {
-		if (State.variables.barracks) {
-			mercCosts *= 0.5;
-		}
-		if ((State.variables.PC.warfare >= 100) || (State.variables.PC.career === 'arcology owner')) {
-			mercCosts *= 0.5;
+	function getFSCosts() {
+		let costs = State.variables.FSSpending;
+		if (State.variables.arcologies[0].FSRepopulationFocusLaw === 1 && State.variables.PC.pregKnown === 1) {
+			costs -= 500;
 		}
-		costs += mercCosts;
+		return costs;
 	}
-	return costs;
-};
-
-window.getMenialRetirementCosts = function() {
-	return (State.variables.citizenRetirementMenials === 1) ? State.variables.menials * 2 : 0;
-};
-
-// policy and other expenses
-window.getRecruiterCosts = function() {
-	return (State.variables.Recruiter !== 0) ? 250 : 0;
-};
 
-window.getSchoolCosts = function() {
-	let costs = 0;
-	if (State.variables.TSS.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.GRI.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.SCP.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.LDE.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.TGA.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.HA.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.TCR.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if (State.variables.NUL.schoolPresent === 1) {
-		costs += 1000;
-	}
-	if ((State.variables.TFS.schoolPresent === 1) && ((State.variables.PC.dick === 0) || (State.variables.PC.vagina === 0) || (State.variables.PC.boobs === 0))) {
-		costs += 1000;
-	}
-	if (State.variables.TSS.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.GRI.subsidize !== 0) {
-		costs += 1000;
+	function getCitizenOrphanageCosts() {
+		return State.variables.citizenOrphanageTotal * 100;
 	}
-	if (State.variables.SCP.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.LDE.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.TGA.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.HA.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.TCR.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.NUL.subsidize !== 0) {
-		costs += 1000;
-	}
-	if (State.variables.TFS.subsidize !== 0) {
-		costs += 1000;
+
+	function getPrivateOrphanageCosts() {
+		const costs = State.variables.privateOrphanageTotal * 500;
+		return (State.variables.breederOrphanageTotal > 0) ? costs + 50 : costs;
 	}
-	return costs;
-};
 
-window.getPolicyCosts = function() {
-	let costs = 0;
-	const policyCost = State.variables.policyCost;
-	if (State.variables.alwaysSubsidizeGrowth === 1) {
-		costs += policyCost;
+	function getPeacekeeperCosts() {
+		return (State.variables.peacekeepers !== 0 && State.variables.peacekeepers.undermining !== 0) ? State.variables.peacekeepers.undermining : 0;
 	}
-	if (State.variables.alwaysSubsidizeRep === 1) {
-		costs += policyCost;
+
+	function getMercenariesCosts() {
+		const V = State.variables;
+		let costs = 0;
+		let mercCosts = V.mercenaries * 2000;
+		if (V.mercenaries > 0) {
+			if (V.barracks) {
+				mercCosts *= 0.5;
+			}
+			if ((V.PC.warfare >= 100) || (V.PC.career === 'arcology owner')) {
+				mercCosts *= 0.5;
+			}
+			costs += mercCosts;
+		}
+		return costs;
 	}
-	if (State.variables.RegularParties === 1) {
-		costs += policyCost;
+
+	function getMenialRetirementCosts() {
+		return (State.variables.citizenRetirementMenials === 1) ? State.variables.menials * 2 : 0;
 	}
 
-	if (State.variables.ProImmigrationCash === 1) {
-		costs += policyCost;
+	// policy and other expenses
+	function getRecruiterCosts() {
+		return (State.variables.Recruiter !== 0) ? 250 : 0;
 	}
-	if (State.variables.AntiEnslavementCash === 1) {
-		costs += policyCost;
+
+	function getSchoolCosts() {
+		let costs = 0;
+		if (State.variables.TSS.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.GRI.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.SCP.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.LDE.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.TGA.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.HA.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.TCR.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if (State.variables.NUL.schoolPresent === 1) {
+			costs += 1000;
+		}
+		if ((State.variables.TFS.schoolPresent === 1) && ((State.variables.PC.dick === 0) || (State.variables.PC.vagina === 0) || (State.variables.PC.boobs === 0))) {
+			costs += 1000;
+		}
+		if (State.variables.TSS.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.GRI.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.SCP.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.LDE.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.TGA.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.HA.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.TCR.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.NUL.subsidize !== 0) {
+			costs += 1000;
+		}
+		if (State.variables.TFS.subsidize !== 0) {
+			costs += 1000;
+		}
+		return costs;
 	}
 
-	if (State.variables.CoursingAssociation === 1) {
-		costs += 1000;
+	function getPolicyCosts() {
+		let costs = 0;
+		const policyCost = State.variables.policyCost;
+		if (State.variables.alwaysSubsidizeGrowth === 1) {
+			costs += policyCost;
+		}
+		if (State.variables.alwaysSubsidizeRep === 1) {
+			costs += policyCost;
+		}
+		if (State.variables.RegularParties === 1) {
+			costs += policyCost;
+		}
+		if (State.variables.ProImmigrationCash === 1) {
+			costs += policyCost;
+		}
+		if (State.variables.AntiEnslavementCash === 1) {
+			costs += policyCost;
+		}
+		if (State.variables.CoursingAssociation === 1) {
+			costs += 1000;
+		}
+		return costs;
 	}
-	return costs;
-};
 
-window.getProstheticsCosts = function() {
-	return ((100 * State.variables.researchLab.maxSpace) + (300 * State.variables.researchLab.hired) + (100 * State.variables.researchLab.hired));
-};
+	function getProstheticsCosts() {
+		return ((100 * State.variables.researchLab.maxSpace) + (300 * State.variables.researchLab.hired) + (100 * State.variables.researchLab.hired));
+	}
 
 
-// player expenses
-window.getPCTrainingCosts = function() {
-	const PA = Object.values(PersonalAttention);
-	const currentPA = State.variables.personalAttention;
-	let costs = 0;
-	if (State.variables.PC.actualAge >= State.variables.IsInPrimePC && State.variables.PC.actualAge < State.variables.IsPastPrimePC) {
-		if (PA.includes(currentPA) && currentPA !== PersonalAttention.MAID) {
-			costs += 10000 * State.variables.AgeEffectOnTrainerPricingPC;
+	// player expenses
+	function getPCTrainingCosts() {
+		const V = State.variables;
+		const PA = Object.values(PersonalAttention);
+		const currentPA = V.personalAttention;
+		let costs = 0;
+		if (V.PC.actualAge >= V.IsInPrimePC && V.PC.actualAge < V.IsPastPrimePC) {
+			if (PA.includes(currentPA) && currentPA !== PersonalAttention.MAID) {
+				costs += 10000 * V.AgeEffectOnTrainerPricingPC;
+			}
 		}
+		return costs;
 	}
-	return costs;
-};
 
-window.getPCCosts = function() {
-	let costs = 0;
-	if (State.variables.PC.preg === -1) {
-		costs += 25;
-	} else if (State.variables.PC.fertDrugs === 1) {
-		costs += 50;
-	} else if (State.variables.PC.preg >= 16) {
-		costs += 100;
-	}
-	if (State.variables.PC.staminaPills === 1) {
-		costs += 50;
+	function getPCCosts() {
+		let costs = 0;
+		if (State.variables.PC.preg === -1) {
+			costs += 25;
+		} else if (State.variables.PC.fertDrugs === 1) {
+			costs += 50;
+		} else if (State.variables.PC.preg >= 16) {
+			costs += 100;
+		}
+		if (State.variables.PC.staminaPills === 1) {
+			costs += 50;
+		}
+		return costs;
 	}
-	return costs;
-};
 
 
-window.getPCMultiplierCosts = function(cost) {
-	if (State.variables.PC.career === 'servant') {
-		if (State.variables.personalAttention === PersonalAttention.MAID) {
-			if (State.variables.PC.belly >= 5000) {
-				cost *= 0.80;
+	function getPCMultiplierCosts(cost) {
+		if (State.variables.PC.career === 'servant') {
+			if (State.variables.personalAttention === PersonalAttention.MAID) {
+				if (State.variables.PC.belly >= 5000) {
+					cost *= 0.80;
+				} else {
+					cost *= 0.75;
+				}
 			} else {
-				cost *= 0.75;
+				cost *= 0.9;
 			}
-		} else {
-			cost *= 0.9;
 		}
+		return cost;
 	}
 
-	return cost;
-};
-
-window.getEnvironmentCosts = function(cost) {
-	if (State.variables.secExp === 1) {
-		if (State.variables.terrain === 'oceanic' || State.variables.terrain === 'marine') {
-			if (State.variables.docks > 0) {
-				cost *= (1 - State.variables.docks * 0.05);
+	function getEnvironmentCosts(cost) {
+		if (State.variables.secExp === 1) {
+			if (State.variables.terrain === 'oceanic' || State.variables.terrain === 'marine') {
+				if (State.variables.docks > 0) {
+					cost *= (1 - State.variables.docks * 0.05);
+				}
+			} else if (State.variables.railway > 0) {
+				cost *= (1 - State.variables.railway * 0.05);
 			}
-		} else if (State.variables.railway > 0) {
-			cost *= (1 - State.variables.railway * 0.05);
 		}
+		return Math.trunc(cost);
 	}
-	return Math.trunc(cost);
-};
 
-window.getSFCosts = function() {
-	let costs = 0;
-	if (State.variables.SF.Toggle && State.variables.SF.Active >= 1 && State.variables.SF.Subsidy > 0) {
-		App.SF.Count(); costs += Math.ceil(State.temporary.SFSubsidy); cashX(-costs, "specialForces");
-	}
-	return costs;
-};
-
-window.getWeatherCosts = function() {
-	let costs = 0;
-	if (State.variables.econWeatherDamage && State.variables.disasterResponse > 0) {
-		costs += Math.trunc(State.variables.disasterResponse * 200000 / State.variables.localEcon);
-	}
-	if (State.variables.antiWeatherFreeze > 0) {
-		costs += Math.trunc(State.variables.antiWeatherFreeze * 200000 / State.variables.localEcon);
+	function getSFCosts() {
+		let costs = 0;
+		if (State.variables.SF.Toggle && State.variables.SF.Active >= 1 && State.variables.SF.Subsidy > 0) {
+			App.SF.Count();
+			costs += Math.ceil(State.temporary.SFSubsidy);
+			cashX(-costs, "specialForces");
+		}
+		return costs;
 	}
-	return costs;
-};
 
-window.getSlaveMinorCosts = function(slave) {
-	let costs = 0;
-	const rulesCost = State.variables.rulesCost;
-	if (slave.assignment === Job.SERVANT || slave.assignment === Job.SERVER) {
-		if (slave.trust < -20) {
-			costs -= rulesCost * 4;
-		} else if (slave.devotion < -20) {
-			costs -= (slave.trust >= 20) ? rulesCost / 2 : rulesCost * 2;
-		} else if (slave.devotion <= 20) {
-			costs -= rulesCost * 3;
-		} else if (slave.devotion <= 50) {
-			costs -= rulesCost * 4;
-		} else {
-			costs -= rulesCost * 5;
-		}
-		if (slave.fetish === 'submissive') {
-			costs -= rulesCost;
-		} else if (slave.fetish === 'dom') {
-			costs += rulesCost;
+	function getWeatherCosts() {
+		let costs = 0;
+		if (State.variables.econWeatherDamage && State.variables.disasterResponse > 0) {
+			costs += Math.trunc(State.variables.disasterResponse * 200000 / State.variables.localEcon);
 		}
-		if (slave.relationship < -1) {
-			costs -= rulesCost;
+		if (State.variables.antiWeatherFreeze > 0) {
+			costs += Math.trunc(State.variables.antiWeatherFreeze * 200000 / State.variables.localEcon);
 		}
-		if (slave.energy < 20) {
-			costs -= rulesCost;
-		} else if (slave.energy < 40) {
-			costs -= rulesCost / 2;
-		}
-		if (slave.lactation > 0) {
-			costs -= 25;
-		}
-		if (slave.assignment === Job.SERVANT) {
-			costs -= rulesCost;
-		}
-		if (setup.servantCareers.includes(slave.career) || slave.skill.servant >= State.variables.masteredXP) {
-			costs -= rulesCost;
+		return costs;
+	}
+
+	//the cost of keeping a slave under restrictive rules
+	function getSlaveMinorCosts(slave) {
+		let costs = 0;
+		const rulesCost = State.variables.rulesCost;
+		if (slave.assignment === Job.SERVANT || slave.assignment === Job.SERVER) {
+			if (slave.trust < -20) {
+				costs -= rulesCost * 4;
+			} else if (slave.devotion < -20) {
+				costs -= (slave.trust >= 20) ? rulesCost / 2 : rulesCost * 2;
+			} else if (slave.devotion <= 20) {
+				costs -= rulesCost * 3;
+			} else if (slave.devotion <= 50) {
+				costs -= rulesCost * 4;
+			} else {
+				costs -= rulesCost * 5;
+			}
+			if (slave.fetish === 'submissive') {
+				costs -= rulesCost;
+			} else if (slave.fetish === 'dom') {
+				costs += rulesCost;
+			}
+			if (slave.relationship < -1) {
+				costs -= rulesCost;
+			}
+			if (slave.energy < 20) {
+				costs -= rulesCost;
+			} else if (slave.energy < 40) {
+				costs -= rulesCost / 2;
+			}
+			if (slave.lactation > 0) {
+				costs -= 25;
+			}
+			if (slave.assignment === Job.SERVANT) {
+				costs -= rulesCost;
+			}
+			if (setup.servantCareers.includes(slave.career) || slave.skill.servant >= State.variables.masteredXP) {
+				costs -= rulesCost;
+			}
 		}
+		return costs;
 	}
-	return costs;
-};
+})();
 
 window.getSlaveCost = function(s) {
 	if (!s) {
@@ -888,7 +863,7 @@ window.getSlaveCost = function(s) {
 	}
 
 	if (isNaN(cost)) {
-		throw new Error(`Cost calculation for slave ${ s.slaveName } (${ s.ID }) failed.`);
+		throw new Error(`Cost calculation for slave ${s.slaveName} (${s.ID}) failed.`);
 	}
 	return cost;
 };
@@ -1489,10 +1464,7 @@ window.cashX = function(cost, what, who) {
 			who.lastWeeksCashIncome += cost;
 			who.lifetimeCashIncome += cost;
 		}
-	}
-
-	// EXPENSES
-	else if (cost < 0) {
+	} else if (cost < 0) { //EXPENSES
 		// record the action
 		if (typeof V.lastWeeksCashExpenses[what] !== 'undefined') {
 			V.lastWeeksCashExpenses[what] += cost;
@@ -1542,10 +1514,7 @@ window.repX = function(rep, what, who) {
 		} else {
 			V.lastWeeksRepErrors += `Unknown place "${what}" gained you ${rep}<br>`;
 		}
-	}
-
-	// EXPENSES
-	else if (rep < 0) {
+	} else if (rep < 0) { //EXPENSES
 		// record the action
 		if (typeof V.lastWeeksRepExpenses[what] !== 'undefined') {
 			V.lastWeeksRepExpenses[what] += rep;
@@ -1567,10 +1536,7 @@ window.repX = function(rep, what, who) {
 	if (V.rep > 20000) {
 		V.lastWeeksRepExpenses.overflow += (20000 - V.rep);
 		V.rep = 20000;
-	}
-
-	// Rep should never be lower than 0. Record this rounding purely to keep the books balanced.
-	else if (V.rep < 0) {
+	} else if (V.rep < 0) { // Rep should never be lower than 0. Record this rounding purely to keep the books balanced.
 		V.lastWeeksRepIncome.overflow += (0 - V.rep);
 		V.rep = 0;
 	}
diff --git a/src/uncategorized/main.tw b/src/uncategorized/main.tw
index 178c40dac2eb14c71f99ec29443abd63a88e0f63..40702a3a48979d8b6d9e1470751735ac33f85e56 100644
--- a/src/uncategorized/main.tw
+++ b/src/uncategorized/main.tw
@@ -67,7 +67,7 @@
 <<if (def _BG && $dojo > 1)>><<set $slavesVisible++>><</if>>
 
 <<set $nextButton = "END WEEK", $nextLink = "End Week", $showEncyclopedia = 1, $encyclopedia = "How to Play">>
-<<set $costs = Math.trunc(predictCost())>>
+<<set $costs = Math.trunc(calculateCosts.predict())>>
 
 <<if ($PC.customTitle == "")>>
 	<<set $PC.customTitle = undefined, $PC.customTitleLisp = undefined>>
diff --git a/src/uncategorized/persBusiness.tw b/src/uncategorized/persBusiness.tw
index 64b8a4e6b35a34d1894e23a5281480d732b0ea46..7116025fa293a938e9eb642a3fa966cebe65b51e 100644
--- a/src/uncategorized/persBusiness.tw
+++ b/src/uncategorized/persBusiness.tw
@@ -808,7 +808,7 @@ Routine upkeep of your demesne costs @@.yellow;<<print cashFormat($costs)>>.@@
 		<</if>>
 	<</if>>
 <</if>>
-<<set $costs = Math.trunc(Math.abs(getCost()) * 100)/100>> /*overwrite the prediction and actually pay the bill. GetCost should return a negative. Round to two decimal places.*/
+<<set $costs = Math.trunc(Math.abs(calculateCosts.bill()) * 100)/100>> /*overwrite the prediction and actually pay the bill. GetCost should return a negative. Round to two decimal places.*/
 <<if isNaN($costs)>>
 	<br>@@.red;Error, costs is NaN@@
 <</if>>