Skip to content

Generated reference. This page mirrors Code/Economy/README.md, this module's source-of-truth documentation (Standards/02_DOCUMENTATION_STANDARDS.md §1). Edit it there, not here -- this file is regenerated on every docs build and any local edit is silently overwritten.

Economy

Purpose. One character-scoped balance, floored at zero, with no debt — the single legacy invariant Legacy/07_ECONOMY.md §1 calls out as worth keeping. See 08_DATA_MODEL.md §4.

Responsibilities. - IEconomyService / EconomyStore — the balance itself: LoadOrCreateAsync, GetBalance, CanAfford, DebitAsync, CreditAsync. EconomyStore is the one implementation; nothing else writes a character's balance. - Floor-at-zero on debit, and rejection of a negative amount into either typed method — a debit and a credit are always two calls with a non-negative amount, never one signed GiveMoney, matching this codebase's existing preference for typed operations over one overloaded call (Standards/00_CODING_STANDARDS.md). - Persistence of the balance under economy/{characterId} (08_DATA_MODEL.md §8).

Not responsible for. - Calling LoadOrCreateAsync when a character actually becomes active. DebitAsync/ CreditAsync fail explicitly for a character never loaded this way, rather than guessing a 0 balance and silently overwriting a real saved one -- but nothing in this codebase yet subscribes to CharacterLoaded/CharacterCreated to call it automatically. Same "no lifecycle entry point" gap Code/Items/README.md flags for its own missing RPC entry point; whoever builds the first system that needs a live balance wires this the same way. - Where money comes from or goes, beyond the mechanics of moving it. Salary, payday, contraband income, taxation, and manufacturing costs (Legacy/07_ECONOMY.md §2–4) are all Jobs/Needs-era gameplay this module deliberately does not build — it only has to exist for those systems to call into later. - A door's purchase price — that is World's DoorConfiguration, not an Economy concern; Economy only knows how to check and move a balance, never what something costs. - Any UI display of a balance — Ui's HUD reads IEconomyService.GetBalance directly once it exists (Milestone 6, deferred).

Dependencies. Core (IServiceRegistry, IServiceResolver, IPersistenceBackend, ISchemaRegistry, IEventBus, IGameLog), Character (CharacterId, the key every balance is stored under).

Public API. - IEconomyServiceGetBalance(CharacterId), CanAfford(CharacterId, int), DebitAsync(CharacterId, int), CreditAsync(CharacterId, int).

Events published. None yet — a MoneyChanged event is natural once Ui needs one to react to, deferred until that consumer exists, following Inventory's README's identical deferral.

Persistence. EconomyDocument { CharacterId, Balance } under economy/{characterId}, schema version 1.

Future improvements. - Salary/payday, contraband income, door tax with repossession, and manufacturing cost — all named in Legacy/07_ECONOMY.md as worth preserving, all deferred to the Jobs/Needs milestones per ROADMAP.md. - MoneyChanged event once a UI or scoreboard consumer exists.