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
+5 -5
View File
@@ -306,7 +306,7 @@ export const openApiSpec = {
post: {
summary: 'Buy a plane from the market',
description:
'Buy an aircraft at its full catalog price (v0.8.0). The new plane arrives "available" with a full tank at the home base (EDDF). Only models in the in-code catalog are known.',
'Buy an aircraft at its catalog price minus a reputation-scaled discount (v0.38.0, ISS-072 — higher reputation buys cheaper; no discount at the starting reputation). The new plane arrives "available" with a full tank at the home base (EDDF). Only models in the in-code catalog are known.',
operationId: 'buyPlane',
requestBody: {
required: true,
@@ -370,7 +370,7 @@ export const openApiSpec = {
post: {
summary: 'Refuel a grounded plane',
description:
'Refuel a grounded plane at the fuel price per added liter, deducted from cash (v0.8.0). The body is optional (v0.16.0): no body or mode "full" fills to maxFuel; mode "forFlight" with packageId buys 150% of the weather-adjusted fuel required for that loaded package\'s destination leg, capped at tank capacity — liters = min(maxFuel, max(current fuel, 1.5 × required)) − current fuel, where required is the weight-proportional burn model over the great-circle distance with a ±20% wind adjustment (v0.36.0).',
'Refuel a grounded plane at the fuel price per added liter, deducted from cash (v0.8.0); the per-liter price is reduced by a reputation-scaled discount (v0.38.0, ISS-072 — higher reputation refuels cheaper; no discount at the starting reputation). The body is optional (v0.16.0): no body or mode "full" fills to maxFuel; mode "forFlight" with packageId buys 150% of the weather-adjusted fuel required for that loaded package\'s destination leg, capped at tank capacity — liters = min(maxFuel, max(current fuel, 1.5 × required)) − current fuel, where required is the weight-proportional burn model over the great-circle distance with a ±20% wind adjustment (v0.36.0).',
operationId: 'refuelPlane',
parameters: [
{ name: 'planeId', in: 'path', required: true, schema: { type: 'string' } },
@@ -476,7 +476,7 @@ export const openApiSpec = {
description: 'Aircraft catalog (v0.10.0) — static per build, one entry per plane type.',
items: { $ref: '#/components/schemas/CatalogEntry' },
},
fuelPricePerL: { type: 'number', description: 'Jet-A1 price in €/liter; refuel cost = (maxFuel − fuel) × this.' },
fuelPricePerL: { type: 'number', description: 'Jet-A1 price in €/liter; refuel cost = (maxFuel − fuel) × this, reduced by a reputation-scaled discount at refuel time (v0.38.0).' },
sellFraction: { type: 'number', description: 'Fraction of the catalog price paid out when selling a plane.' },
},
required: ['account', 'simState', 'planes', 'packages', 'catalog', 'fuelPricePerL', 'sellFraction'],
@@ -486,7 +486,7 @@ export const openApiSpec = {
properties: {
model: { type: 'string', description: 'Catalog model id (e.g. "atr72") — used by buy/fly.' },
label: { type: 'string', description: 'Display name (e.g. "ATR 72-600").' },
price: { type: 'number', description: 'Market price in € (buy cost; sell pays out sellFraction × this).' },
price: { type: 'number', description: 'Market price in € — the full catalog list price. Buying costs this minus a reputation-scaled discount at purchase time (v0.38.0); selling pays out sellFraction × this.' },
maxFuel: { type: 'number', description: 'Fuel capacity, liters.' },
burnPerKm: { type: 'number', description: 'Cruise fuel burn at a full tank, liters/km (v0.16.0 weighted model calibrates to this). Actual per-leg burn varies ±20% with wind — departure weather vs route heading (v0.36.0).' },
emptyWeightKg: { type: 'number', description: 'Operating empty weight, kg — with burnPerKm and maxFuel it drives the v0.16.0 weight-proportional burn model.' },
@@ -499,7 +499,7 @@ export const openApiSpec = {
type: 'object',
properties: {
cash: { type: 'number' },
reputation: { type: 'number' },
reputation: { type: 'number', description: 'Reputation — grows with delivered packages; drives the purchase/fuel discounts and job reward quality (v0.38.0, ISS-072).' },
},
required: ['cash', 'reputation'],
},