Timber Commons - ihsoft/TimberbornMods GitHub Wiki

Timber Commons: Irrigation towers

TimberCommons provides reusable irrigation tower components that other mods can add to their own buildings.

The current public surface is centered on:

Add TimberCommons as a required mod if your mod uses these components:

{
  "Id": "Timberborn.IgorZ.TimberCommons",
  "MinimumVersion": "1.16.0"
}

Use the minimum version that matches the API you rely on.

How irrigation works

An irrigation tower keeps reachable tiles at full moisture while the tower is active.

Important behavior:

  • The irrigation range is measured from the building boundary, not from the building center.
  • Only tiles on the tower's base Z level can be irrigated.
  • Tiles must be connected to the tower through orthogonal neighbors. Diagonal contact alone is not enough.
  • Terrain breaks, different elevations, and full moisture barriers block irrigation reach.
  • The effective range changes with building efficiency.
  • Coverage is the ratio between currently reachable tiles and the maximum possible coverage on flat terrain.
  • Consumption is scaled by Coverage, so a tower that can reach fewer tiles consumes fewer resources.

IrrigationTower is the base component. In most mods, use one of the ready-to-use tower components below instead of deriving from it.

Good-consuming tower

Use GoodConsumingIrrigationTower for a simple tower powered by one consumed good, usually water.

It works together with Timberborn's GoodConsumingBuilding:

  • The building consumes exactly one good.
  • The tower irrigates while the good-consuming building can consume and consumption is not paused.
  • The configured consumption rate should be the maximum-rate value for full coverage.
  • At runtime, TimberCommons scales the consumed good rate by Coverage.
  • If the building has IRangeEffect components, all of them are applied while irrigation is active.
  • EffectGroup is ignored for this tower type.

The tower spec is GoodConsumingIrrigationTowerSpec:

{
  "GoodConsumingIrrigationTowerSpec": {
    "IrrigationRange": 12,
    "IrrigateFromGroundTilesOnly": true
  }
}

Fields:

  • IrrigationRange - maximum irrigation distance from the building boundary.
  • IrrigateFromGroundTilesOnly - when true, only foundation tiles marked as ground-only are used as starting points. Default is true.

Manufactory tower

Use ManufactoryIrrigationTower when irrigation should be driven by recipes.

It works together with Timberborn's Manufactory:

  • The tower acts as the production executor.
  • Do not add another production executor to the same building, such as a workplace or ProductionIncreaser.
  • The tower irrigates while the manufactory is ready to produce.
  • Production progress advances while irrigation is possible.
  • Recipe duration is adjusted by Coverage, so ingredient consumption scales with the area that can actually be irrigated.
  • Range effects can be selected per recipe via the Effects mapping.

The tower spec is ManufactoryIrrigationTowerSpec:

{
  "ManufactoryIrrigationTowerSpec": {
    "IrrigationRange": 12,
    "IrrigateFromGroundTilesOnly": true,
    "Effects": [
      "MyMod.WaterOnly=wet",
      "MyMod.FertilizedWater=fertilized"
    ]
  }
}

Fields:

  • IrrigationRange - maximum irrigation distance from the building boundary.
  • IrrigateFromGroundTilesOnly - when true, only foundation tiles marked as ground-only are used as starting points. Default is true.
  • Effects - recipe-to-effect mappings in the form <recipe id>=<effect group>.

When the current recipe changes, TimberCommons resets effects from the old recipe and applies effects matching the new recipe's group.

Range effects

Range effects are optional components that react to irrigation state.

The interface is IRangeEffect:

  • EffectGroup identifies the effect group.
  • ApplyEffect(HashSet<Vector3Int> tiles) applies the effect to the currently reachable tiles.
  • ResetEffect() removes the effect applied by the last ApplyEffect call.

Multiple effects can use the same group. In that case, all matching effects are applied together.

Growth-rate effect

ModifyGrowableGrowthRangeEffect changes growth speed for growables in range.

{
  "ModifyGrowableGrowthRangeEffectSpec": {
    "EffectGroup": "fertilized",
    "GrowthRateModifier": 25.0,
    "ComponentsFilter": [
      "Timberborn.Forestry.TreeComponent"
    ],
    "PrefabNamesFilter": []
  }
}

Fields:

  • EffectGroup - group name used by ManufactoryIrrigationTowerSpec.Effects.
  • GrowthRateModifier - relative percentage. 25.0 means +25%, -10.0 means -10%.
  • ComponentsFilter - optional full component type names that a growable must have.
  • PrefabNamesFilter - optional exact prefab names to target.

If several growth modifiers affect the same growable, same-type modifiers do not add up. TimberCommons uses the strongest positive modifier and the strongest negative modifier.

Contamination-blocking effect

BlockContaminationRangeEffect blocks contamination on reachable tiles while the effect is active.

{
  "BlockContaminationRangeEffectSpec": {
    "EffectGroup": "wet"
  }
}

Fields:

  • EffectGroup - group name used by ManufactoryIrrigationTowerSpec.Effects.

Choosing a tower type

Use GoodConsumingIrrigationTower when:

  • the building consumes one good continuously;
  • no recipe selection is needed;
  • all range effects should always apply while irrigation is active.

Use ManufactoryIrrigationTower when:

  • the building should use recipes;
  • different recipes should have different effects;
  • the building may consume multiple ingredients or fuel.

Implementation checklist

For a custom irrigation tower building:

  1. Add Timberborn.IgorZ.TimberCommons to your mod dependencies.
  2. Add either GoodConsumingIrrigationTowerSpec or ManufactoryIrrigationTowerSpec to the building blueprint.
  3. Add the matching stock Timberborn components, such as GoodConsumingBuilding or Manufactory.
  4. Configure consumption or recipes for maximum coverage.
  5. Add optional range effect specs to the same building blueprint.
  6. Test the tower on flat ground, near terrain breaks, near moisture barriers, and at reduced efficiency.

Current limitations

  • GoodConsumingIrrigationTower supports exactly one consumed good.
  • Irrigation does not cross terrain elevation changes.
  • Irrigation does not cross full moisture barriers.
  • The tower irrigates only tiles connected to the building through orthogonal neighbors.
  • EffectGroup matters for ManufactoryIrrigationTower; it is ignored by GoodConsumingIrrigationTower.
⚠️ **GitHub.com Fallback** ⚠️