feat: New theme + wire price adjustement

This commit is contained in:
gauvainboiche
2026-10-08 12:25:45 +02:00
parent aa9721ac2a
commit 1734487f1e
19 changed files with 348 additions and 88 deletions
+20 -8
View File
@@ -3,7 +3,7 @@
// browser and in Node (tests, balance simulations).
import { computeModifiers } from './effects.js';
import { bulkCost, clamp, demandPerSecond, maxAffordable } from './formulas.js';
import { bulkCost, clamp, demandPerSecond, materialBatch, maxAffordable } from './formulas.js';
const MAX_STEP_SECONDS = 1;
@@ -38,6 +38,13 @@ export function derive(state, ctx) {
}
const demandMultiplier = mods.demand * rules.marketing.demandPerLevel ** state.marketing;
const batch = materialBatch(
rules.materialMarket,
state.totalProduced,
rate,
state.materialFactor,
mods.batchDiscount,
);
return {
clickYield: rules.click.yield * mods.click,
perGenerator,
@@ -46,8 +53,8 @@ export function derive(state, ctx) {
demand: demandPerSecond(rules.market, state.price, demandMultiplier),
valueMultiplier: mods.value,
materialPerUnit: rules.unit.materialPerUnit / mods.materialEfficiency,
batchSize: rules.materialMarket.batchSize,
batchCost: Math.ceil(rules.materialMarket.basePrice * state.materialFactor * mods.batchDiscount),
batchSize: batch.size,
batchCost: batch.cost,
autoBuyMaterial: mods.autoBuyMaterial,
marketingCost: Math.ceil(rules.marketing.baseCost * rules.marketing.costGrowth ** state.marketing),
};
@@ -121,9 +128,12 @@ function stepMaterialMarket(state, ctx, dt, rng) {
state.materialTimer += dt;
while (state.materialTimer >= m.updateEverySeconds) {
state.materialTimer -= m.updateEverySeconds;
const shock = 1 + (rng() - 0.5) * 2 * m.volatility;
let shock = 1 + (rng() - 0.5) * 2 * m.volatility;
if (rng() < m.spikeChance) shock *= rng() < 0.5 ? m.spikeSize : 1 / m.spikeSize; // shortage or glut
const pulled = state.materialFactor + (1 - state.materialFactor) * m.reversion;
state.materialFactor = clamp(pulled * shock, m.minFactor, m.maxFactor);
const next = clamp(pulled * shock, m.minFactor, m.maxFactor);
state.materialTrend = Math.sign(next - state.materialFactor);
state.materialFactor = next;
}
}
@@ -137,9 +147,11 @@ function step(state, ctx, dt, rng, totals) {
state.units += made;
state.totalProduced += made;
// Automatic restock when the stock runs low.
if (d.autoBuyMaterial && state.material < d.batchSize / 2 && state.funds >= d.batchCost) {
buyMaterial(state, ctx);
// Automatic restock: patient while the price is high, urgent when nearly out.
if (d.autoBuyMaterial && state.funds >= d.batchCost) {
const { autoBuyBelowFactor } = ctx.rules.materialMarket;
const low = state.material < d.batchSize / 2 && state.materialFactor <= autoBuyBelowFactor;
if (low || state.material < d.batchSize / 10) buyMaterial(state, ctx);
}
// Customers buy what they want, up to what is in stock.