Files
Battle-for-Tismo/data/proto_building.gd
T
adrien c49899a2fd Initial commit
Server-authoritative Godot 4.6 strategy game.

Includes the headless WebSocket game server, the browser client, and
Nix packaging (server and web-export derivations plus a NixOS module)
for deployment.
2026-09-15 14:48:34 +02:00

75 lines
2.7 KiB
GDScript

class_name ProtoBuilding
extends Resource
## Template for a city building. Concrete instances live under
## res://data/buildings and are edited in the inspector.
##
## Unlike Civilisation's one-off buildings, these can be levelled up and down.
## The build cost and the upkeep grow exponentially with the level (alpha^level)
## while the effects grow linearly or sublinear (see BuildingEffect), so pushing
## a building too high yields diminishing returns for an accelerating bill.
##
## The build cost is based on the owner's GDP: a flat base_cost plus a fraction
## of GDP, both multiplied by cost_alpha^level, so it stays meaningful as the
## economy grows.
## Effect stat keys consumed by GameState.
const EFFECT_GDP := "gdp"
const EFFECT_RESEARCH := "research"
const EFFECT_CULTURE := "culture"
const EFFECT_BUDGET_INCOME := "budget_income"
@export var name : String
@export_multiline var description : String
## Levels the building can reach; 0 means "not built".
@export var max_level : int = 10
## Flat part of the build cost, in budget currency.
@export var base_cost : float = 0.0
## Fraction of the owner's GDP added to the build cost.
@export var cost_gdp_fraction : float = 0.0
## Exponential cost growth per level (alpha in alpha^level).
@export_range(1.0, 5.0) var cost_alpha : float = 1.5
## Flat part of the hourly upkeep, in budget currency.
@export var base_upkeep : float = 0.0
## Fraction of the owner's GDP charged as hourly upkeep.
@export var upkeep_gdp_fraction : float = 0.0
## Exponential upkeep growth per level (alpha in alpha^level).
@export_range(1.0, 5.0) var upkeep_alpha : float = 1.5
## Fraction of the removed level's build cost refunded when downgrading.
@export_range(0.0, 1.0) var refund_fraction : float = 0.5
@export var effects : Array[BuildingEffect] = []
## Budget cost to raise the building from `level` to `level + 1`.
func build_cost(gdp: float, level: int) -> float:
return (base_cost + cost_gdp_fraction * maxf(gdp, 0.0)) * pow(cost_alpha, float(maxi(level, 0)))
## Budget refunded when lowering the building from `level` to `level - 1`.
func refund(gdp: float, level: int) -> float:
return build_cost(gdp, level - 1) * refund_fraction
## Budget upkeep per game hour while the building sits at `level`.
func upkeep(gdp: float, level: int) -> float:
if level <= 0:
return 0.0
var base := base_upkeep + upkeep_gdp_fraction * maxf(gdp, 0.0)
return base * pow(upkeep_alpha, float(level))
## Total contribution to `stat` at `level`, summed over every effect that feeds
## it. Returns 0.0 for an unknown stat or an unbuilt building.
func effect_value(stat: String, level: int) -> float:
var total := 0.0
for effect in effects:
if effect.stat == stat:
total += effect.value_at(level)
return total