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

For some examples of buildings being placed on a couple different maps check out the scenes located in …/CityBuilderCore.Tests/Other/BuildingPlayground.

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

Core Building Components

High level overview of the core building components of CCBK and their walkers, mouse over a component for a short explanation.

Building Requirements

In CCBKs default implementations whether a building can be placed in a certain position is ultimately up to the tool placing it. The BuildingBuilder tool that is used for most buildings in the demos checks whether the cost defined in BuildingInfo can be payed and whether all the points are inside the maps boundaries. It also calls the BuildingInfo methods CheckBuildingAvailability for each individual point and CheckBuildingRequirements for every building.

By default CheckBuildingAvailability checks if the points are blocked by the map or a structure that occupies the same level. CheckBuildingRequirements on the other hand makes sure that all the BuildingRequirements and RoadRequirements defined on the BuildingInfo are fulfilled. Both of these can be overridden in inherited classes so if, for example, you need only one of the BuildingRequirements to be fulfilled you can create a custom BuildingInfo like this:

using CityBuilderCore;
using System.Linq;
using UnityEngine;

[CreateAssetMenu(menuName = "CityBuilder/" + nameof(BuildingInfoX))]
public class BuildingInfoX : BuildingInfo
{
    public override bool CheckBuildingRequirements(Vector2Int point, BuildingRotation rotation)
    {
        if (BuildingRequirements != null && BuildingRequirements.Length > 0 && BuildingRequirements.All(r => !r.IsFulfilled(point, Size, rotation)))
            return false;
        if (RoadRequirements != null && RoadRequirements.Length > 0 && RoadRequirements.All(r => !Dependencies.Get<IRoadManager>().CheckRequirement(rotation.RotateBuildingPoint(point, r.Point, Size), r)))
            return false;
        return true;
    }
}

When you look at a BuildingRequirement in the inspector, the top fields(Mode, Points, Count) define how success for the entire building is determined while the lower(Map, Building) sections define how the individual points are checked. Basically the points of the building are checked against the lower portion and whether that allows placing the building is determined by the upper parameters. For a good example of this check out the differences between the GraniteMineInfo and the IronMineInfo in the three demo.

The RoadRequirement lets you specify that certain points of a building need to be placed on a road. A simple example of this is the RoadBlockerInfo which just needs its single point to be placed on any kind of road. The StageInfo is a bit more advanced since it needs certain points to be placed on the upgraded STR stage of the roads.