feat: economy with lazy stock advancement and price curve

This commit is contained in:
2026-06-12 13:58:54 +00:00
parent 3682205580
commit 922926cc6d
3 changed files with 111 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
export const GOODS = ['ore', 'food', 'fuel', 'tech', 'meds', 'luxury'];
export const BASE_PRICE = { ore: 10, food: 8, fuel: 12, tech: 40, meds: 30, luxury: 60 };
export const TYPICAL_STOCK = 120; // stock at which price == base price
export const MAX_STOCK = 2000;
export const NEWS_DAYS_PER_LANE = 1; // price news travels 1 lane per day
export const SNAPSHOT_KEEP = 30; // days of price history kept per planet
export const DOCK_DELAY = 0.25; // days an NPC idles between arrival and replanning
export const INSYS_LEG_DAYS = 0.3; // planet<->planet or planet<->gate hop inside a system
export const OBSERVE_INTERVAL = 0.1; // how often the player's system marks ships as seen
export const VIS_BAND = 0.15; // fraction of a lane near a system that is "inside" it
export const WIN_CREDITS = 100000;
export const PLAYER_START_CREDITS = 1000;
export const PLAYER_CAPACITY = 30;
+37
View File
@@ -0,0 +1,37 @@
import { GOODS, BASE_PRICE, TYPICAL_STOCK, MAX_STOCK } from './constants.js';
// Deterministic price curve: scarce -> expensive. Clamped to [0.25x, 4x].
export function priceOf(good, stock) {
const ratio = TYPICAL_STOCK / Math.max(stock, 1);
const mult = Math.min(4, Math.max(0.25, ratio));
return Math.round(BASE_PRICE[good] * mult * 100) / 100;
}
// Lazily advance a planet's stocks to time t (no per-tick simulation).
export function advancePlanet(planet, t) {
const dt = t - planet.stockTime;
if (dt <= 0) return;
for (const g of GOODS) {
const rate = (planet.produces[g] || 0) - (planet.consumes[g] || 0);
planet.stock[g] = Math.min(MAX_STOCK, Math.max(0, planet.stock[g] + rate * dt));
}
planet.stockTime = t;
}
// Execute a trade at the current price. deltaQty > 0 delivers goods,
// deltaQty < 0 removes them. Returns the unit price the trade executed at.
export function applyTrade(planet, t, good, deltaQty) {
advancePlanet(planet, t);
const price = priceOf(good, planet.stock[good]);
planet.stock[good] = Math.min(MAX_STOCK, Math.max(0, planet.stock[good] + deltaQty));
return price;
}
export function marketView(planet, t) {
advancePlanet(planet, t);
return GOODS.map((g) => ({
good: g,
stock: Math.floor(planet.stock[g]),
price: priceOf(g, planet.stock[g]),
}));
}