Files
Battle-for-Tismo/shared/data/buildings.js
T
adrien bd9b206708 Gave the new buildings real effects
The catalogue had grown a barracks, wartime shelters, an air-defense
battery, a warm-water port and a shipyard, but only as data: infantry
still trained without a barracks, shelters did nothing, and an airport was
just an airbase. Each building now names the rule it grants with a
`mechanic` id, so the simulation and the city panel describe the same
thing without magic strings.

- Barracks and shipyards open one more production line each. A line sticks
  to one entry at full rate, so two units build at once rather than the
  head absorbing every line; the base behaviour (one queue, overflow
  carrying into the next entry) is unchanged.
- Wartime shelters keep 10% of civilians per level safe from bombardment
  and are very hard to knock down, and ranged fire can now destroy a
  building level outright, with no refund. Each building rolls its own
  chance per point of damage, from a generator seeded off the world so a
  bombardment replays identically.
- Air defense fires one volley at a hostile aircraft the moment it enters
  the city tile, scaled by its level; a plane shot down never drops its
  bombs.
- A port adds 1000 GDP per capita per level, per adjacent sea tile, to
  every tile in its region.
- An airport draws a daily trickle of people from every other airport city
  in the world, scaled by the destination's level.
- Wired the new effects into the city panel and taught the repeatable
  Industrial Automation to satisfy other technologies' prerequisites.

Added tests for each mechanic and for the parallel lines.
2026-09-21 11:38:01 +02:00

166 lines
5.5 KiB
JavaScript

// Buildings that can be raised in a city. Build costs are fixed and grow only
// with the level, with no level cap; upkeep is 1% of that cost, so it follows
// the level too.
import { EFFECT_GDP, EFFECT_BUDGET_INCOME, EFFECT_RESEARCH, EFFECT_CULTURE, effect } from "./effects.js";
// Buildings whose benefit is a rule rather than a stat effect. Kept as ids so
// the simulation and the UI can name them without magic strings.
export const BUILDING_MECHANIC = {
// Units: one more parallel training line per level.
PARALLEL_TRAINING: "parallel_training",
// Buildings: one more parallel construction line per level.
PARALLEL_BUILDING: "parallel_building",
// Cuts civilian deaths from bombing, and is very hard to knock down.
CIVILIAN_SHELTER: "civilian_shelter",
// Fires one volley at hostile aircraft passing over the city.
AIR_DEFENSE: "air_defense",
// Flat GDP per capita for the city's region, per adjacent sea tile.
PORT_GDP: "port_gdp",
// Lets people fly in from any other city with an airport.
AIR_IMMIGRATION: "air_immigration",
};
export const BUILDINGS = [
{
id: "market",
name: "Market",
description: "A hub of local trade. Raises the GDP per capita of the city's region, with diminishing returns.",
baseCost: 500_000,
costAlpha: 1.2,
refundFraction: 0.5,
effects: [effect(EFFECT_GDP, 0.04, 0.75)],
icon: "icon_market.svg",
},
{
id: "bank",
name: "Bank",
description: "Channels private wealth into the state coffers. Raises the tax collected from the city's region.",
baseCost: 1_000_000,
costAlpha: 1.3,
refundFraction: 0.5,
effects: [effect(EFFECT_BUDGET_INCOME, 0.05, 0.7)],
icon: "icon_bank.svg",
},
{
id: "barracks",
name: "Barracks",
description: "Enables training infantry units. Each level allows one more parallel training.",
baseCost: 10_000_000,
costAlpha: 1.1,
refundFraction: 0.5,
effects: [],
mechanic: "parallel_training",
icon: "icon_barracks.svg",
},
{
id: "shelters",
name: "Wartime shelters",
description: "Each level reduces civilian life loss from bombing by 10%. Extremely hard to destroy. Does not protect other buildings.",
baseCost: 100_000_000,
costAlpha: 2,
refundFraction: 0.5,
effects: [],
mechanic: "civilian_shelter",
civilianProtectionPerLevel: 0.1,
// Multiplies the odds of the city losing a level of this building to a
// bombardment: at a tenth of the normal chance it is very hard to destroy.
destructionResistance: 0.1,
icon: "icon_shelters.svg",
},
{
id: "aa_building",
name: "Air defense",
description: "Damages hostile aircraft that fly above this city.",
baseCost: 1_000_000_000,
costAlpha: 2,
refundFraction: 0.5,
effects: [],
mechanic: "air_defense",
icon: "icon_aa_building.svg",
},
{
id: "research_lab",
name: "Research lab",
description: "Applies science to industry and government. Produces research points for the whole nation.",
baseCost: 100_000_000,
costAlpha: 1.65,
refundFraction: 0.5,
effects: [effect(EFFECT_RESEARCH, 1.0, 0.9)],
icon: "icon_research_lab.svg",
},
{
id: "university",
name: "University",
description: "Higher education produces research and a little culture for the whole nation.",
baseCost: 100_000_000,
costAlpha: 1.7,
refundFraction: 0.5,
effects: [effect(EFFECT_RESEARCH, 2.0, 0.8), effect(EFFECT_CULTURE, 0.5, 0.7)],
icon: "icon_university.svg",
},
{
id: "museum",
name: "Museum",
description: "Preserves the nation's heritage, raising its culture output across the country.",
baseCost: 50_000_000,
costAlpha: 1.6,
refundFraction: 0.5,
effects: [effect(EFFECT_CULTURE, 1.5, 0.85)],
icon: "icon_museum.svg",
},
{
id: "cinema_studio",
name: "Cinema studio",
description: "Mass media spreads the nation's culture, raising its culture output across the country.",
baseCost: 50_000_000,
costAlpha: 1.75,
refundFraction: 0.5,
effects: [effect(EFFECT_CULTURE, 3.0, 0.7)],
icon: "icon_cinema_studio.svg",
},
{
id: "port",
name: "Port",
description: "Warm water port. Gains 1000 GDP/capita per tile per level.",
baseCost: 20_000_000,
costAlpha: 1.7,
refundFraction: 0.5,
effects: [effect(EFFECT_BUDGET_INCOME, 0.08, 0.7)],
// Every tile the city's region covers gains this much GDP per capita for
// each sea tile next to the city, per port level.
mechanic: "port_gdp",
gdpPerCapitaPerSeaTilePerLevel: 1000,
icon: "icon_port.svg",
coastal: true,
},
{
id: "airport",
name: "Airport",
description: "An airfield with a control tower. Lets the city train aircraft and serves as a home airbase for them to land and refuel. Immigration can reach this city from any other city in the world with an airport. The effect scales with airport level.",
baseCost: 250_000_000,
costAlpha: 1.7,
refundFraction: 0.5,
effects: [effect(EFFECT_GDP, 0.05, 0.8)],
mechanic: "air_immigration",
icon: "icon_airport.svg",
},
{
id: "shipyard",
name: "Shipyard",
description: "Naval yards that build warships. Only a coastal city can raise one, and it must already have a port. Each level adds one parallel building queue.",
baseCost: 150_000_000,
costAlpha: 1.65,
refundFraction: 0.5,
effects: [],
mechanic: "parallel_building",
icon: "icon_shipyard.svg",
coastal: true,
requiresBuilding: "port",
},
];
export function buildingById(id) {
return BUILDINGS.find((b) => b.id === id) || null;
}