Home Town Market NPC Price

Town Market — NPC Price Mode

Related: 10 — Economy & Markets, 37 — Economic map zones, 19 — NPCs, 08 — Inventory & storage.


1. Summary

Market-hall listings support two pricing modes:

Mode Meaning
Fixed Seller sets unit copper ≥ 1 (player order book — 10 §4)
NPC price Mode, not a copper value. Goods sit in hall escrow until buying NPCs sweep the dump queue

NPC price is a convenience dump queue: players list loot once at the hall instead of visiting each merchant. Only NPCs purchase these listings. Players never buy NPC-price lots.

Sweeps are instant (no pathing). Eligible NPCs run on a per-NPC phase schedule (default morning + afternoon). Matching lots are bought FIFO per template. Sellers are paid each NPC’s normal buy price minus a per-NPC convenience fee. Crown hall sales tax does not apply to NPC-price sweeps (fee only).


2. Design principles

Principle Meaning
Mode, not quote Listing stores NpcPrice; copper is resolved at sweep from that NPC’s buy table + rates
Dump queue only Players cannot purchase NPC-price listings
FIFO Same template: oldest listing first (listing_id / creation order)
Fee, not tax Convenience fee on NPC-price sweeps; hall market_sales_tax_* stays for Fixed player buys
Instant sweep Phase-enter edge trigger; no walk-to-hall choreography
Notify sellers Log + toast when online; pending notices flush on join if offline
Economy sink Bought goods leave the world (same dump-valve role as face-to-face NPC buys)

3. Listing model

Escrow listing fields (conceptual):

Field Fixed NPC price
pricing Fixed { unit_price_copper } NpcPrice
Player buy Allowed (bank + tax) Forbidden
Reprice Change unit copper N/A (mode has no copper)
Delist Return goods Same

List flow at clerk: source → stack → qty → pricing mode → (if Fixed) unit copper → submit.

Browse labels: Fixed shows copper; NPC price shows “NPC price”. Seller can delist own NPC-price lots. Enter/buy on NPC-price lots is rejected for players.


4. NPC economy authoring

On NPC definition economy (content-admin NPCs tab + YAML):

Field Default Meaning
buy_rate / sell_rate 0.5 / 1.25 Existing face-to-face rates
market_convenience_fee_bps 500 (5%) Deducted from NPC buy price on hall sweeps
market_buy_phases [morning, afternoon] World-clock phases that trigger a sweep on phase enter
market_buy_pct 25 Percent of each matching listing’s remaining qty bought per visit
market_buy_all_at_most 4 If remaining ≤ this, buy the entire listing this visit (skips pct). 0 disables
market_buy_max_qty_per_visit null Optional hard cap per listing per visit
market_buy_enabled true When false, wishlist/shop only — no hall sweeps

Eligibility for a template: market_buy_enabled and the template has base_value_copper > 0 (any listable valued item). NPC buys[] still supplies fixed-coin overrides when present.

Halls in scope: market halls in the region whose zone-share rules include the listing (10 §4.2).


5. Sweep (phase enter)

On world-clock phase change, for each NPC whose market_buy_phases contains the new phase:

  1. Collect NPC-price listings whose template is on this NPC’s buy list (zone-visible halls).
  2. Group / order by template, then FIFO (ascending listing id / creation).
  3. For each listing, buy
    • if market_buy_all_at_most > 0 and remaining ≤ market_buy_all_at_most: qty = remaining
    • else qty = min(remaining, max(1, floor(remaining × market_buy_pct / 100)), max_cap_or_∞). Unit pay = npc_buy_price_copper(...) after convenience fee (integer divide). If the pre-fee unit is 0, skip. If the post-fee unit would be 0 but the pre-fee unit is at least 1, pay 1 copper (cheap stacks still move).
  4. Credit seller bank for unit × qty (NPC treasury / mint — same inflation model as shop sells).
  5. Sink goods; reduce or remove listing; ledger (MarketSell / fee category as implemented).
  6. Queue seller notice (see §6).

Multiple NPCs in the same phase: process NPCs in stable id order. Each sees remaining qty after prior NPCs.

Empty market_buy_phases → no sweeps (face-to-face shop still works).


6. Seller notifications

State Delivery
Online Interaction / game log: {NpcLabel} bought {qty}× {ItemLabel} at market for {copper}.
Toast Success toast from that log line (gfx feedback classifier)
Offline Persist pending_market_notices on character; flush to log/toast on join (same pattern as pending bank credits)

7. Settlement vs Fixed buys

Fixed (player buyer) NPC price (NPC sweep)
Buyer Player bank debit NPC treasury (no player debit)
Seller Bank credit − crown tax Bank credit − convenience fee only
Goods To buyer dest Sunk
Tax zone market_sales_* Applies Does not apply

8. Client UX

Step Behavior
List After qty: choose Fixed or NPC price; Fixed still prompts for copper
Browse NPC-price rows show “NPC price”; buy confirm not offered / rejected for players
Delist Own Fixed and NPC-price lots
Sale Log + toast (§6)

Prefer item / NPC labels over raw ids.


9. Content-admin & designer notes

  • NPCs tab: economy fields in §4 (fee, phases, pct, clear-at-most, max qty, enabled).
  • Example content: enable sweeps on town buyers (Ada, blacksmith, butcher, cook) with defaults.
  • Designer note: docs/player-markets.md (NPC-price dump queue + fee vs tax).

10. Design notes

NPC-price mode keeps the open player book honest while giving a one-stop dump for loot that merchants already want. FIFO protects earlier listers when several players dump the same template. Instant sweeps keep v1 simple; walk-to-hall theater is out of scope.