fix: Fixing the MP power bonus + seed maintenance

This commit is contained in:
gauvainboiche
2026-04-03 14:25:19 +02:00
parent b11446cf56
commit d345c025c0
11 changed files with 349 additions and 132 deletions
+45 -2
View File
@@ -4,13 +4,24 @@ import {
getGridCells,
addEconScore,
setElementBonus,
getElementBonus,
getMilitaryDeductions,
resetTeamActions,
} from "./db/gameDb.js";
import { computeTeamIncome, computeTeamElementBonus } from "./helpers/economy.js";
import { computeTeamIncome, computeTeamElementBonus, computeTeamMilitaryPower } from "./helpers/economy.js";
import { nextResetUtc, resetUserActionsByTeam } from "./db/usersDb.js";
import { buildRealtimeSnapshot } from "./realtimeSnapshot.js";
import { broadcast } from "./ws/hub.js";
import { broadcast, broadcastToTeam } from "./ws/hub.js";
const TICK_SECONDS = 5;
const TEAMS = ["blue", "red"];
let lastTickSeed = null;
let lastQuotaSlot = null;
function currentQuotaSlot(intervalSeconds, epochSec) {
const nowSec = Math.floor(Date.now() / 1000);
return Math.floor((nowSec - epochSec) / intervalSeconds);
}
/**
* Starts the server-side economy tick loop.
@@ -50,6 +61,38 @@ export function startEconTick() {
await setElementBonus(worldSeed, "blue", blueBonus);
await setElementBonus(worldSeed, "red", redBonus);
// ── Actions quota reset (on every new interval slot) ─────────────────
const intervalSec = cfg.actionsResetIntervalSeconds ?? 3600;
const epochSec = cfg.timingEpochSec ?? 0;
const quotaSlot = currentQuotaSlot(intervalSec, epochSec);
if (lastQuotaSlot !== null && quotaSlot !== lastQuotaSlot) {
const nextReset = nextResetUtc(intervalSec, epochSec).toISOString();
const elementBonus = await getElementBonus(worldSeed);
const milDeductions = await getMilitaryDeductions(worldSeed);
for (const team of TEAMS) {
// ── Team quota: base + military bonus, written to DB ──────────────
const milPower = computeTeamMilitaryPower(team, rows, cfg.militaryPower ?? {});
const milNet = milPower - (milDeductions[team] ?? 0);
// milNet is in "billions of military-weighted population".
// The UI displays milNet * 1000; the bonus formula applies to that display scale:
// floor(displayedValue / 1000) = floor(milNet * 1000 / 1000) = floor(milNet).
const milBonus = Math.floor(Math.max(0, milNet));
const teamQuota = cfg.teamActionQuota + milBonus;
await resetTeamActions(team, teamQuota, nextReset);
broadcastToTeam(team, "team-quota-updated", { team, actionsRemaining: teamQuota });
// ── Per-user quota: element bonus scales the daily quota ──────────
const teamElemBonus = elementBonus[team] ?? 0;
const effectiveUserQuota = Math.floor(cfg.dailyActionQuota * (1 + teamElemBonus / 100));
await resetUserActionsByTeam(team, effectiveUserQuota, nextReset);
}
console.log(`[quota] Slot ${lastQuotaSlot}${quotaSlot}; user & team quotas reset.`);
}
lastQuotaSlot = quotaSlot;
const snapshot = await buildRealtimeSnapshot(worldSeed);
broadcast("snapshot", snapshot);
} catch (e) {