Resource Generators

👍

Reminder - Keep Daily Backups

When working on a strategy game with a kit as big as the Complete Kit - always keep a working daily backup! Save yourself the trouble of rolling-back changes and losing work.

What are resource generators?

When playing city-building games or battle strategy games you'll always have some sort of economy. In the case of city-builders it could be resources like steel, wood, stone, or money or in the case of battle strategy games like Clash of Clans it could be gold and liquids. These are in-game currencies your players try to collect either through raiding other player villages or building resource generators.

Two types of in-game resources: Gold and Liquids

In the City Building Game Kit we provide two types of resource generators, gold mines and liquid mana collectors. The names may be unique in this example but the concept is simple: in-game resource #1 and in-game resource #2. (In addition there's a rare in-game currency that can be purchased with real-world money known as crystal gems, but that's a topic under the In-App Purchases section on the left)

Shop Menu

Here's a screenshot of the shop menu for the resources. There are three different types of items on this page, resource generators (like the Gold Mine Forge), resource storage (like the Gold Vault) and the builder huts (Dobbit Toolhouse - how to get additional city builders)

636

Click to view larger.

743

Click to view larger.

Where to find the resource store menu in Unity?

Open the game scene hierarchy and locate the ScrollViewProduction in UIAnchor > Anchor - Center > Shop > Main. Look at the below screenshot.

270

UIAnchor. Click to view larger.

Store Item

All of the store details seen in the below screenshot are taken from the XML/Buildings.xml file and loaded by Scripts/Creators/BaseCreator.cs (details below on what part of the script does this)

483

Breakdown of the information shown to players in the store.

From Image AboveDescription
Item NameThis is the Name variable from XML/Buildings.xml
Time to BuildThe TimeToBuild variable (in minutes) from Buildings.xml. How long the structure will take to to be created.
# Build / Level LimitThe number of this structure already created versus the number limited by their level in XML/EvolutionBuildings.xml. See Gameplay > XP and Levels documentation for details)
Currency CostThe Price variable from XML/Buildings.xml
Currency TypeThe Currency variable from XML/Buildings.xml (Either Gold, Mana, or Gems) You could change this to whatever currency you will have in your game and also add additional currencies.
View DescriptionShows the Description text variable from XML/Buildings.xml
Prefab ImageThe prefab image which you can edit from the UIAnchor: Center shop main menu. More details on how to change this under the Buildings > Part 2: Customize Menus page of the documentation

Resource Generators

The first type of resource building are generators. These create in-game currencies for players over time. See the Buildings > Resource Generators documentation page for more details about these structures.

294

Resource Generators

Resource Storage

The second type of resource buildings are storage buildings. These store in-game currency and add capacity to the player's stats. For example, 250,000 total gold capacity.

150

Resource Storage Example

Additional Builders

The last type of resource buildings are a special type known as builder huts, or Dobbit Toolhouses in the demo. These allow the player to have additional builders and construct more than one building at a time. They're considered a builder resource, since it's limited.

141

Builder hut

By default, players get one builder and can purchase more in the store here. The screenshot below shows the HUD Dobbit builder stat for the player's one builder which is active. Purchasing additional builders in the store increases the total by one for a price of 25 gems (or whatever value you set in the XML/Buildings.xml -- see more details below)

900

One builder active. Click to view larger.

Watch about how builders work in the game as a limited resource:

Resource Building XML Example

Here's an example of how to do a resource generator, in this case a gold mine, in the XML. For resource generators, the single XML difference most noticeable is that ProdType (production type) line item is set to either Gold or Mana, instead of None. The order of items in the XML document must exactly match the scripts you customize in Buildings > Part 2: Customize Menus documentation as this XML item order becomes the structure index used in the scripts.

<Building> 
		
		<Name>Gold Forge</Name>	
    <!--  name displayed in the store -->	
    
		<StructureType>Forge</StructureType>	
    <!--  IMPORTANT: use the same name same as prefab in your XML -->	

		<Description>Gold mines are so '2050s. Mages create gold by simply mumbling to themselves. Or pull it out of their, aaa... pointy hats! We never asked. Neither should you. Know your place, little one.</Description>
    <!--  description displayed in the store -->	
								
		<Currency>Mana</Currency>			
    <!-- save as Gold, Mana, or Crystals to buy; production/storage building, buy with gold, produces mana -->			
    
		<Price>100</Price>		
    <!-- amount of resource necessary to pay for the building -->
		
		<ProdType>Gold</ProdType>	
    <!-- resource produced - gold/mana/none-->	
		<ProdPerHour>100</ProdPerHour>	
    <!-- the amount of the resource generated per hour -->	

		<StoreType>Internal</StoreType>					
    <!-- None, Internal, Distributed (where the gold is stored, in this case 500 internally in the Unit until you click and disperse the gold into your player stats -->
		<StoreResource>Gold</StoreResource>
    <!-- resource stored - None/Gold/Mana/Dual (gold+mana)/Soldiers-->	
		<StoreCap>500</StoreCap>		
    <!-- gold/mana/dual/soldiers storage -->	
    <!--although it's not centralized, there is an internal storage-->
						
		<TimeToBuild>10</TimeToBuild>
    <!-- the time (in minutes) needed to create the building -->		
		<Life>300</Life>		
    <!-- hitpoints for the building in battle  -->
		<XpAward>100</XpAward>		
    <!-- experience awarded for the completion of building this -->
		
	</Building>

XML for a resource generator (Gold Mine example)

If you look closely, you'll see the gold forge costs the opposite currency (in this case mana) to purchase and produce 100 gold per hour with 500 internal gold storage. This internal storage is not a part of the player's gold capacity and when production reaches this amount the gold will no longer product until the player taps the building to save it to their distributed gold storage. (See details below on the Gold Vault XML example)

<Currency>Mana</Currency>						
		<Price>100</Price>						
		
		<ProdType>Gold</ProdType>	
		<ProdPerHour>100</ProdPerHour>	

		<StoreType>Internal</StoreType>					
		<StoreResource>Gold</StoreResource>			
		<StoreCap>500</StoreCap>

Meanwhile the Mana generator is the exact opposite in costs to the Gold Mine. The mana generator costs 100 gold, produces 100 mana per hour and internally stores 500 mana. This is done to balance the game so that players have to earn both currencies to be able to level up their base equally.

<Currency>Gold</Currency>							
		<Price>100</Price>						
		
		<ProdType>Mana</ProdType>	
		<ProdPerHour>100</ProdPerHour>	
		
		<StoreType>Internal</StoreType>					
		<StoreResource>Mana</StoreResource>			
		<StoreCap>500</StoreCap>

XML for a resource storage (Gold Vault example)

Following the example from above, a Gold Vault has no resource production (ProdType is set to None and ProdPerHour set to 0) but the storage is now set to Distributed which means it adds to the player's total Gold capacity unlike Internal which is capped and stops production when reached unless the player retrieves the resources.

<ProdType>None</ProdType>	
		<ProdPerHour>0</ProdPerHour>	
		
		<StoreType>Distributed</StoreType>					
		<StoreResource>Gold</StoreResource>					
		<StoreCap>2500</StoreCap>

XML - want to store both resources in one building?

This is possible with the kit. Select the Dual option for StoreResource to add the value in StoreCap to the player's total storage capacity for both in-game resources. The Summoning Circle item is an example of this in the demo. Here's an excerpt from it's XML:

<StoreType>Distributed</StoreType>					
		<StoreResource>Dual</StoreResource>						
		<StoreCap>1000</StoreCap>

BaseCreator.cs

In Scripts/Creators/BaseCreator.cs the building data from your XML file (seen above) is loaded using a common system for the resource buildings, defense buildings, walls, decorations, and other buildings. Here's an excerpt from BaseCreator.cs of the XML data load:

//reads structures XML
protected void GetBuildingsXML()
{
	XmlDocument xmlDoc = new XmlDocument(); 
	xmlDoc.LoadXml(StructuresXML.text); 
	XmlNodeList structuresList = xmlDoc.GetElementsByTagName(structureXMLTag);
	
	foreach (XmlNode structureInfo in structuresList)
	{
		XmlNodeList structureContent = structureInfo.ChildNodes;	
		dictionary = new Dictionary<string, string>();
		
		foreach (XmlNode structureItem in structureContent) 
		{
		
      // For each of the XML values, it stores the information
      // to be used later in BaseCreator.cs
      
			if(structureItem.Name == "Name")
			{
				dictionary.Add("Name",structureItem.InnerText); 
        // put this in the dictionary.
			}						
			if(structureItem.Name == "StructureType")
			{
				dictionary.Add("StructureType",structureItem.InnerText); 
        // put this in the dictionary.
			}	
			if(structureItem.Name == "Description")
			{
				dictionary.Add("Description",structureItem.InnerText); 
			}
			if(structureItem.Name == "Currency")
			{
				dictionary.Add("Currency",structureItem.InnerText); 
			}
			if(structureItem.Name == "Price")
			{
				dictionary.Add("Price",structureItem.InnerText); 
			}				
			if(structureItem.Name == "ProdType")
			{
				dictionary.Add("ProdType",structureItem.InnerText); 
			}				
			if(structureItem.Name == "ProdPerHour")
			{
				dictionary.Add("ProdPerHour",structureItem.InnerText); 
			}
			if(structureItem.Name == "StoreType")
			{
				dictionary.Add("StoreType",structureItem.InnerText); 
			}
			if(structureItem.Name == "StoreResource")
			{
				dictionary.Add("StoreResource",structureItem.InnerText); 
			}
			if(structureItem.Name == "StoreCap")
			{
				dictionary.Add("StoreCap",structureItem.InnerText); 
			}
			if(structureItem.Name == "PopCap")
			{
				dictionary.Add("PopCap",structureItem.InnerText); 
			}
			if(structureItem.Name == "TimeToBuild")
			{
				dictionary.Add("TimeToBuild",structureItem.InnerText); 
			}
			if(structureItem.Name == "Life")
			{
				dictionary.Add("Life",structureItem.InnerText); 
			}
			if(structureItem.Name == "XpAward")
			{
				dictionary.Add("XpAward",structureItem.InnerText); 
			}
      
      // The following two are not currently used in the demo
      // but have been provided for developers wishing to expand
      // their builings with upgrades. Additional scripting required.
      
			if(structureItem.Name == "Upgrades")
			{
				dictionary.Add("Upgrades",structureItem.InnerText); 
			}
			if(structureItem.Name == "UpRatio")
			{
				dictionary.Add("UpRatio",structureItem.InnerText); 
			}
		}
		
		structures.Add(dictionary);
	}
}

When the data is loaded, the store panels are updated with the appropriate information.

XP levels and building maximums

Read the Gameplay > XP and Levels documentation page for more details about how the XML/EvolutionBuildings.xml file limits the number of certain Building.xml structures per level. For example, game players could have a maximum of two gold mines at level one until the player reaches level two, in which the maximum increases to five (or whatever value you choose -- read XP and Levels documentation for more details)

158

1/2 gold mines built. Maximum not reached.

161

2/2 maximum reached, can't build more

This is relevant to mention now because the menu items are greyed out for buildings that the player can no longer build until they increase their base level through other ways of gaining XP. The function UpdateLabelStats()

// Excerpt from UpdateLabelStats()
// Check if the player is looking at items in the store that
// would exceed their XP level limits
buildingAllowed =(allowedStructures[i]-existingStructures[i]>0);

// Set the store item's label data
NameLbs[i].text = structures [i] ["Name"];
TimeLbs[i].text = structures [i] ["TimeToBuild"];

// Quantity - for example, 2/2 means they have reached the maximum of 2
QuantityLbs[i].text = existingStructures[i].ToString()+"/"+allowedStructures[i].ToString();
PriceLbs[i].text = structures [i] ["Price"];

// If they can build, set the normal store item background and label colors
if(buildingAllowed)
{
	NicheSprites[i].spriteName = "stone_niche";
	PortraitSprites[i].atlas = Portraits;

	NameLbs[i].color = brown;
	TimeLbs[i].color = brown;
	QuantityLbs[i].color = brown;
	PriceLbs[i].color = brown;
// If the player can no longer build this item, grey out the item in the store
} else {
	NicheSprites[i].spriteName = "stone_niche_bw";
	PortraitSprites[i].atlas = PortraitsBW;

	NameLbs[i].color = black;
	TimeLbs[i].color = black;
	QuantityLbs[i].color = black;
	PriceLbs[i].color = black;
}

What happens when a store button is clicked?

When the player clicks one of the buttons to build a building in the store, first one of the building functions is triggered, like this example below:

//receive a NGUI button message to build
	public void OnBuild0()	 { currentSelection=0; 	Verify(); }
//when a building construction menu button is pressed

Verify() is run shortly after, which initiates the conditions checking to see if the player actually can build what they want to build.

private void Verify()
	{
		if (isArray[currentSelection] == 0) 
		{			
			VerifyConditions ();
		}
		else 
		{			
			isField = true;
			drawingField = true;
			Delay ();
			VerifyConditions ();
		}
	}

VerifyConditions()

Can the player build this structure? In Scripts/Creators/BaseCreator.cs the VerifyConditions() script takes over once the store button has been pushed to determine if the following conditions are met and canBuild is set to true.

VerifyConditions() Test #1 - Maximum structures reached?

First, we check if the player's level restricts the structure from being made. Have they exceeded the number of structures allowed by their level in XML/EvolutionBuildings.xml? (See Gameplay > XP and Levels documentation for more information on this)

if (existingStructures[currentSelection] >= maxAllowed){				
      // Max already reached
    	// Fails the first test, set canBuild = false
			canBuild = false;
      
      // Throws an error message in the in-game messanger
			((Messenger)statusMsg).DisplayMessage("Maximum " + maxAllowed.ToString() + 
				" structures of type " +
				structures [currentSelection] ["Name"]+". "); 
        // Displays the hint:
        // you can have only X structures of this type for their level
}

VerifyConditions() Test #2 - Do they have enough funds?

The second test the player data must pass is their funds - do they have enough of the currency the building requires to be constructed?

// Get the building cost
int price = int.Parse (structures [currentSelection] ["Price"]);

// If the building cost is in Gold, do they have enough gold?
if (structures [currentSelection] ["Currency"] == "Gold"){

	// Finding out how much gold they have remaning if you subtract it
	int existingGold = ((Stats)stats).gold + ((Stats)stats).deltaGoldPlus - ((Stats)stats).deltaGoldMinus;

   // See if the gold remaining is less than the price
	if (existingGold < price) 
	{
  	// not enough
		canBuild = false;
		((Messenger)statusMsg).DisplayMessage("Not enough gold.");
    //updates hint text
	}
  
// Repeat the same above, but instead for the other currency (Mana)
} 
else  if (structures [currentSelection] ["Currency"] == "Mana")
{
	int existingMana = ((Stats)stats).mana + ((Stats)stats).deltaManaPlus - ((Stats)stats).deltaManaMinus;

	if(existingMana < price)
	{
		canBuild = false;
		((Messenger)statusMsg).DisplayMessage("Not enough mana.");//updates hint text
	}
  
// Repeat the same above but for the rare Crystal currency
// If you have additional currencies in your game, uncomment the //
// and repeat for each currency
}
else  //if (structures [currentSelection] ["Currency"] == "Crystals")
{
	int existingCrystals = ((Stats)stats).crystals + ((Stats)stats).deltaCrystalsPlus - ((Stats)stats).deltaCrystalsMinus;

	if(existingCrystals < price)
	{
		canBuild = false;
		((Messenger)statusMsg).DisplayMessage("Not enough crystals.");//updates hint text
	}
}

VerifyConditions() Test #3 - Do they have an available builder?

In the City Building Kit each building under construction takes one builder. Players get a certain number of builders to start with (default is 1 in the demo) and you can adjust this for your game. It costs extra rare gems to get additional builders like games such as Clash of Clans. (The builder hut is called a dobbit hut in the demo, and can be seen in the resource shop screenshot above.)

//builder available?
if (((Stats)stats).occupiedDobbits >= ((Stats)stats).dobbits) 
{
	canBuild = false;
	((Messenger)statusMsg).DisplayMessage("You need more dobbits.");
}

VerifyConditions() - If all tests pass, greenlight construction.

If the player's data passes all 3 tests and canBuild still is set to true, then the script adjusts the player data awarding the XP they get from the building XML (if any) and deducting the costs involved from the building currency and price.

if (canBuild) 
{
	((MenuMain)menuMain).constructionGreenlit = true;
  //ready to close menus and place the building; 
	//constructionGreenlit bool necessary because the command is sent by pressing the button anyway

	((Stats)stats).experience += int.Parse (structures [currentSelection] ["XpAward"]); 
  //increases Stats experience  
  // move this to building finished 

	if(((Stats)stats).experience>((Stats)stats).maxExperience)
	{
		((Stats)stats).level++;
		((Stats)stats).experience-=((Stats)stats).maxExperience;
		((Stats)stats).maxExperience+=100;
	}

	//pays the gold/mana price to Stats
	if(structures [currentSelection] ["Currency"] == "Gold")
	{

		((Stats)stats).SubstractResources (price, 0, 0);

	}
	else if(structures [currentSelection] ["Currency"] == "Mana")
	{

		((Stats)stats).SubstractResources (0, price, 0);
    

	}
	else //if(structures [currentSelection] ["Currency"] == "Crystals")
	{
        
// Repeats the same above but for the rare Crystal currency
// If you have additional currencies in your game, uncomment the //if(structures
// above and repeat for each currency in your game

		((Stats)stats).SubstractResources (0, 0, price);

	}

	UpdateButtons ();//payments are made, update all

	((Stats)stats).UpdateUI();
  //tells stats to update the interface - otherwise new numbers are updated but not displayed

	if (!isField || buildingFields) 
	{
		UpdateExistingStructures (+1);
    //an array that keeps track of how many structures of each type exist
		InstantiateStructure ();
	}
} 
else 
{
	((MenuMain)menuMain).constructionGreenlit = false;
  //halts construction - the button message is sent anyway, but ignored
}

ConstructionGreenlit = true is sent the MenuMain script which then deactivates the store panel the player was just on and waits for the building to be placed.

((MenuMain)menuMain).constructionGreenlit = true;
// ready to close menus and place the building; 
// constructionGreenlit bool necessary because the command is sent by pressing the button anyway