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?

Your game can include buildings that create in-game resources like gold. These are called resource generators and the city building kit comes with two in-game resource examples (gold and mana) plus one rare currency example. In the store you'll see the two generator examples, gold mine forge (example currency #1) and the mana generator (example currency #2)

750

Examples of the resource generators in the store.

Resource #1 Generator (Gold)

Like many free-to-play strategy games, the first resource generator produces gold as you can see in the below example.

990

Gold resource generators. Click to view larger.

Resource #2 Generator (Liquid Mana)

The second type of resource generator in the city building kit is liquid mana, as seen in the below screenshot.

990

Liquid resource generator. Click to view larger.

Can I change these currencies to others, like wood or stone?

Yes, you can change everything inside the city building kit. All the source code is included. The easiest way to change one of the existing currency examples like gold to wood without adding more currencies is to update the gold sprite images. The source code can remain the same.

Can I add more currencies to my game?

Yes, you can add more to your game by copying the existing source code for the first two currencies examples - gold and liquid mana. Or to have more than one purchase currency, you'll want to work with the rare crystal gem example included in the kit.

Adding more currencies to your game will take some time to fully understand. We'd hope you'd become comfortable with the kit source code first and editing the existing two currency examples before attempting more difficult customizations like additional currencies.

What is an example of their XML?

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>

For a closer look at the XML for resource generators and storage units, you want to open the Shops Menu > Resource Generators section of the documentation.

Updating the ConstructionSelector.cs

If you're adding a new resource building to your game and not working from one of the existing examples (we highly recommend you work from the examples first!) then you'll want to edit the list seen in Scripts/Creators/ConstructionSelector.cs ProgressBarUpdate() function which runs when the construction has completed.

The following is an excerpt from that function -- you'll see the two examples for resource buildings have the line isProductionBuilding = true marked. Make sure you do this for your own resource buildings too since later in the function it sets up the notifications for harvesting above the resource buildings.

// ProgressBarUpdate() excerpt
// from Scripts/Creators/ConstructionSelector.cs
//
// The following part of the function updates the player stats depending 
// on what sort of special features the building they create

					//the builder previously assigned becomes available
					((Stats)stats).occupiedDobbits--;			

					// What type of building is it?
					// Any special building attributes are added to the player stats
					if(structureType=="Toolhouse")													
					{
					//increases total builders since they built a builder house
						((Stats)stats).dobbits += 1;
            															
					}
					else if(structureType=="Tatami")									
					{
            // increases total unit storage in Stats	because they built
            // the Tatami example which has unit storage
						((Stats)stats).maxHousing += storageAdd;
					}
					else if(structureType=="Forge")
					{
            // if it's a production building
            // later in this fuction we'll register it for
            // notifictions above the building using
            // RegisterAsProductionBuilding
						isProductionBuilding = true;			
					}
					else if(structureType=="Generator")
					{
            // if it's a production building
            // later in this fuction we'll register it for
            // notifictions above the building using
            // RegisterAsProductionBuilding
						isProductionBuilding = true;		
					}

					else if(structureType=="Barrel")				
					{	
            //increases total mana (currenct #2) storage in Stats														
						((Stats)stats).maxMana += storageAdd;
					}
					else if(structureType=="Vault")
					{
            //increases total gold (currency #1 storage in Stats	
						((Stats)stats).maxGold += storageAdd;
					}

					// since we've probably changed values seen in the UI 
					// (e.g. extra storage with a vault) then update the stats UI
					((Stats)stats).UpdateUI();

		// .........

How resource generators work

Resource generators work by producing a certain amount of resources per hour (specified in XML/buildings.xml). In the case of the gold mine forge example above, you can see it's 100 gold per hour which roughly translates to approximately 0.28 gold per second.

<ProdType>Gold</ProdType>	
    <!-- resource produced - gold/mana/none-->	
		<ProdPerHour>100</ProdPerHour>	
    <!-- the amount of the resource generated per hour -->

The function RunEconomy() in the Scripts/Creators/ResourceGenerator.cs script is what manages the resource generation each second. It's invoked on start in this script to repeat each second - calculating the new resource generation total. See the following excerpt:

// Excerpt from Scripts/Creators/ResourceGenerator.cs
// The RunEconomy() script is involved on application start
// And repeats once per second to add resources to the resource building
private void RunEconomy()
{
	bool valuesChanged = false;

  // loop through each production building the player owns
	for (int i = 0; i < existingEconomyBuildings.Count; i++) 
	{
		string prodType = existingEconomyBuildings [i].ProdType;

    // only do the following calculations for buildings
    // who's XML prodType item is either Gold or Mana (not None)
		if (prodType != "None") 
		{
      // calculate the total produce per second from the ProdPerHour
      // XML item for this structure
			float produce = (float)existingEconomyBuildings [i].ProdPerHour / 3600;

      // For either of the two cases of prodType (Gold or Mana)
      // here's where you would add an additonal switch case if you
      // want to add more than two in-game currencies to your game
      //
			switch (prodType) {
			case "Gold":
          // Add resources to the structure's internal storage
          // only if the storded gold in the building does
          // not exceed the storage cap of that structure
				if (existingEconomyBuildings [i].storedGold + produce < existingEconomyBuildings [i].StoreCap) 
				{
          // add the produce to the structure's total storage
					existingEconomyBuildings [i].ModifyGoldAmount (produce);
          
				
         
          // The following line below is commented out
          // it would display the collect resources icon if >10%
          // have been stored. The uncommented line instead shows
          // The harvest notification when resources have exceeded 1
           //if((float)existingEconomyBuildings [i].storedGold/existingEconomyBuildings [i].StoreCap>0.1f)//to display when 10% full
					if(existingEconomyBuildings [i].storedGold>1)
					DisplayHarvestNotification (i, existingEconomyBuildings [i].storedGold);					
				}					
				break;
			case "Mana":
				if (existingEconomyBuildings [i].storedMana + produce < existingEconomyBuildings [i].StoreCap) 
				{						
          // add the produce to the structure's total storage
					existingEconomyBuildings [i].ModifyManaAmount (produce);
          
        
          // The following line below is commented out
          // it would display the collect resources icon if >10%
          // have been stored. The uncommented line instead shows
          // The harvest notification when resources have exceeded 1 
					//if((float)existingEconomyBuildings [i].storedMana/existingEconomyBuildings [i].StoreCap>0.1f)//to display when 10% full
					if(existingEconomyBuildings [i].storedMana>1)
					DisplayHarvestNotification (i, existingEconomyBuildings [i].storedMana);	
				}
				break;				
			}	
			valuesChanged = true;
		}			
	}
}

The below screenshot shows what a harvest notification looks like above buildings, and as you can read in the source excerpt above, this notification shows when greater than 1 is ready for collection (tap or click to collect). This can be changed to show when a certain percent of the internal storage is reached for that structure, like 10% as seen in the commented out line in the function above.

624

Currency generation. Click to view larger.

After a certain amount is reached, the value of the resource yet to be collected appears above the resource structure. This continues accumulating until you reach the resource cap. In the case of the above example

EconomyBuilding.cs

How to get the "gameObject" of each EconomyBuilding (from the script "script/Creators/EconomyBuilding"):

The EconomyBuilding script acts like a production account (as opposed to a bank account). Each building that produces something is registered in the ResourceGenerator along with its index for unique identification. This script is not attached to the building so you can recover it.

1280

Click to view larger.

If you need to register/retrieve the building position, you can record this information with the StructureSelector script that all buildings have. Buildings based on grid position already register the grid col/row to calculate the position. Modify the behaviour of this class for structures to be aware of its position on the map.

1280

Click to view larger.

What is internal storage?

To keep the player engaged with your game they collect resources from their resource generators by tapping or clicking on the generator to add the total resources generated since last harvest collection to the player's stats.

<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-->

Waiting too long means they miss out on resources that are generated because each building has a maximum storage cap defined in the XML/Buildings.xml as seen above. This StoreCap item is used in the RunEconomy() function to throw away resources gained per second if the storage cap has been reached.

// Excerpt from RunEconomy() function in
// Scripts/Creators/ResourceGenerator.cs
// this function runs once per second

// The following checks if the stored gold plus the resources
// generated in the last second exceed the storage cap
// If exceeded, resources are discared until the player collects
// the stored resources.

if (existingEconomyBuildings [i].storedGold + produce < existingEconomyBuildings [i].StoreCap) 
					{
  					// Adds resources
						existingEconomyBuildings [i].ModifyGoldAmount (produce);
						
  					// Displays harvest notification reminder
						if(existingEconomyBuildings [i].storedGold>1)
						DisplayHarvestNotification (i, existingEconomyBuildings [i].storedGold);					
					}

Can I remove the storage cap from buildings?

Yes. If you still want the resource structures to collect resources until they've been tapped, but not allow the resources to generate automatically without the need to collect - then change the StoreCap variable to an incredibly high value, such as the below example:

<StoreCap>2147483647</StoreCap>

Can I make resource generate automatically without collection?

Yes, if you change the StoreType from Internal to Distributed then the resource are automatically added to the player stats rather than being stored in the resource collectors until the structure's StoreCap is reached.

<StoreType>Distributed</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 -->

What happens when you tap the structure to harvest?

First, you should understand that every building has a unique structureIndex ID (for example, 1, 2, 3, etc.) this allows us to know which resource building we are collecting resources from. This structureIndex is set on the PlaceStructure() function triggered when you are placing a structure purchased in the store. See the excerpt below:

// Excerpt from Scripts/Creators/BaseCreator.cs
// when placing a structure, it adds a unique number
// to the existing structure index so we can identify this structure
// when tapping on it

	public void PlaceStructure()
	{
		Vector3 
		grassPos = selectedGrass.transform.position,
		structurePos = selectedStructure.transform.position;
    
    // Only runs the following on first place, not when reselecting a building
		if(!isReselect)
		{			
      // Increments the structureIndex
			((Stats)stats).structureIndex++;
      
      //unique number for harvesting, the structureIndex we just incremented
			structureIndex = ((Stats)stats).structureIndex;
      
      //.....

With a structureIndex variable attached to every building, we can then call the Harvest() function in ResourceGenerator.cs.

But first, we need to detect when the player clicks on the structure. The ReSelect() function in Scripts/Creators/StructureSelector.cs does just that.

When a building is selected, this function is called. In the checks - pointed out at the end of this excerpt below we can call the Harvest function with the proper structure index.

// Excerpt from Scripts/Creators/StructureSelector.cs
// ReSelect() function is triggered when selecting a building

	public void ReSelect()
	{
		if(((Relay)relay).delay||((Relay)relay).pauseInput) return;
		// Jump animation when selecting a building
		((StructureTween)tween).Tween();
    // Play the select sound effect
		((SoundFX)soundFX).Click();

    // Only do the following if we're on the home base and not an enemy map
		if(!battleMap)
		{		
      // If the building hasn't already just been selected
			if(!((StructureCreator)structureCreator).isReselect &&
				!((Relay)relay).pauseInput)
				{

        // Do the following only if there is a notification for collection
        // above the resource generator
				if (messageNotification != null&&((MessageNotification)messageNotification).isReady) 
					{
          // Fade the notification message out
					((MessageNotification)messageNotification).FadeOut ();
          
          // Run the harvest resources from ResourceGenerator.cs
          // with the structureIndex
					resourceGenerator.Harvest (structureIndex);
					return;
					}
        
     // ........

The Harvest() function in Scripts/Creators/ResourceGenerator.cs called from ReSelect() in Scripts/Creators/StructureSelector.cs does the total resource addition to the stats.

It's actually quite simple. Since ReSelect told us the structureIndex, all we need to do is loop through the economy buildings until we found the structure that matches the structureIndex value. Then determine its type of resource and add this resource to the player's total. See the excerpt below:

// Excerpt from Scripts/Creators/ResourceGenerator.cs
// Harvest() function collects the resources from the structure
// and puts them into the player stats

public void Harvest(int index)
{
  // Find the economy building that matches the structureIndex called from ReSelect() function in StructureSelector.cs
	for (int i = 0; i < existingEconomyBuildings.Count; i++) 
	{
    // Found a match
		if (existingEconomyBuildings [i].structureIndex == index) 
		{
      // Check what Production Type the structure is
			switch (existingEconomyBuildings [i].ProdType) 
			{
			case "Gold":
          // Add the gold resources from the stored value to the stats
				((Stats)stats).AddResources ((int)existingEconomyBuildings [i].storedGold, 0, 0);
          // Reset the stored gold value
				existingEconomyBuildings [i].storedGold -= (int)existingEconomyBuildings [i].storedGold;
				break;
         
			case "Mana":
          // Add the gold resources from the stored value to the stats
				((Stats)stats).AddResources (0, (int)existingEconomyBuildings [i].storedMana, 0);
          // Reset the stored gold value
				existingEconomyBuildings [i].storedMana -= (int)existingEconomyBuildings [i].storedMana;
				break;
			}
      // Remove the notification icon
			ResetHarvestNotification(i);
      
      // Call an update to the UI so that the new gold shows
			((Stats)stats).UpdateUI ();
			break;
		}	
	}
}

Resetting the harvest notification

At the end of the function above this line resets the gather resource notification so it no longer appears until the RunEconomy() described above triggers the notification again.

ResetHarvestNotification(i);

Below is an example of what the resource building looks like after resources have been gathered.

644

Tapping the building to gather resources. Click to view larger.

How are player stats updated?

Seen in the above Harvest() function excerpt, the last line calls a UI update which then reflects the changes from 99900 to after 99916 with the 16 gold collected from the gold mine forge in the below screenshots.

((Stats)stats).UpdateUI ();
298

Gold total before gathering resources. Click to view larger.

304

Gold total gained +16 after gathering resources.. Click to view larger.

Where are the prefabs?

All of the game object prefabs are set in the Game scene Game manager. Look at the below screenshots:

275

Game scene Game Manager > SaveLoadMap

360

Inspector Resource generator prefabs. Click to view closer.

In addition, you will want to look at GameManager > Creators > BuildingCreator (prefabs are also there) and Map01 scene GameManager > SaveLoadBattle. This is discussed in the Buildings > Part 2: Customize Menus section of the documentation. Prefabs are used by the creator for construction and by SaveLoadBattle for loading during battle.

GameManager > Creators > BuildingCreator

In the GameManager > Creators > BuildingCreator we have the list of game object prefabs used by the creator in addition to certain build settings used by the Scripts/Creators/BaseCreator.cs script. Let's describe these below. But first, here's how to open the BuildingCreator Inspector

273

Game scene Game Manager

365

Resource generator prefabs in the BuildingCreator

In the Inspector you'll notice a few arrays, here's a description of each one. It's the same for every type of game object you can build in the game except for the RemovableCreator (removables are not for players to construct but rather remove -- see Player Removable Objects doc for details)

Array TitleDescription
Structure PfThe structure prefab. Order in this list matches the exact order of the XML items which the Creator matches the prefab with.
Grass Pf1x1 to 5x5 dark green grass collider grid prefabs list. These you don't have to edit, they are shared by all structures in the game based on their grid size.
Construction PfUnder construction prefab list. There's 3 different sizes of this for 1x1 to 3x3 grid size construction projects.
Grass TypesSize of this array matches the the Structure Pf array size. We tell which Grass Pf element to use with each structure. Depends on structure size whether they take 1x1 (Grass Pf element 0) like a wall segment or 3x3 (Grass Pf element 2) like the large gold vault. Tatami is the only object that takes grass collider 5x5 ( Grass Pf Element 4).
Construction TypesArray size matches Structure Pf. Like grass types, we match the construction prefab grid size too. Since there's 3 different sizes of construction prefabs, this ranges from values 0 to 2. By default, we set most structures to use the 3x size.
Pivot CorrectionsArray size matches Structure Pf. Odd size grid structures (1x1 and 3x3) need a pivot correction so they don't appear accidentally off-center, taking more grid space than necessary. Pivot Correction does this.
Is ArrayArray size matches Structure Pf. If set to 1, uses the row making field builder for construction instead of the usual construction. The only objects that use this are the wall segments that let you pick a start and end point and automatically constructs a repeating row of the structure between the points.
Is InstantArray size matches Structure Pf. For items you set TimeToBuild to 0 (instant build) in the XML, you also want to set the elements Is Instant boolean to 1 in this array. The only objects that use this in the demo are the wall segments.

What about resource storage structures?

Locate the Resource Storage section of the documentation on the right for details about the resource storage building examples included with the kit.