Skip to content

Economy — Internal — Services

Purpose

This folder contains the internal service implementations that orchestrate multi-step economy operations such as Shop, Crafting, and Rewards.

Namespace root: RevGaming.RevFramework.Economy.Internal.Services Folder: Runtime/Systems/Economy/Internal/Services/

These types are not entry points and are not extension points. They provide the built-in implementation of the public abstractions and may change over time.

If you are looking for how to use Economy, start with:

  • RevGaming.RevFramework.Economy.Abstractions (interfaces)
  • EconomyBootstrap (facade wiring)
  • RevGaming.RevFramework.Economy (model, results, reasons)

Public-facing behaviour documentation lives in:

  • Documentation/Economy/PublicAPI/

Not for Production Use

Types in this folder are internal implementation details

They should not be referenced from gameplay code or relied upon as stable APIs.


What Lives Here

This folder contains internal implementations of:

  • IShopService
  • ICraftingService
  • IRewardService

Each service:

  • Applies operation ordering and rollback behaviour as implemented by the built-in services
  • Coordinates between IValueLedger (money) and IItemStore (items)
  • Handles partial failure and may attempt rollback where possible
  • Produces EcoOpResult outcomes describing success or failure

Request Idempotency

Two internal helpers back the whole-transaction dedup shared by Shop and Crafting:

  • EconomyRequestDedup — a bounded, per-owner cache of recent successful results, keyed by (owner, operation, requestId). A replayed key returns the cached result as a no-op.
  • EconomyRequestFingerprint — a compact value derived from the transaction payload, stored with each cached result so a replay can be checked against what the id was first used for. A mismatch is refused with EcoOpCode.IdempotencyMismatch rather than replayed.

The fingerprint is deliberately order-independent and merge-independent, so a caller rebuilding the same basket from an unordered collection is still recognised as a retry. That is a correctness requirement rather than a convenience: duplicate money lines are merged inside the core operation, so [gold:50, gold:50] and [gold:100] are already the same transaction.

It is a misuse detector, not a security boundary — the accumulation is linear, so distinct payloads can collide. A collision degrades to a replay, which is the behaviour that predated the check.


Usage Guidance

Responsibilities

Internal services are responsible for:

  • Validation Input validation and early failure with clear EcoOpCode values

  • Preflight Side-effect-free checks (CanPay, ownership, capacity) run before any mutation. Passing is advisory — the authoritative step can still fail. Failing is not: these services return the refusal (InsufficientFunds / PolicyBlocked / NotOwned / NoSpace) and the transaction does not happen

  • Execution Applies mutation ordering (money vs items) May attempt rollback on partial failure

  • Telemetry Passing sourceId to currency operations Recording canonical EcoReasons for operations


Important Notes

What services are not

  • They are not public APIs
  • They are not intended for direct invocation
  • They are not designed for subclassing or extension
  • They are not intended to be referenced from gameplay, UI, or networking code

Custom behaviour should be introduced by:

  • Supplying custom implementations of the public abstractions, or
  • Modifying behaviour at the facade or composition level

Important Notes

Maintenance rules

  • Keep all service types internal and sealed
  • Do not expose service concrete types in public signatures
  • Do not add public helpers or convenience methods here
  • Changes should preserve the intended operation ordering and rollback behaviour of the built-in services

If a change cannot be made without breaking these rules, it belongs in a new abstraction


  • Economy — Abstractions
  • Economy — Facade
  • Economy — Adapters
  • Economy — Diagnostics