Reputation economy: rep-scaled buy/refuel discounts + job reward quality (ISS-072, v0.38.0)
CI / build + unit + e2e (pull_request) Successful in 9m3s

This commit is contained in:
2026-09-21 10:51:22 +00:00
parent 0f5f3ae23e
commit 8daca54840
16 changed files with 273 additions and 33 deletions
+20
View File
@@ -1,5 +1,9 @@
import { STARTING_REPUTATION } from './seed';
// Aircraft catalog — in-code constants for now (no DB table yet). One type is
// enough for the MVP; add more entries to PLANE_TYPES as they are designed.
// ponytail: circular import with seed.ts is safe — neither module touches the other's
// bindings at top level, only inside function bodies.
export interface PlaneType {
id: string;
@@ -102,6 +106,22 @@ export const FUEL_PRICE_PER_L = 0.8;
// Fraction of the catalog price paid out when selling a plane (v0.8.0).
export const SELL_FRACTION = 0.5;
// Shared rep-discount shape (v0.38.0, ISS-072): linear in reputation above the starting value,
// capped — exactly 0 at/below STARTING_REPUTATION so default-rep behavior is unchanged.
export function repRate(reputation: number, perPoint: number, cap: number): number {
return Math.min(cap, perPoint * Math.max(0, reputation - STARTING_REPUTATION));
}
// ponytail: balance-tunable — plane purchase discount per rep point above the starting value.
export const PLANE_DISCOUNT_PER_REP = 0.01;
// ponytail: balance-tunable — max plane purchase discount (reached at rep ≥ 50).
export const MAX_PLANE_DISCOUNT = 0.4;
// ponytail: balance-tunable — refuel price discount per rep point above the starting value.
export const FUEL_DISCOUNT_PER_REP = 0.005;
// ponytail: balance-tunable — max refuel price discount (reached at rep ≥ 50).
export const MAX_FUEL_DISCOUNT = 0.2;
// Snapshot shape of one catalog entry in GET /api/state (v0.10.0): `model` is the
// id used by buy/dispatch, `label` the display name — clients compute all market
// previews (buy price, sell payout, refuel cost) from these + the economy constants.