Classic City Builder Kit
by Softleitner





read manual online at
https://citybuilder.softleitner.com/manual
for support please contact
softleitner@gmail.com

Overview


permalink: /manual title: “Overview” sidebar: title: “Manual” nav: manual —

Welcome

This is the manual for Classic City Builder Kit by SoftLeitner. Classic City Builder Kit is quite the mouthful so i will be referring to it using the shorthand CCBK.

Oldschool walker based City Builders are very systems heavy games that require lots of tweaking and balancing to get right. CCBK was created with the aim of providing all the common tropes of the genre and making them easily accessible in the Editor.

The kit was created with the classic evolve housing, build monuments type of game in mind and most of the systems are commonly seen in that genre. That being said large parts like Buildings, Items, Walkers and Layers are general enough to create a wide variety of games.

Project Structure

CCBK is separated into multiple assemblies. Which ones you need depends on how you are planning to use the Kit. For your first exploration create a new project and remove the example assets and materials, then import the entire asset. Importing project settings is optional except for TagManager if you want to run the demos.

  • CityBuilderCore
    The Core Framework of CCBK.
    Always import this one.

  • CityBuilderCore.Tests
    Tests some core functionality of CityBuilderCore.
    Only import this if you plan to change CityBuilderCore and want to check if the basic systems still function.

  • CityBuilderThree
    Contains the 3D City Builder demo
    Import if you want to start by adapting this demo.
    For the menu to work add the Menu, StageOne, StageTwo, StageThree scenes in Build Settings.

  • CityBuilderDefense
    Contains the 2D Tower Defense demo
    Import if you want to start by adapting this demo.

  • CityBuilderManual
    Holds completed samples of the HowTo section of this manual.
    Import if you’re stuck on a how to or exploring.

Both demos depend on either layers, tags or sorting layers. If these settings were not set during import please copy the contents of TagManager.txt from the demo folder to the TagManager.asset in you ProjectSettings.

Dependencies

Usage

After familiarizing yourself with CCBK you should be ready to start your project. I’ll outline three basic levels of usage for CCBK here. The first two don’t require any coding, implementing custom systems assumes basic knowledge of C#.

  • Adapting one of the Demos
    Is one of the demos close enough to what you are trying to achieve? Great!
    Import it along with CityBuilderCore and the Settings and start tweaking. The content of the demos is explained in detail in the 3D City Builder and 2D Tower Defense manual pages.

  • Starting from Scratch using Core Logic
    If none of the demos gets close enough to what you want to make or you want to make sure you understand every piece of your project starting from scratch is the way to go. Continue Here for a step to step guide to creating a city builder purely in Unity Editor.

  • Implementing Custom Logic
    Need some special sauce in your game and know basic C#. Continue Here for a step to step guide to extending CCBK with your own components and systems.

Feedback

The quickest channels to reach me are mail and discord. Please feel free to reach out with any problems and questions. Feedback regarding the general direction of CCBK and particular future features are also always welcome. Though I might not immediately be able to incorporate your requests I very much take them into consideration when planning out future updates.

If you can spare the time please consider leaving a review in the asset store.

Release Notes


permalink: /manual/releases title: “Release Notes” sidebar: title: “Manual” nav: manual —

1.3.0

ADDED

  • Timings system (events, animations and text based on playtime)
  • Hexagon support in Setup, Map, Tiles, …
  • Decorator Structures that save rotations and sizes
  • Object Generator for easy map object generation

IMPROVED

  • FireWalker in Three Demo now actively walks to and extinguishes fires
  • Walkers use better points to enter and exit buildings(Pathfinding accepts multiple starts/ends)
  • BuildingRequirement can now require Buildings(see BuildingRequirementDebugging)
  • DefaultGameManager now saves the current randomization state

FIXED

  • AccessType Exclusive
  • Rotations in XY Maps

1.2.0

ADDED

  • Overview Windows for Buildings, Walkers and Items
    these display all the objects in a set with preview images
    objects can be filtered, cloned and deleted

IMPROVED

  • Complete visual overhaul of 3D City Builder Demo
    • 25 Original Low Poly Buildings
    • Humanoid Walkers with Animations
    • Maps, Props, Materials, Effects, …
  • Updated “Start from Scratch” Tutorial
    • Incorporates new Setup and Overview Windows
    • New sprites for Buildings and Walkers

CHANGED

  • Common walker properties have been moved to WalkerInfo
    PathTyp, PathTag, Speed, MaxWait, Delay

FIXED

  • Expandable buildings not loading their expansion
  • Buildings having wrong scale after being affected by BuildingAddonTransformer
    this lead to buildings in the three demo always being slightly off scale or very off scale when the framerate was low
  • Roads for Bridge being amended without rotation
  • Path Recalculation for moving walkers in Defense Demo
  • Roads being demolished when their RoadBlocker was demolished
    Roads are “underlying” and therefore only demolished when no non “underlying” structure is demolished at the same time
  • Pooled walkers retaining their items and state

1.1.0

ADDED

  • Setup Wizard window
    creates a clean project template with placeable buildings
    configure display modes, axis, sizes, … in a simple dialog
  • Expandable Buildings
    building size is determined during building
    expand building in one or two dimensions
    showcased in the new bridge building of THREE demo
  • enhanced Full 3D support
    showcased in new 3D demo scene in THREE demo
    support for perspective camera and 3D roads
    height parameter in walkers can modify their display
    (move along terrain or change to different layer in tunnel)
  • Road Switching
    allows destination walkers to move between road networks
    showcased in SwitchRoadDebugging scene in tests and tunnel scene in urban demo

IMPROVED

  • Building Requirements now support various modes and configurations
  • Road Requirements can now be configured to amend missing roads
  • Cell Size of grid is taken into account in default and isometric map

CHANGED

  • RoadBuilding functionality has been merged into regular Buildings

FIXED

  • incorrect camera area when camera was pitched enough to look up
  • structure level editor not working inside arrays
  • monument pathing when using worker pooling

1.0.0

ADDED

  • urban demo project
    simple city sim in isometric 2d
    showcases various 1.0 features
  • connections core system
    build a network of feeders and passers
    enables water and electricity networks
  • connected tiles that switch sprite based on their neighbors
    simple base class and variants for rectangle and isometric grids

IMPROVED

  • walkers can now be pooled using ObjectPool
  • roads now support multiple networks
    simply use MultiRoadManager instead of DefaultRoadManager

    rails and roads in urban demo

  • structures now support multiple levels
    easily control which levels a structure inhabits using the level toggles

    a single point in the urban demo can have a pipe, road and power line; pumps inhabit all three levels

  • new view type that displays building efficiency

CHANGED

  • demo materials have been switched from urp to legacy shaders
  • sort axis moved to camera controller

FIXED

  • blockers not working after save/load
  • building walkers not triggering on spawn
  • panning in xy isometric maps
  • speed controls in historic demo

0.9.0

Initial Release

3D City Builder


permalink: /manual/three title: “3D City Builder” sidebar: title: “Manual” nav: manual —

Play it here, uses pretty much every system in CCBK except attacks.

While the visuals are now fully 3D this demo still uses Tilemaps for its logic. This means the 2D Tilemap Editor is still required. For example the type of ground is still determined by the ground Tilemap, it is just invisible because its renderer has been disabled. So to block building or set layer values based on ground you need to enable the renderer, draw your changes and then disable it again.

Buildings

Housing

Property Property HousingPlaceholderComponent Prefab: Tent
Tent Tent HousingComponent
EvolutionComponent
RiskerComponent
Capacity: 5 Plebs
Evolution: Housing
Collapse: 1/s Disease: 3/s
Hut Hut HousingComponent
EvolutionComponent
RiskerComponent
Capacity: 10 Plebs
Evolution: Housing
Collapse: 3/s
House House HousingComponent
EvolutionComponent
RiskerComponent
Capacity: 15 Plebs
Evolution: Housing
Collapse: 3/s
Villa Villa HousingComponent
EvolutionComponent
RiskerComponent
GenerationComponent
Capacity: 15 Plebs
Evolution: Housing
Collapse: 3/s
Interval: 10 Items: 20 Gold

Risks&Services

Well Well EmploymentComponent
ServiceWalkerComponent
Group: Services Needed: 5 Plebs
Downtime: 5 Prefab: WaterWalker
Workshop Workshop EmploymentComponent
RiskWalkerComponent
Group: Services Needed: 5 Plebs
Downtime: 5 Prefab: CollapseWalker
Firefighter Firefighter EmploymentComponent
RiskWalkerComponent
Group: Services Needed: 5 Plebs
Downtime: 5 Prefab: FireWalker
Doctor Doctor EmploymentComponent
RiskWalkerComponent
Group: Services Needed: 5 Plebs
Downtime: 5 Prefab: DiseaseWalker
Treasurer Treasurer EmploymentComponent
CollectionComponent
Group: Services Needed: 5 Plebs
Downtime: 5 Prefab: TreasureWalker Storage: Global

Food

Farm Farm EmploymentComponent
ProductionComponent
LayerEfficiencyComponent
Group: Food Needed: 15 Plebs
Interval: 10 Produces: 100 Potatoes
Layer: Water Min: 0.2 Max: 100
Hunter Hunter EmploymentComponent
ItemsRetrieverComponent
Group: Food Needed: 10 Plebs
Retriever: HunterWalker Downtime: 10
Silo Silo EmploymentComponent
StorageComponent
Group: Logistics Needed: 10 Plebs
Storage: Stacked StackCount: 6 Capacity: 4
Orders: Accept Potato, Meat
Market Market EmploymentComponent
DistributionComponent
Group: Services Needed: 10 Plebs
Storage: Unit Capped Capacity: 5 MinimumOrder: 1 Orders: Fill Potato, Meat

Production

IronMine Iron Mine EmploymentComponent
ProductionComponent
Group: Production Needed: 10 Plebs
Interval: 20 Produces: 1 Iron
GraniteMine Granite Mine EmploymentComponent
ProductionComponent
Group: Production Needed: 10 Plebs
Interval: 20 Produces: 1 Granite
Smith Smith EmploymentComponent
ProductionComponent
Group: Production Needed: 10 Plebs
Interval: 10 Consumes: 1 Iron Produces: 10 Tools
Yard Yard EmploymentComponent
StorageComponent
Group: Logistics Needed: 10 Plebs
Storage: Stacked StackCount: 8 Capacity: 4
Orders: Accept Iron, Tools, Granite Refuse Potato, Meat

Workers

LabourCamp Labour Camp CyclicWorkerProviderComponent
ItemEfficiencyComponent
Prefab: LabourWalker Downtime: 5
Item: Tools Interval: 10
MasonCamp Mason Camp PooledWorkerProvider Prefab: MasonWalker Count: 2 Downtime: 3
EntertainerCamp Entertainer Camp CyclicWorkerProviderComponent
RiskerComponent
LayerAffector
Prefab: EntertainerWalker
Risk: Fire Increase: 5/s
Layer: Desirability Value: -10 Range: 3 Falloff: -3

Other

ObelisksSite Obelisks Site MonumentSiteComponent Stages: CirclyPits, CenterPit, CircleObelisk, CenterObelisk
various steps with different workers per stage
Obelisks Obelisks    
Stage Stage WorkerUserComponent
LayerAffectorWorking
Worker: Entertainer Quantity: 1 Queue: 2 Duration: 20
Layer: Entertainment Value: 100 Range: 10
Garden Garden LayerAffector Layer: Desirability Value: 10 Range: 3 Falloff: 3
RoadBlocker Road Blocker HousingComponent Health: 100
Bridge Bridge    

Structures

Tree Tree StructureCollection
LayerAffector
Key: TRE Destr: 1 Deco: 0 Walk: 0 Size: 1
Layer: Desirability Value: 5 Range: 2 Falloff: 2
Ore Ore StructureCollection
LayerAffector
Key: ORE Destr: 0 Deco: 0 Walk: 0 Size: 2
Layer: Iron Value: 10 Range: 1
Rubble Rubble StructureCollection Key: RUB Destr: 1 Deco: 1 Walk: 0 Size: 1

Walkers

Migration

ImmigrationWalker ImmigrationWalker Path: Map Capacity: 5
EmigrationWalker EmigrationWalker Path: Map Capacity: 5
HomelessWalker HomelessWalker Path: Road Capacity: 1

Roaming

WaterWalker ServiceWalker Path: RoadBlocked Service: Water Amount: 100/s
CollapseWalker RiskWalker Path: RoadBlocked Risk: Collapse Amount: 100/s
DiseaseWalker RiskWalker Path: RoadBlocked Risk: Disease Amount: 100/s
SickWalker RiskWalker Path: Road Risk: Disease Amount: -10/s
FireWalker RiskWalker Path: RoadBlocked Risk: Fire Amount: 100/s
TreasureWalker CollectionWalker Path: RoadBlocked Items: Gold
SaleWalker SaleWalker Path: RoadBlocked Storage: 1 Unit
EmploymentWalker EmploymentWalker Path: RoadBlocked Return: 1

Logistics

DeliveryWalker DeliveryWalker Path: Road Storage: 1 Unit Return: 1
StorageWalker StorageWalker Path: Road Storage: 1 Unit Return: 1
PurchaseWalker PurchaseWalker Path: Road Storage: 2 Unit

Workers

LabourWalker WorkerWalker Path: Road Worker: Laborer Storage: 1 Unit
MasonWalker WorkerWalker Path: Road Worker: Mason Storage: 1 Unit
EntertainerWalker WorkerWalker Path: Road Worker: Entertainer Storage: 1 Unit

Items

Gold Gold Key: GLD Unit Size: 1
Potato Potato Key: PTT Unit Size: 100
Meat Meat Key: MEA Unit Size: 100
Iron Iron Key: IRN Unit Size: 1
Tools Tools Key: TOL Unit Size: 10
Granite Granite Key: GRT Unit Size: 1

2D Tower Defense


permalink: /manual/defense title: “2D Tower Defense” sidebar: title: “Manual” nav: manual —

Art assets have been adapted from packs made by Kenney

Play it here, primarily uses the attacks and items retriever resource systems.

Buildings

Center Center AttackableComponent Health: 100
Tower Tower DefenderComponent Distance: 2
Cooldown: 1.5
Damage: 2
Lumberjack Lumberjack ItemsRetrieverComponent Storage: Global
Walker: LumberjackWalker
StoneQuarry Stone Quarry ItemsRetrieverComponent Storage: Global
Walker: StoneQuarryWalker

Structures

Wall Walls StructureTiles Key: STO Replicates to WallObstacles
Trees Trees StructureCollection
Tree > ReloadingItemsDispenser
Key: TRE Prefab: Tree
Key: TRE Charges: 1 Reload: 5
Rocks Rocks StructureCollection
Rock > ReloadingItemsDispenser
Key: ROK Prefab: Rock
Key: STO Charges: 1 Reload: 5

Walkers

AttackWalker AttackWalker AttackWalker Path: MapGrid Speed: 3
Health: 10 Damage: 5 Rate: 5
LumberjackWalker LumberjackWalker ItemsRetrieverWalker Path: Map Speed: 2
Distance: 10 DispenserKey: TRE
StoneQuarryWalker StoneQuarryWalker ItemsRetrieverWalker Path: Map Speed: 2
Distance: 10 DispenserKey: STO

Items

Stone Stone
Wood Wood

2D City Sim


permalink: /manual/urban title: “2D City Sim” sidebar: title: “Manual” nav: manual —

Art assets have been adapted from sprites made by opengameart user pixel32

Play it here.

Demonstrated Connections, Multi-Road-Networks and Multi-Level-Structures.

Buildings

Railstation Railstation RailwayComponent Goods OXX
House House ConnectionPasserComponent
LayerEfficiencyComponent
HouseComponent
Power
Water
Van
OXX
Shop Shop ConnectionPasserComponent
LayerEfficiencyComponent
ShopComponent
Power
Water
Money
OXX
WaterPump Water Pump ConnectionPasserComponent
ConnectionFeederComponent
LayerEfficiencyComponent
Power
Water
Water
XXX
PowerStation Power Station ConnectionFeederComponent Power OXX

Structures

PowerLines Power Lines StructureTiles
ConnectionPasser
POW
Power
OOX
Pipes Pipes StructureTiles
ConnectionPasser
PIP
Water
XOO

Walkers

Train Train TrainWalker Rail
Truck Train TruckWalker Road
100 Goods
Van Train VanWalker Road
5 Goods

How To 2D City Builder


permalink: /manual/two title: “2D City Builder” layout: single classes: ‘’ toc: true toc_label: “Chapters” toc_icon: city toc_sticky: true sidebar: title: “Manual” nav: manual —

Throughout the following steps we will create a very simple oldschool city builder from scratch using CCBK. Play an advanced version of it here.

This page covers only the first two evolutions, water and food. A completed version with all stages can be found in the CityBuilderManual project. I believe you will be able to figure the rest out after following the steps laid out here. Religion is very similar to water and pottery has just a slightly longer production chain than food.

Setup

  • Create a new unity project using the 2D template
  • Import TMP Essential Resources (Windows/TextMeshPro/…)
  • Import the CCBK Core Framework

Import
(Import the Asset normally, the video imports a custom package because it was made pre release)

  • Generate a basic Sprite based Game (Window/CityBuilder/Setup)

Import

You are now left with a very basic but already runnable game. Save/Load, SpeedControls, Minimap and some other small features are already fully functional. The left bar contains Tools that can build a road and a building that spawns a walker on those roads as well as a demolish tool that destroys them. A single item has also been created that is used up when building.
Check out the Grid Object in the Scene to find stuff related to the grid and the tiles on it. See the Logic Object to see all kinds of Managers that are commonly used. The DefaultItemManager for example manages Items and has a setting that determines the items at the start of the game.
Various Assets have also been generated. The City folder holds all the different parts that make up a city in CCBK.
If you see any gaps between sprites try disabling Anti-Aliasing.

Map

  • Place the Manual Assets inside your Assets folder
  • Open the Tile Palette Tab found in Windows/2D
    • Make sure your active Tilemap is ‘Ground’ and your Palette is ‘HTPalette’
    • Draw your map inside the guide lines of the map(turn on gizmos if you cant see it)

Ground
We’ll later add a water layer that spreads out two tiles from water. I’ ve drawn grass tiles there to communicate that to the player.

  • On DefaultMap(Grid) replace the groundBlocked Tile in Walking- and Building Blocking Tiles with the same HTWater you just painted onto the ground TileMap
  • Set Rotation to Mirror
  • Find the RoadTool(UI/Tools)
    • Replace its Background Image with HTRoadSN
    • On the RoadTool itself click the Road to select it in the Project View
    • Replace the Tile with HTRoad

When you start the game now you should be able to draw some nice connecting roads everywhere but on the water.

Water

Supply

  • Find the HouseTool(UI/Tools)
    • Rename it to WaterSupplyTool
    • Replace its Background Image with HTWaterSupply
    • Click the BuildingInfo on the BuildingBuilder to select it in the ProjectView
      • Rename the BuildingInfo to WaterSupplyInfo
      • Key > ‘WAT’ ; Name > ‘WaterSupply’
    • Rename the Building Prefab to WaterSupply and open it
      • Remove the WalkerSpawner Component
      • On the SpriteRenderer of the Sprite Object set HTWaterSupply as the Sprite
  • Create a Layer(RMB>Create/CityBuilder/Layer) in the City folder named ‘WaterLayer’
  • In the Scene find the DefaultLayerManager(Logic) and add an affecting tile entry
    WaterLayer
  • Back in the WaterSupplyInfo add a BuildingRequirement
    WaterLayer

  • Create a Service(RMB>Create/CityBuilder/Layer) in the City folder named ‘WaterService’

Carrier

  • Open up the WalkerBase Asset
    • On the Sprite Object add the following
      • Animator (Controller > HTAnimator)
      • UnityAnimatorEvent (Parameter > ‘walking’)
      • UnityAnimatorEventVector (Parameter > ‘direction’ ; Set Y > TRUE)
  • Rename WalkerInfo(City/Walkers) to ‘WaterCarrierInfo’
  • Rename the Walker Prefab to WaterCarrier and open it
    • Sprite > HTCarrierD1 ; Animator > HTCarrier
    • Replace the RoamingWalker Script with a ServiceWalker
      • Service > WaterService ; Amount > 1000
      • Hook WalkingChanged up to SetBool on the UnityAnimatorEvent(Sprite)
      • Hook DirectionChanged up to SetVector3 on the UnityAnimatorEventVector(Sprite)
  • On the WaterSupply Building Prefab add a ServiceWalkerComponent
    • Walker > WaterCarrier ; Downtime > 5

You should now be able to place Water Supplies but only directly next to Water Tiles. They should spawn Water Carriers when connected to Roads that are correctly animated.

Food

Wheat

  • Select currently only Item(City/Items)
    • Rename the Asset itself to Gold
    • Key > ‘GOL’ ; Name > ‘Gold’
  • Create an Empty Gameobject in your Scene
    • Reset its Position
    • Name it WheatVisual
    • Drag the Sprites HTWheatG1-4 from Project View onto WheatVisual
      • Order In Layer > 15
    • Add a StorageQuantity Visual to WheatVisual
      • Swap > TRUE ; Objects > HTWheatG1-4
    • Drag WheatVisual into the Items folder and delete it from the Scene
  • Create an Item(RMB>Create/CityBuilder/Item) named ‘Wheat’
    • Key > ‘WHT’ ; Name > ‘Wheat’ ; UnitSize > 100
    • Visuals > WheatVisual
    • Add it to the Items Set by selecting it and clicking ‘Find in Folder’

Cart Pusher

  • Open up the Walkers Window(Window/CityBuilder/Walkers)
  • Copy WaterCarrier and call the new Walker ‘CartPusher’
    • Open the Prefab by double clicking the preview image
    • Sprite > HTPusherD1 ; Animator > HTPusher
    • Replace the ServiceWalker Script with DeliveryWalker

Farm

  • Open up the Buildings Window(Window/CityBuilder/Walkers)
  • Copy WaterSupply with Key > FAM ; Name > Farm
  • Open the Info by double clicking the entry
    • Building Requirement - Mode > Average
    • Size > 3x3
  • Open the Prefab by double clicking the preview image
    • Move Pivot X > 1.5 Y > 1.5
    • Sprite > HTFarm
    • Remove ServiceWalkerComponent
    • Add ProductionComponent
      • Interval > 20
      • Add Items Producer
        • Items Item > Wheat ; Quantity > 100
        • Storage Mode > Free Unit Capped ; Capacity > 1
      • DeliveryWalkers Prefab > CartPusher
    • Drag the Sprites HTFarmProgress1-4 from Project View onto Sprite
      • Reset the Positions and set Order In Layer > 15
    • Add ProgressThresholdVisualizer
      • Component > ProductionComponent ; Swap > TRUE
      • Add 4 Elements to Progress Thresholds
      • 0.2 > HTFarmProgress1 ; 0.4 > HTFarmProgress2
      • 0.6 > HTFarmProgress3 ; 0.8 > HTFarmProgress4
  • Back in the Scene find WaterSupplyTool(UI/Tools) and clone it
    • Rename it to FarmTool
    • BuildingBuilder BuildingInfo > FarmInfo
    • Background Image > HTFarm

You should now be able to build Farms that visualize their progress and spawn walkers whenever they are done. We’ll take care of storage next so they will have somewhere to go.

Granary

  • Open up the Buildings Window(Window/CityBuilder/Walkers)
  • Copy WaterSupply with Key > GRN ; Name > Granary
  • Open the Info by double clicking the entry
    • Remove the Building Requirement
    • Size > 4x4
  • Open the Prefab by double clicking the preview image
    • Move Pivot X > 2 Y > 2
    • Sprite > HTGranary
    • Remove ServiceWalkerComponent
    • Add StorageComponent
      • Storage Mode > Stacked ; Stack Count > 8 ; Capacity > 4
      • Order Item > Wheat ; Ratio > 1
    • Add StorageQuantityVisualizer
      • Add 8 Transforms under the Sprite
      • Move them to about the center of the granary openings
      • Add the to the Origins Array
  • Back in the Scene find WaterSupplyTool(UI/Tools) and clone it
    • Rename it to GranaryTool
    • BuildingBuilder BuildingInfo > GranaryInfo
    • Background Image > HTGranary

The Farms Cart Pushers should now carry the Wheat to the Granary. The quantity stored in a Granary should be properly visualized.

Buyer & Seller

  • Open up the Walkers Window(Window/CityBuilder/Walkers)
  • Copy WaterCarrier and call the new Walker ‘BazaarBuyer’
    • Open the Prefab by double clicking the preview image
      • Sprite > HTBuyerD1 ; Animator > HTBuyer
      • Replace the ServiceWalker Script with PurchaseWalker
      • Storage Capacity > 3
  • Copy WaterCarrier and call the new Walker ‘BazaarSeller’
    • Open the Info by double clicking the entry
      • PathType > RoadBlocked
    • Open the Prefab by double clicking the preview image
      • Sprite > HTSellerD1 ; Animator > HTSeller
      • Replace the ServiceWalker Script with SaleWalker

Bazaar

  • Open up the Buildings Window(Window/CityBuilder/Walkers)
  • Copy WaterSupply with Key > BAZ ; Name > Bazaar
  • Open the Info by double clicking the entry
    • Remove the Building Requirement
  • Open the Prefab by double clicking the preview image
    • Sprite > HTBazaar
    • Remove ServiceWalkerComponent
    • Add DistributionComponent
      • Storage Capacity > 5
      • Order Item > Wheat ; Ratio > 1
      • Purchase Walker Prefab > BazaarBuyer
      • Sale Walker Prefab > BazaarSeller ; Downtime > 5
      • Minimum Order > 2
  • Back in the Scene find WaterSupplyTool(UI/Tools) and clone it
    • Rename it to BazaarTool
    • BuildingBuilder BuildingInfo > BazaarInfo
    • Background Image > HTBazaar

The Bazaar will do nothing but spawn Sellers for now. It will only send out Buyers once a Seller has reported that Buildings on its path need Wheat.

Peasants

Housing

  • Create a Population(RMB>Create/CityBuilder/Population) in the City folder named ‘PeasantPopulation’
    • Key > ‘PST’ ; Name > ‘Peasant’
  • Open up the Buildings Window(Window/CityBuilder/Walkers)
  • Copy Bazaar with Key > H1 ; Name > H1Hut
  • Open the Prefab by double clicking the preview image
    • Sprite > HTHut
    • Remove DistributionComponent
    • Add HousingComponent
      • Add a Population Housing entry with Population > PeasantPopulation ; Quantity > 20
  • Copy H1Hut with Key > H2 ; Name > H2Shanty
  • Open the Prefab by double clicking the preview image
    • Sprite > HTShanty
    • Quantity > 35
  • Copy H1Hut with Key > H3 ; Name > H3Cottage
  • Open the Prefab by double clicking the preview image
    • Sprite > HTCottage
    • Quantity > 50
  • Copy H1Hut with Key > H0 ; Name > H0Property
  • Open the Prefab by double clicking the preview image
    • Sprite > HTHousing
    • Remove HousingComponent
    • Add HousingPlaceholderComponent with Prefab > H1Hut
  • Back in the Scene find WaterSupplyTool(UI/Tools) and clone it
    • Rename it to HousingTool
    • BuildingBuilder BuildingInfo > H0PropertyInfo
    • Background Image > HTHut

Migration

  • Open up the Walkers Window(Window/CityBuilder/Walkers)
  • Copy WaterCarrier and call the new Walker ‘Immigrant’
    • Open the Info by double clicking the entry
      • PathType > MapGrid
    • Open the Prefab by double clicking the preview image
      • Sprite > HTMigrantD1 ; Animator > HTMigrant
      • Replace the ServiceWalker Script with ImmigrationWalker
      • Capacity > 10
  • Copy Immigrant and call the new Walker ‘Emigrant’
    • Open the Prefab by double clicking the preview image
      • Replace the ImmigrationWalker Script with EmigrationWalker
  • On the Logic Object in the Scene add a Migration Component
    • Immigration Walkers Prefab > Immigrant ; Count > 10
    • Emigration Walkers Prefab > Emigrant ; Count > 10
    • Entry > Logic ; Population > PeasantPopulation
  • On the Logic Object add a DefaultPopulationManager

When you start the game now and build Housing the Migration should spawn Immigrants that occupy the properties and turn them into Huts.

Evolution

  • Create an EvolutionSequence(RMB>Create/CityBuilder/EvolutionSequence) in the City folder named ‘HousingEvolution’
    • 0 Building Info > H1HutInfo
    • 1 Building Info > H2ShantyInfo Services > WaterService
    • 2 Building Info > H3CottageInfo Items > Wheat
  • Add Evolution Components to H1Hut, H2Shanty and H3Cottage with
    • Evolution Sequence > HousingEvolution
    • ServiceRecipient
      • Service > WaterService ; Loss Per Second > 5
    • ItemsRecipient(only H2 and H3)
      • Item > Wheat ; Consumption Interval > 2
      • Storage > Free Item Capped ; Capacity > 10

Your Huts should now turn into Shanty when a Water Carrier passes them. Once a BazaarSeller provides them with Wheat they should turn into Cottages. You might want to give yourself some more gold by increasing the Quantity in DefaultItemManager(Logic).

How To Custom Systems


permalink: /manual/custom title: “Custom Systems” sidebar: title: “Manual” nav: manual —

In this section i will walk you through creating a custom system in CCBK. The system itself is not especially useful but it contains implementations of all the most important parts of the framework.

A completed, playable version can be found in the Custom folder of the CityBuilderManual project within the CCBK asset.

Building Component

We will start off with a pretty basic building component. All it will do is keep a building effective for a certain duration and then disrupt it until it is reset.

Before actually creating the component let’s add an interface for the component so we can easily add other components for the same purpose or switch out the implementation. This step can be skipped, using the component directly instead of an interface works too.

public interface ICustomBuildingComponent : IBuildingComponent
{
    void DoSomething();
}

Next add a script that inherits from BuildingComponent and implements the interface.

public class CustomBuildingComponent : BuildingComponent
{
    public override string Key => "CCO";

    public GameObject GoodVisual;
    public GameObject BadVisual;

    public float Duration;

    private float _time;

    private void Update()
    {
        if (_time > 0)
        {
            _time -= Time.deltaTime;
        }

        GoodVisual.SetActive(IsWorking);
        BadVisual.SetActive(!IsWorking);
    }

    public void DoSomething()
    {
        _time = Duration;
    }
}

As you can see i’ve added the reset logic and some GameObjects for visualization. The Code is mandatory for building components and is used to identify the component in save/load. We’ll add the save logic next, put the following at the end of your script.

#region Saving
[Serializable]
public class CustomComponentData
{
    public float Time;
}

public override string SaveData()
{
    return JsonUtility.ToJson(new CustomComponentData()
    {
        Time = _time
    });
}
public override void LoadData(string json)
{
    var data = JsonUtility.FromJson<CustomComponentData>(json);

    _time = data.Time;
}
#endregion

As you can see saving usually contains a data class that stores all the runtime data of the component. The building component base class provides overridable save and load methods that are called by the building. Saving is optional, if the methods are not overridden or return empty not data will be saved.

The last thing we need is for the component to influence the buildings efficiency. We do this by implementing IEfficiencyFactor

public class CustomBuildingComponent : BuildingComponent, ICustomBuildingComponent, IEfficiencyFactor
{
    public override string Key => "CCO";

    public bool IsWorking => _time > 0;
    public float Factor => _time > 0 ? 1 : 0;
...

Building Trait

A BuildingTrait is a special BuildingComponent that always creates a Reference an is stored in a special collection within the BuildingManager. This is done so they can be retrieved without having to iterate through all the buildings on the map. The interface for it looks like this.

public interface ICustomBuildingTrait : IBuildingTrait<ICustomBuildingTrait>
{
    float CustomValue { get; }

    void DoSomething();
}

The minimal implementation for the Trait is similar to a normal component.

public class CustomBuildingTrait : BuildingComponent, ICustomBuildingTrait
{
    public override string Key => "CTR";

    public float CustomValue => 1;

    public BuildingComponentReference<ICustomBuildingTrait> Reference { get; set; }

    public override void InitializeComponent()
    {
        base.InitializeComponent();

        Reference = registerTrait<ICustomBuildingTrait>(this);
    }
    public override void OnReplacing(IBuilding replacement)
    {
        base.OnReplacing(replacement);

        var replacementTrait = replacement.GetBuildingComponent<ICustomBuildingTrait>();

        replaceTrait(this, replacementTrait);
    }
    public override void TerminateComponent()
    {
        base.TerminateComponent();

        deregisterTrait<ICustomBuildingTrait>(this);
    }

    public void DoSomething()
    {
        Debug.Log("Hello!");
    }
}

The major difference to normal components is that we have to manage a reference throughout the lifecycle of the component. It has to be created when the building is build, passed on when it is replaced and removed when the building gets demolished.

The purpose of the trait is to spawn walkers so we will return to it after creating some custom walkers.

Walker

The first walker we will add is a roaming walker that resets every ICustomBuildingComponent it passes. CCBK has a base class called BuildingComponentWalker for exactly this purpose.

public class CustomRoamingWalker : BuildingComponentWalker<ICustomBuildingComponent>
{
    protected override void onComponentEntered(ICustomBuildingComponent buildingComponent)
    {
        base.onComponentEntered(buildingComponent);

        buildingComponent.DoSomething();
    }
}

Thats it, whenever the walker passes a ICustomBuildingComponent onComponentEntered will be called. The base class also provides onComponentRemaining in case you want to do something as every frame the component is in reach instead of just the first one.

The second most prevalent kind of walker in city builder are destination walkers. The one we’ll add is fairly simple since it gets its path passed to it from outside. It will follow that path it is given and call a method on its target when it is finished.

public class CustomDestinationWalker : Walker
{
    public enum CustomDestinationWalkerState
    {
        Inactive = 0,
        Walking = 1
    }

    private CustomDestinationWalkerState _state = CustomDestinationWalkerState.Inactive;
    private BuildingComponentReference<ICustomBuildingTrait> _target;

    public void StartWalker(BuildingComponentPath<ICustomBuildingTrait> customPath)
    {
        _state = CustomDestinationWalkerState.Walking;
        _target = customPath.Component;
        walk(customPath.Path);
    }

    protected override void onFinished()
    {
        if (_target.HasInstance)
            _target.Instance.DoSomething();

        base.onFinished();
    }

    #region Saving
    [Serializable]
    public class DeliveryWalkerData
    {
        public WalkerData WalkerData;
        public int State;
        public BuildingComponentReferenceData Target;
    }

    public override string SaveData()
    {
        return JsonUtility.ToJson(new DeliveryWalkerData()
        {
            WalkerData = savewalkerData(),
            State = (int)_state,
            Target = _target.GetData()
        });
    }
    public override void LoadData(string json)
    {
        var data = JsonUtility.FromJson<DeliveryWalkerData>(json);

        loadWalkerData(data.WalkerData);

        _state = (CustomDestinationWalkerState)data.State;
        _target = data.Target.GetReference<ICustomBuildingTrait>();

        switch (_state)
        {
            case CustomDestinationWalkerState.Walking:
                continueWalk();
                break;
        }
    }
    #endregion
}

The _state variable is only added so the walker can be correctly restored when loading. The _target is stored so the walker can call DoSomething on it when it is reached.
The WalkerData field in the save data contains all the basic data of the walker like current position and path which enables you to just call continueWalk in Load.

WalkerSpawner

To actually spawn walkers from buildings CCBK uses something called in WalkerSpawner. These come in Cyclic, Pooled and Manual varieties and are serializable field that are added to building components. In Unity versions prior to 2020.1 generic fields do not get serialized which which is why you will see concrete spawner implementations at the end of all the walker classes in CCBK. If you are using such a version add the spawners to the walkers.

/// <summary>
/// concrete implementation for serialization, not needed starting unity 2020.1
/// </summary>
[Serializable]
public class ManualCustomRoamingWalkerSpawner : ManualWalkerSpawner<CustomRoamingWalker> { }
/// <summary>
/// concrete implementation for serialization, not needed starting unity 2020.1
/// </summary>
[Serializable]
public class CyclicCustomRoamingWalkerSpawner : CyclicWalkerSpawner<CustomRoamingWalker> { }
/// <summary>
/// concrete implementation for serialization, not needed starting unity 2020.1
/// </summary>
[Serializable]
public class PooledCustomRoamingWalkerSpawner : PooledWalkerSpawner<CustomRoamingWalker> { }

Now add the spawner to the building trait we created earlier.

public CyclicCustomRoamingWalkerSpawner CustomRoamingWalkers;
public CyclicCustomDestinationWalkerSpawner CustomDestinationWalkers;

private void Awake()
{
    CustomRoamingWalkers.Initialize(Building);
    CustomDestinationWalkers.Initialize(Building);
}
private void Update()
{
    if (Building.IsWorking)
    {
        CustomRoamingWalkers.Update();
        CustomDestinationWalkers.Update();
    }
}

Initialization and updating of the spawners is handled by the owning building component. You might have noticed that StartWalker on the destination walker is not called here. While that would be the easier thing to do we’ll move that responsibility out into a manager for the sake of this example.

Manager

Managers are central scripts meant to orchestrate different systematic behaviors. Once again we’ll start by creating an interface.

public interface ICustomManager
{
    float GetTotalValue();
    BuildingComponentPath<ICustomBuildingTrait> GetPath(BuildingReference home, PathType pathType);

    void Add(BuildingComponentReference<ICustomBuildingTrait> trait);
    void Remove(BuildingComponentReference<ICustomBuildingTrait> trait);
}

The manager will be responsible for calculating a total from the CustomValue field of our traits. It will also provide the paths for our destination walkers. Lastly it will be notified when oue of our traits gets built or demolished. Let’ look at the implementation.

public class CustomManager : MonoBehaviour, ICustomManager
{
    public float Multiplier;

    private void Awake()
    {
        Dependencies.Register<ICustomManager>(this);
    }

    public float GetTotalValue()
    {
        return Dependencies.Get<IBuildingManager>().GetBuildingTraits<ICustomBuildingTrait>().Sum(t => t.CustomValue) * Multiplier;
    }
    public BuildingComponentPath<ICustomBuildingTrait> GetPath(BuildingReference home, PathType pathType)
    {
        foreach (var other in Dependencies.Get<IBuildingManager>().GetBuildingTraitReferences<ICustomBuildingTrait>())
        {
            if (other.Instance.Building == home.Instance)
                continue;

            var path = PathHelper.FindPath(home.Instance, other.Instance.Building, pathType);
            if (path == null)
                continue;

            return new BuildingComponentPath<ICustomBuildingTrait>(other, path);
        }

        return null;
    }

    public void Add(BuildingComponentReference<ICustomBuildingTrait> trait)
    {
        Debug.Log("Custom Trait Added!");
    }
    public void Remove(BuildingComponentReference<ICustomBuildingTrait> trait)
    {
        Debug.Log("Custom Trait Removed");
    }
}

To calculate the total value the manager pulls all the traits from the BuildingManager and applies a Multiplier. As mentioned before BuildingManager keeps track of all traits for quick retrieval.
For the path we just loop all traits and return the first one that PathHelper is able to calculate.
The Add and Remove Methods don’t have and function in this demonstration so we’ll just log to check if they work.

Score

To be able to use the total value calculated by the manager in visuals and win conditions we will now create a score. Scores are pretty straightforward ScriptableObjects that are implemented like this.

[CreateAssetMenu(menuName = "CityBuilder/Scores/" + nameof(CustomScore))]
public class CustomScore : Score
{
    public float Multiplier;

    public override int Calculate()
    {
        return Mathf.RoundToInt(Dependencies.Get<ICustomManager>().GetTotalValue() * Multiplier);
    }
}

To see the score add some kind of text to the scene in combination with a ScoreVisualizer. For the score to be calculated you need a ScoreCalculator in the scene. The ScoreCalculator pulls the Scores it has to calculated from a set of scores it retrieves from the Dependencies. To register your custom score for that add an ObjectRepository to the scene and give it a ScoreSet that contains the instance of score used in the visualizer.

Buildings


permalink: /manual/buildings title: “Buildings” sidebar: title: “Manual” nav: manual —

The bread and butter of every good city are, of course, buildings.
In CCBK Buildings do not define any actual behaviour.
Instead they act as containers for components and addons that can be placed on the map.

Global properties of buildings like name, size, prefab and access type are stored in a ScriptableObject called BuildingInfo.

give buildings that spawn roamers a preferred access point to avoid annoying scenarios where roamers spawn wrong because a road was added

A system deeply embedded in buildings is the ability to replace them.
This can be used to change a buildings appearance and behaviour by replacing it with another.

useful for evolving housing, upgradable towers, …

Anything interacting with a Building or one of its parts should not directly carry a reference to it. Instead a BuildingReference can be used which updates its reference when the building is replaced.

The different building parts can either interact directly of through the buildings efficiency.

eg farms growing wheat quicker based on land fertility or storages not accepting wares without enough workers

The efficiency is expressed through two values. IsWorking[bool] is meant to indicate whether the building is generally working or somehow disrupted. The Efficiency[float] expresses how well the building is working from 0-1.

An important field of the Building Component is the Pivot. The Pivot is a transform in the center and root of the Building. It is used to transform and rotate the Building and to place bars and other visuals over the building. If any of these things go wrong check that the Pivot is correctly assigned.

Walkers


permalink: /manual/walkers title: “Walkers” sidebar: title: “Manual” nav: manual —

The primary way to move things about in CCBK.

storage workers moving items, hunters collecting meat, architects inspecting buildings

Path Types

Among other base functions Walkers have a setting for PathType which specifies the kind of pathfinding it will use to get to its destination.

Road

Simple A* Pathfinding inside the road network on the map. Usually used for all kinds of destination walkers.

carriers delivering goods, workers walking to a monument site, …

RoadBlocked

Same as Road but points with RoadBlockers are removed. Usually used for all kinds of roaming walkers.

water carrier distributing out water,

Map

This Pathfinding uses Unity NavMesh. All demo scenes have a gameobject called Navigation that is used purely to generate the NavMesh. To change the NavMesh follow these steps.

  • activate Navigation gameobject
  • adjust the objects inside Navigation
    • make sure Navigation Area is correctly set to Walkable/Not Walkable
  • bake the NavMesh
  • deactivate Navigation gameobject

    immigrants walking to their new homes, hunters walking to pray, …

MapGrid

Simple A* pathfinding of all points on the map that are not occupied. Only feasible for small maps, on larger maps use Map pathfinding instead.

Walker Modes

The walker base class includes helper methods for various modes of walking. These save their states automatically and can easily be continued on loading.

Walk

Directly pass a WalkingPath for the Walker to follow it immediately.

used when the path is checked before the walker is even spawned like storage walkers

TryWalk

Tells the walker to try to find a way to a target or give up after a certain time. The walker can be given a target building or position to check pathfinding by itself or a function that returns one.

deliver walkers spawned by production are spawned and have to figure out a path afterwards

Roaming

The walker randomly walks around while trying to avoid points already visited. It does for a set number of steps specified in Range, how many positions it remembers is defined in Memory.

well workers handing out water, bazaar workers selling food

Wander

Moves to a random adjacent point

homeless walkers

An important field of the Walker Component is the Pivot. The Pivot is a transform in the center and root of the Walker. It is used to transform and rotate the Walker. If any of these things go wrong check that the Pivot is correctly assigned.

Layers


permalink: /manual/layers title: “Layers” sidebar: title: “Manual” nav: manual —

Layers define numeric values for every point on the map.

resources like water and ore, desirability of buildings or even the spreading heat from fires

At the start of the game a layers base values are calculated using predefined tiles. After that LayerAffecters can register with the layer system to add their own values.

Here are some of the ways Layers interact with other systems

  • requirement for building or evolution

    wells need a minimum amount of water, housing needs desirability to evolve

  • (working-)affecter on building

    eg gardens affecting desirability, working stages affect entertainment

  • layer efficiency component affecting building efficiency

    fertility on farm buildings,

  • multiplier for risk increase and service decrease

    fires happen faster in hotter positions and more water is consumed

Resources


permalink: /manual/resources title: “Resources” sidebar: title: “Manual” nav: manual —

The different resource systems deal with creating, moving and consuming items. Items are ScriptableObjects that specify how the item is visualized in storage and UI among other settings.

wood, meat, clay, iron, …

Items are stored in the ItemStorage class which can limit how many items they fit by item quantity, item units or stacks. ItemStorages are either part of building components or a global manager. ItemsStorages on Buildings can be set to global mode so their items go to global storage instead.

gold is stored in global storage, food is stored in buildings

The two essential interfaces regarding resources are IItemReceiver and IItemGiver.

  • Item receivers are building component that accept items from others.
    Other components deliver items to receivers.
  • Item givers are building components that provide certain items for others.
    Other components acquire items from givers.

Storage

Storage Components act as both receivers and givers. They need a StorageOrder for every Item they store. Storage components performs actions in the following order.

  • get items with StorageOrderMode GET from other givers
  • supply receivers with a higher priority with items(production)
  • empty items with StorageOrderMode EMPTY to other receivers

silos, storage yards, …

Production

As long as it is supplied with items specified in ItemsConsumers a production component will periodically use up those and produce the items specified in ItemsProducers. It does not actively get the consumer items but instead registers as an IItemsReceiver. It does however spawn delivery walkers to move produced items to other receivers.

barley farm, brewery, clay pit, potter, …

Distribution

These components send out roaming Sale Walkers that take note of the items IItemRecipients it passes need. They then look for IItemGivers that give out those items and send Purchase Walkers to get them. The Sale Walkers are filled up with items whenever they leave and pass out the items to the IItemRecipient they pass.

markets

Retrieval

Retrieval Components periodically send out walkers that get items from the closest dispenser. They then spawn delivery walkers that try to move them to an items receiver.

hunting lodge, wood cutter, …

Collection

Collection Components spawn walkers that collect items from generation components the pass while roaming. These also use delivery walkers to move the collected items on.

tax collector

People


permalink: /manual/people title: “People” sidebar: title: “Manual” nav: manual —

CCBK supports multiple classes of citizens, create a Population ScriptableObject for each one. Different populations may be able to fill different job openings or pay different tax rates.

plebs, scholars, aristocrats, …

Housing

Housing components provide space for a specified number of a defined population. Migrations control how fast new citizens arrive or leave based on their sentiment value.

One migration script per population is needed which allows different rates of immi-/emigration per population as well as different entry points on the map.

Employment

Directly sustained by the population is the employment system. Individual Buildings either always have full access to the employment pool or they send out an EmploymentWalker that checks if any buildings housing the needed population are nearby.
Employment is mostly used to drive building efficiency.

It is possible to define different groups of employment to specify which buildings get employees first.

essentials like water should not cease operation because ore mining is using up its employees

CCBK comes with a dialog that allows the user to change employment priorities at runtime.

Workers

The worker system is not directly liked to populations but will most likely be effected by building employment/efficiency.
Some buildings need trained workers to function effectively which creates a slightly different kind of production chain.

farms, monuments, …

Services


permalink: /manual/services title: “Services” sidebar: title: “Manual” nav: manual —

Services are values on Buildings that decrease over time and influence building efficiency and evolution. ServiceWalkers roam around filling the Service values of ServiceRecipients they pass.

water access, religion, education, …

Risks


permalink: /manual/risks title: “Risks” sidebar: title: “Manual” nav: manual —

Risks are values on Buildings that increase over time and cause some event when full. RiskWalkers roam around reducing the Risk values of RiskRecipients they pass.

fire, collapse, disease

CCBK comes with Risks that add Addons to Buildings or replace the Building with other structures or Buildings.
To add Risks that execute other actions simply inherit from Risk and implement the Execute and Resolve methods.

Monuments


permalink: /manual/monuments title: “Monuments” sidebar: title: “Manual” nav: manual —

Monuments are buildings that take time, resources and workers depending on their current stage of construction. They are supplied by the Worker System and, unlike other worker users, provide the workers with a path to their respective work places inside the site when they arrive.

The created building does not necessarily have to be a monument, monument sites can be used for any building that needs time and resources to be built instead of being instantly plopped down.

Attacks


permalink: /manual/attacks title: “Attacks” sidebar: title: “Manual” nav: manual —

The attack system coming with CCBK provides the features needed for basic tower defense functionality. While it is prominently featured in the Defense Demo.

The IHealther interface is used to display the health bars.

i’d love to see a city builder with tower defense mechanics

Timings


permalink: /manual/timings title: “Timings” sidebar: title: “Manual” nav: manual —

This system provides interactions with the current Playtime.

time display in years, days, ..
happenings like catastrophes or blessings
time based weather and lighting

Units

Created using ContextMenu > CityBuilder-TimingUnit these determine how the playtime is partitioned. TimingUnits can be repeating(DayOfWeek, Month, …) or endless(Year). Use the PlaytimeVisual to visualize the progress of a TimingUnit in the UI.

Happenings

Various events that happen at predefined times. Some Happenings have a one off effect at their start or end while others may be active for a period. The different Happenings coming with CCBK can be found in ContextMenu > CityBuilder-Happenings. They are then added to Missions along with a condition that determines when they happen. This means that a Happening may be reused a number of times throughout missions. Adding a title and description to a happening may trigger a dialog at the happenings start or end that display them.

Happenings are relatively easy to extend. Create a new script and derive from the TimingHappening base class. For a Happening that executes once at its start or end override Start or End, for an ongoing effect override Activate and Deactivate.(ie rain from hour 2-3 is an Activate/Deactivate, an earthquake that destroy some buildings at the start of hour 2 uses Start) Check out all the existing Happenings in CityBuilderCore.Systems.Timings.Happenings for examples.

Structures


permalink: /manual/structures title: “Structures” sidebar: title: “Manual” nav: manual —

A structure is basically anything that is placed on the map.
The default structure manager stores basic structures in a dictionary based on the position, so checking and retrieving structures when the position is known is fast. This has the downside that only one regular structure can be stored per position. Since only Buildings are stored this way in Core CCBK this is not a problem.
StructureCollections and Tiles are always stored separately and Roads register themselves as underlying structures which also stored them in a separate list.

Structures are defined by the points they occupy on the map as well as three bit flags:

  • IsDestructible
    Specifies whether the structure can be removed by the player
  • IsDecorator
    Decorator structures are automatically removed when something is built on top of them
  • IsWalkable
    Whether the MapGrid Pathing Type includes the points of the structure

Roads

The DefaultRoadManager is a special structure that includes all the points that are filled out in the TileMap on the GameObject and does pathfinding between them. It is possible to define multiple Roads with different Stages that work similar to Building Evolutions.

simple paths turn into prettier streets when the desirability of the area improves

StructureCollections

A collection of GameObjects that interact with the map somehow.
Only one kind of GameObject is allowed per collection and the prefab has to be specified. This is done so the Structures can be restored after the game is loaded.

3D - trees, rocks, rubble, walls…

StructureTiles

Similar to StructureCollections but using Tiles instead of GameObjects.

2D - trees, rocks, rubble, walls…

Buildings

see Buildings

Dependencies


permalink: /manual/dependencies title: “Dependencies” sidebar: title: “Manual” nav: manual —

Dependencies in CCBK are used similarly to IOC Containers in other areas of development. The implementation however is stripped down to a minimum to accommodate the performance needs of games.
Basically Dependencies allow the registration and retrieval of interfaces. This allows the implementation to be changed and moved without having to rewire all entities that depend on it.

Most systems in CCBK have some central manager component that all the components need access to. Theses managers are not wired up in the editor or implemented as singletons.
Instead the system includes an interface for that manager. The Behaviour that actually implements the interface calls Register on Dependencies when it awakens in the scene. Any components that need the manager call Get on Dependencies.

When possible keep changes to CCBK to a minimum. Instead remove the default implementation from the scene and add your own.

Let’s say you wanted to change how the production components are prioritized for delivered raw materials.

  • copy DefaultItemManager to the project folder and rename it to something like MyProjectItemManager
  • change the code to fit your project
  • replace the item manager in the scene
    • pro tip: switch to debug mode in the inspector and replace the script to keep the field values

Many of the default managers register multiple interfaces for convenience, these can be easily split up thanks to the Dependency system. To replace just one of those interfaces with a custom implementation comment out the line in Awake where that interface is registered. That change will be lost if the Asset is upgraded but should be easy enough to restore.

Dependencies are automatically cleared between scenes.

All interfaces registered with Dependencies are effectively singletons. A possible extension of the system would be passing a tag when registering and getting to partition different areas of dependencies(eg different road managers for underground, ground and sky). CCBK does not include such an extension to keep performance optimal for those that do not need it.

Scores


permalink: /manual/scores title: “Scores” sidebar: title: “Manual” nav: manual —

Scores represent all kinds of numerically quantifiable values for a city. They are used for displaying statistics to the player and checking win conditions.
The different Score Scripts each implement a way of calculating a score value. They are available as ScriptableObjects in the CityBuilder/Scores Context Menu.

You can easily create your own scores by inheriting from Score and implementing the Calculate Method.

Some of the Scores included in CCBK are:

Average Building Score

Calculates the average value from different values assigned to Buildings

Tent:0 Hut:50 Palace:100 > 1xTent 2xHut 2xPalace = 60 Housing Quality

Average Service/Risk Score

Averages out the risk/service value of a defined building category

how well are housings supplied with water, whats the general risk of collapse across my city, …

Building, Item, Population Score

Just counts the number of a building that exist.

how many pyramids have been built, how many diamonds stored, how many plebs live in town, …

Coverage Score

Calculates the number of people buildings would cover against the current population count

1 temple covers 1x100 , 2 shrines cover 2x50 > population=400 => 50% Coverage

Multiplied, Summed, Threshold Score

can be used to transform other scores

culture = entertainment + monuments, different threshold of employment, …

Misc


permalink: /manual/misc title: “Misc” sidebar: title: “Manual” nav: manual —

Saving

CCBK includes a complete save and load system that serializes save data using unity’s json serializer. The save data containers and save/load logic can generally be found in ‘#region Saving’ at the end of the respective script.
Save-/LoadData are perpetuated through the different systems starting at the central manager scripts. This means core components of CCBK like building components and walkers already have overridable Save/Load Methods that will be called without any extra work.
The easiest way to hook data that is outside of CCBK into the save system is to inherit from ExtraDataBehaviour. The default game manager finds all those in its awake Method.

Mission Parameters

Mission, Difficulty and MissionParameters are a proposal for managing different scenarios in your game.
Mission and Difficulty are Scriptable Objects that can be defined in the Editor.
MissionParameters includes all parameters needed to start a game and are passed to the IMissionManager when the scene is loaded.