0079 — Haggling numerical model¶
Status¶
Folded into FEATURES/economy/haggling.md (rollup 2026-06-21) — the seven numbers + the band engine now live canonically in haggling.md § Numerical Haggling; this ADR is retained as the decision record.
Accepted (Max 2026-06-14). Resolves the seven open haggling numbers in one
consolidating ADR (the contradictions span haggling.md ↔ jsonb-schema.md);
all numbers below are blessed. Supersedes haggling-numerical-v1 in
DECISIONS.md. Single source of truth for haggling math.
Context¶
The round skeleton is solid (4-round limit, accept/counter/reject band table, reject-locks-commodity, final clamp [0.80, 1.20]), but seven numeric gaps / cross-doc contradictions block the build. Each is resolved below.
Decision¶
- Counter formula. When the player's offer is outside the acceptance band but not a reject, the NPC counters at the midpoint between the player's offer and the NPC's current fair price (split-the-difference, converging toward fair each round).
- Per-round band narrowing. The acceptance band narrows 20% per round (round 1 widest → round 4 tightest): early rounds forgive, late rounds demand near-fair.
- Rank modifier (resolves the 0–5% vs +1%/tier contradiction). Adopt the richer model: +1% effective price per rank tier, capped at +12%; the 0–5% figure is retired.
- Reputation-tier multipliers (pins the ranges). Faction rep linear from hostile ×1.05 → allied ×0.97 across the named tiers; personal rep linear from disliked ×1.05 → trusted ×0.95.
- Difficulty authority (resolves archetype-bands vs int 1–10).
haggling_difficultyint 1–10 is the single source; archetype only sets that int. Map linearly: difficulty 1 → band-multiplier ×0.85 (easy/generous) … difficulty 10 → ×1.25 (hard/tight). The stray ×1.20 cap is raised to ×1.25 to match; the final realized price is still clamped to [0.80, 1.20]. - Perceived-fair-price model. Haggling modifiers adjust the acceptance band
only, never the displayed/perceived fair price — this prevents double-applying
the
trading.mdprice-stacking modifiers that already set the base price. - Session re-entry. After a non-reject close (accept or round-timeout),
re-entry is allowed only after a cooldown (the
:331-337table becomes real — draft 5 min) to defeat accept-threshold binary search; a reject still hard-locks the commodity for the session. Reputation deltas are zero in numerical mode (it is pure price negotiation; the "optional reputation deltas" are off here).
Schema reconciliation (required before build): align Station.trader_personality
to jsonb-schema.md — memory_duration_days (not memory_duration) and trust
in [−1000, 1000] (not a 50 default). NB: 100% of live stations carry the BORDER
default, so archetype-driven difficulty is a no-op until a bang/seed pass derives
real personalities — flagged as a prerequisite, not part of this ADR.
Consequences¶
- Numerical haggling becomes buildable against a single, internally-consistent
number set;
haggling.mdandjsonb-schema.mdboth defer to this ADR. - Build follow-up (player/gameserver lane): implement the band math, plus the
prerequisite
Station.trader_personalityschema reconcile and the archetype difficulty seeding pass.
Related¶
FEATURES/economy/haggling.md, DATA_MODELS/jsonb-schema.md,
FEATURES/economy/trading.md (price-stacking order).