Skip to content

Settlements

Gold

Settlement.SetttlementComponent.Gold

Current Settlement we are at

Settlement.CurrentSettlement

The settlement hero is at currently

Hero.CurrentSettlement

Notables

Settlement.Notables
if (town.Notables.Contains(notable)) return true;

Type of Settlement

bool value
.IsTown
.IsCastle
.IsVillage
.IsHideout
.IsFortification (Town OR Castle)

Granary/food

How much food in the granary:

Settlement.CurrentSettlement.Town.FoodStocks

Max granary amount:

Settlement.CurrentSettlement.Town.FoodStocksUpperLimit()

Build projects

Current build project:

Building building = Hero.MainHero.CurrentSettlement.Town.CurrentBuilding;

Progress percent:

float perc = BuildingHelper.GetProgressOfBuilding(building, settlement.Town) * 100;

Days to complete:

int days = BuildingHelper.GetDaysToComplete(building, settlement.Town);

Building tier:

int tier = BuildingHelper.GetTierOfBuilding(building.BuildingType, settlement.Town)

Buildings in the queue:

Queue<Building> settlement.Town.BuildingsInProgress

Gold in Reserve:

int settlement.Town.BoostBuildingProcess

Construction / "Bricks"

int bricks = settlement.Town.Construction

Construction Cost

int Building.GetConstructionCost()

Building progress - how much is built

float Building.BuildingProgress

Is building default project?

bool building.BuildingType.IsDefaultProject

Town

TradeBoundVillages

Settlement.Town.TradeBoundVillages

Village

GetItemPrice

int GetItemPrice(ItemObject item, MobileParty tradingParty = null, bool isSelling = false)
    return this.TradeBound.Town.MarketData.GetPrice(itemRosterElement, tradingParty, isSelling, null);

VillageState

  • Normal
  • BeingRaided
  • ForcedForVolunteers
  • ForcedForSupplies
  • Looted (same as .IsDeserted)

TradeBound

Returns Town to which the Village is trade bound.

Levels

Village has 3 visual levels. Level depends on hearths:

  • Lvl 1 - hearths 1..199
  • Lvl 2 - 200-599
  • Lvl 3 - 600+
settlement.Village.Hearth
Change village hearths method example
public static void ChangeVillageHearths(Settlement settlement, float hearthsChange)
{
    if (hearthsChange == 0.0 || settlement == null || settlement.Village == null || !settlement.IsVillage || settlement.IsUnderRaid || settlement.IsRaided) return;
    settlement.Village.Hearth += hearthsChange;
}

XML

To be able to change the owner of the settlement in your mod, you need such files:

  • settlements.xml
  • settlements.xslt
  • CUSTOM_settlements.xml

settlements.xml - full if you are working with the Editor, because Editor requires this file and overwrites it with every map save

settlements.xslt - to delete settlements.xml

CUSTOM_settlements.xml - to apply your changes.

What is interesting/weird - if you change name in the settlements.xml - the name of the settlement is changed in the game. But if you change the owner - owner is not changed. Owner is only changed in CUSTOM_settlements.xml, where 'CUSTOM' can be anything.

SubModule.xml should include:
    <XmlNode>
        <XmlName id="Settlements" path="settlements"/>
        <IncludedGameTypes>
            <GameType value = "Campaign"/>
            <GameType value = "CampaignStoryMode"/>
            <GameType value = "CustomGame"/>
            <GameType value = "EditorGame"/>
        </IncludedGameTypes>
    </XmlNode>


    <XmlNode>
        <XmlName id="Settlements" path="CUSTOM_settlements"/>
        <IncludedGameTypes>
            <GameType value = "Campaign"/>
            <GameType value = "CampaignStoryMode"/>
            <GameType value = "CustomGame"/>
            <GameType value = "EditorGame"/>
        </IncludedGameTypes>
    </XmlNode>
Never make changes to the CUSTOM_settlements.xml

Make changes to the settlemens.xml, then make file copy to the CUSTOM_settlements.xml. Otherwise files will be different and Editor uses settlemens.xml and if you change something on the map, changes will go to settlements.xml, it's get deleted with xslt and your CUSTOM file will be used with mismatching map and you will get a crash.

background_mesh

Size: 100x100
SpriteCategory Name="ui_fullbackgrounds"

Note: name of the sprite is with the '_t' at the end: PNG file gui_bg_village_baltic_t.png but in the settlements.xml it's gui_bg_village_baltic

Image for the settlement small icon in the Encyclopedia:

wait_mesh

Size: 445x805
SpriteCategory Name="ui_fullbackgrounds"
Image for the settlement menu and in the Encyclopedia:

background_crop_position

Not used

SettlementComponent
public float BackgroundCropPosition { get; protected set; }

Village
public override void Deserialize(MBObjectManager objectManager, XmlNode node)
base.BackgroundCropPosition = float.Parse(node.Attributes["background_crop_position"].Value);

EmcyclopediaSettlementPageVM
[DataSourceProperty]
public double SettlementCropPosition
{
    get
    {
        return this._settlementCropPosition;
    }
    set
    {
        if (value != this._settlementCropPosition)
        {
            this._settlementCropPosition = value;
            base.OnPropertyChangedWithValue(value, "SettlementCropPosition");
        }
    }
}
no reference in SandBox\GUI\Prefabs\Encyclopedia\EncyclopediaSubPages\EncyclopediaSettlementPage.xml or anywhere else.

castle_background_mesh

Not used

Village
public string CastleBackgroundMeshName { get; protected set; }

base.CastleBackgroundMeshName = node.Attributes["castle_background_mesh"].Value;
and CastleBackgroundMeshName is not used anywhere else.

Settlements Distance Cache

If you add new settlements, or relocate existing ones, you will need to recalculate settlements_distance_cache.bin which the game uses to optimise AI path finding between different settlements.

From my observation: when adding new settlements it's not necessary to recalculate it, game works as it is. It is necessary to recalculate at the end (when all settlements are added) for performance.

The game crashes if settlements.xml and settlements_distance_cache.bin are incompatible.

settlements_distance_cache.bin

Editor does not generate it by default on map save.

If settlements_distance_cache.bin is missing:

  • v1.2.6b - it is generated by the game, when game starts. Visible in the log.
  • v1.2.7 - it is not generated by the game and needs to be manually generated from the Editor.

Can be regenerated with the Editor using SettlementPositionScript

Load time can be long with wrong settlements_distance_cache.bin. Regenerate to solve it.