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.
149 lines
4.8 KiB
JavaScript
149 lines
4.8 KiB
JavaScript
// Research tree. A technology costs research points and may require earlier
|
|
// technologies before it can be started.
|
|
//
|
|
// Research is focused: a nation picks one technology, and every research point
|
|
// it creates is applied to it, month on month, until it is discovered. A
|
|
// `repeatable` technology may be researched again and again, each level costing
|
|
// `repeatCostGrowth` more than the last, and unlike a discovery it raises no
|
|
// news event (it only notifies the player).
|
|
|
|
import {
|
|
EFFECT_GDP,
|
|
EFFECT_BUDGET_INCOME,
|
|
EFFECT_RESEARCH,
|
|
EFFECT_CULTURE,
|
|
EFFECT_INFANTRY_ATTACK,
|
|
EFFECT_INFANTRY_DEFENSE,
|
|
EFFECT_ARTILLERY_ATTACK,
|
|
EFFECT_CONSTRUCTION_SPEED,
|
|
EFFECT_RAIL_SPEED,
|
|
effect,
|
|
} from "./effects.js";
|
|
|
|
// The tabs the technology panel groups research under.
|
|
export const TECH_THEMES = [
|
|
{ id: "science", name: "Science" },
|
|
{ id: "economy", name: "Economy" },
|
|
{ id: "society", name: "Society" },
|
|
{ id: "military", name: "Military" },
|
|
];
|
|
|
|
export const TECHNOLOGIES = [
|
|
{
|
|
id: "scientific_method",
|
|
name: "Scientific Method",
|
|
description: "A disciplined approach to experiment and evidence. Lays the groundwork for every later technology.",
|
|
theme: "science",
|
|
cost: 20,
|
|
prerequisites: [],
|
|
effects: [effect(EFFECT_RESEARCH, 1.0, 1.0), effect(EFFECT_GDP, 0.02, 1.0)],
|
|
},
|
|
{
|
|
id: "industrial_automation",
|
|
name: "Industrial Automation",
|
|
description: "Robotics and control systems take over the factory floor, lifting national output.",
|
|
theme: "economy",
|
|
repeatable: true,
|
|
cost: 60,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_GDP, 0.08, 1.0)],
|
|
},
|
|
{
|
|
id: "renewable_energy",
|
|
name: "Renewable Energy",
|
|
description: "Clean generation cuts waste and strengthens the public finances.",
|
|
theme: "economy",
|
|
cost: 80,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_GDP, 0.03, 1.0), effect(EFFECT_BUDGET_INCOME, 0.05, 1.0)],
|
|
},
|
|
{
|
|
id: "quantum_computing",
|
|
name: "Quantum Computing",
|
|
description: "Machines that reason in superposition. A step change in the pace of discovery.",
|
|
theme: "science",
|
|
cost: 120,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_RESEARCH, 4.0, 1.0)],
|
|
},
|
|
{
|
|
id: "space_program",
|
|
name: "Space Program",
|
|
description: "Reaching orbit inspires the nation and spins off technology across the economy.",
|
|
theme: "science",
|
|
cost: 300,
|
|
prerequisites: ["industrial_automation", "quantum_computing"],
|
|
effects: [effect(EFFECT_CULTURE, 3.0, 1.0), effect(EFFECT_GDP, 0.05, 1.0)],
|
|
},
|
|
|
|
// Repeatable levels. Each raises a single stat by 1% of its base value.
|
|
{
|
|
id: "infantry_weapons",
|
|
name: "Infantry Weapons",
|
|
description: "Better small arms and training raise the damage infantry deal.",
|
|
theme: "military",
|
|
cost: 40,
|
|
repeatable: true,
|
|
repeatCostGrowth: 0.02,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_INFANTRY_ATTACK, 0.01, 1.0)],
|
|
},
|
|
{
|
|
id: "body_armour",
|
|
name: "Body Armour",
|
|
description: "Personal protection raises infantry base defense.",
|
|
theme: "military",
|
|
cost: 40,
|
|
repeatable: true,
|
|
repeatCostGrowth: 0.02,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_INFANTRY_DEFENSE, 0.01, 1.0)],
|
|
},
|
|
{
|
|
id: "artillery_shells",
|
|
name: "Artillery Shells",
|
|
description: "Improved propellant and shells raise the damage artillery deal.",
|
|
theme: "military",
|
|
cost: 50,
|
|
repeatable: true,
|
|
repeatCostGrowth: 0.02,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_ARTILLERY_ATTACK, 0.01, 1.0)],
|
|
},
|
|
{
|
|
id: "construction_technology",
|
|
name: "Construction Technology",
|
|
description: "Better methods and machines speed every building and unit the nation produces.",
|
|
theme: "economy",
|
|
cost: 50,
|
|
repeatable: true,
|
|
repeatCostGrowth: 0.02,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_CONSTRUCTION_SPEED, 0.01, 1.0)],
|
|
},
|
|
{
|
|
id: "trains_technology",
|
|
name: "Trains Technology",
|
|
description: "Faster locomotives raise movement speed along railways.",
|
|
theme: "economy",
|
|
cost: 50,
|
|
repeatable: true,
|
|
repeatCostGrowth: 0.02,
|
|
prerequisites: ["scientific_method"],
|
|
effects: [effect(EFFECT_RAIL_SPEED, 0.01, 1.0)],
|
|
},
|
|
];
|
|
|
|
export function technologyById(id) {
|
|
return TECHNOLOGIES.find((t) => t.id === id) || null;
|
|
}
|
|
|
|
// The cost of the next level of a technology given how many times it has been
|
|
// researched already. Non-repeatable technologies cost the same either way.
|
|
export function technologyCost(proto, repeatCount = 0) {
|
|
if (!proto) return 0;
|
|
if (!proto.repeatable) return proto.cost;
|
|
const growth = proto.repeatCostGrowth || 0;
|
|
return proto.cost * Math.pow(1 + growth, Math.max(0, repeatCount));
|
|
}
|