feat: Cards writings and balancing (M8)

This commit is contained in:
gauvainboiche
2026-10-25 18:30:43 +01:00
parent 04193e2013
commit c2103c32e7
43 changed files with 25930 additions and 397 deletions
+15 -2
View File
@@ -4,6 +4,7 @@ import { STATE_VERSION, IND_IDS, VAR_IDS, qualityFromRatio } from "./state.js";
import { computeFiscal, computeDevs, advanceEconomy } from "./economy.js";
import { applyShifts, ageBias } from "./modifiers.js";
import { stepSectors } from "./sectors.js";
import { stepWorld } from "./world.js";
import { stepIndicators, stepVars } from "./indicators.js";
import { checkGameOver } from "./gameover.js";
@@ -43,6 +44,7 @@ export function createGame({ scenario, balance, seed = Date.now(), countryName,
sectors,
indicators: { ...scenario.indicators },
modifiers: [],
world: { cycle: 0 }, // global business cycle, see world.js
flags: {},
cardHistory: [],
pendingCard: null,
@@ -51,7 +53,8 @@ export function createGame({ scenario, balance, seed = Date.now(), countryName,
// Any true flag here pauses time (see advanceDay).
pending: { profile: !PRONOUNS.includes(pronouns), weeklyCard: true, review: true, alert: false },
over: null,
risk: { revolution: 0, coup: 0, impeachment: 0, defaultZone: false }, // days in each danger zone
// days in each danger zone; emergency = an unscheduled budget session is open (see advanceDay)
risk: { revolution: 0, coup: 0, impeachment: 0, defaultZone: false, emergency: false, lastEmergency: -999 },
alerts: [], // urgent telegrams waiting to be read, oldest first
history: { t: [], series: {} },
log: [],
@@ -111,6 +114,7 @@ export function advanceDay(state, bal) {
if (isWaiting(state)) return { advanced: false, blocked: "pending", events: null };
applyShifts(state, bal);
stepWorld(state, bal);
const fiscal = computeFiscal(state, bal);
const devs = computeDevs(state, bal, fiscal);
@@ -123,6 +127,7 @@ export function advanceDay(state, bal) {
state.day += 1;
const events = { weeklyCard: false, review: false, termEnd: false, gameOver: null };
const alertsBefore = state.alerts.length;
const fallen = checkGameOver(state, bal);
if (fallen) {
state.over = { type: fallen, day: state.day };
@@ -135,7 +140,15 @@ export function advanceDay(state, bal) {
} else {
if (state.day % bal.time.historyEvery === 0) recordHistory(state, bal);
if (state.day % bal.time.daysPerWeek === 0) state.pending.weeklyCard = events.weeklyCard = true;
if (state.day % bal.time.daysPerQuarter === 0) state.pending.review = events.review = true;
if (state.day % bal.time.daysPerQuarter === 0) {
state.pending.review = events.review = true;
state.risk.emergency = false;
} else if (state.alerts.length > alertsBefore && state.day - state.risk.lastEmergency >= bal.gameOver.emergencyCooldown) {
// A new danger warning: the cabinet meets at once, so the player can react before the next quarter.
state.pending.review = events.review = true;
state.risk.emergency = true;
state.risk.lastEmergency = state.day;
}
}
return { advanced: true, blocked: null, events };
}