Skip to content

💰 Currency -- Core

Namespace: RevGaming.RevFramework.Currency

The Core layer contains the primary runtime building blocks of the Currency system. These are the services, helpers, and utilities you interact with during normal gameplay, UI wiring, and tooling.

Core is where you use Currency --- not where you define contracts (see Abstractions) or wire scene composition (see Bootstrap).

Multiplayer note (netcode-agnostic): Currency is designed to support server/host-authoritative flows. Use Authority (ICurrencyAuthority) and Idempotency (|rid:<token> in sourceId) when building multiplayer systems.


🔎 Core Design Principle

Core exposes capability-based composition.

Features such as:

  • Caps\
  • Audit\
  • Authority\
  • Idempotency\
  • Escrow\
  • Batch emission

are added via decorators composed through CurrencyFactories.

Core helpers automatically detect these optional capabilities when present --- without expanding the public ICurrencyService contract.


What lives in Core

Core includes:

  • The default in-scene currency service (SceneCurrencyService)
  • Public factories for composing stacks (CurrencyFactories)
  • Resolvers (CurrencyResolve) to access the active service
  • High-level helpers for common gameplay patterns:
    • Transactions
    • Hold Transactions
    • Purchases
    • Awaiters
    • Audit helpers

Everything here depends only on Abstractions and optional capabilities. Concrete decorators remain internal.


Core types

SceneCurrencyService

The default in-scene implementation of ICurrencyService.

  • Stores balances in a dictionary keyed by GameObject → CurrencyId → long
  • Emits OnWalletChanged for every mutation
  • Optionally prunes destroyed owners over time
  • Predictable and allocation-light
  • Suitable as the inner layer for all decorator stacks

Important\ SceneCurrencyService.Instance is the raw inner service (no caps, audit, authority, idempotency, etc.).\ Gameplay code should prefer CurrencyResolve to ensure the composed stack is used.

Recommended usage:

var svc = CurrencyResolve.ServiceFrom(this);
svc.Credit(player, new CurrencyId("gold"), 100);

CurrencyResolve

Runtime resolver for the active ICurrencyService.

Resolution order:

  1. Published override (via CurrencyBootstrap.Publish)
  2. Cached per-scene resolve
  3. One-time scene-local search for SceneCurrencyService

Resolution is scene-aware: in additive or multi-scene setups, the service is resolved from the caller's scene.

var svc = CurrencyResolve.ServiceFrom(this);

This is the recommended entry point for gameplay and UI code.


CurrencyFactories

Public factory helpers for composing currency service stacks.

Core helpers:

  • WithCaps
  • WithAudit
  • WithAuthority
  • WithEscrow
  • WithIdempotency
  • WithBatchEvents

Factories ensure:

  • Decorator ordering is explicit
  • Concrete decorator types remain internal

Example:

svc = CurrencyFactories.WithCapsAuditAuthorityIdemBatch(
    svc, policy, this);

Factories define composition order but do not guarantee transactional safety across multi-step workflows.


CurrencyTxn

Best-effort multi-operation transactions.

  • Stages multiple Credit, Debit, Set, or Transfer operations
  • Performs a simulated precheck before committing (funds/overflow only)
  • Applies operations sequentially
  • Attempts rollback automatically on the first failure
  • Emits a single batch event when supported

Note Rollback is best-effort. Final atomicity depends on the composed service stack (policy, authority, escrow, idempotency, etc. may block rollback). For stronger guarantees when escrow is available, use CurrencyHoldTxn.


CurrencyHoldTxn

Two-phase, escrow-backed hold transactions.

Designed for flows where currency must be reserved before final confirmation, such as:

  • Auction bids
  • Crafting queues
  • Matchmaking entry fees
  • Delayed purchases
  • Time-limited offers

CurrencyHoldTxn:

  • Places escrow holds for one or more debits
  • Supports staged commit / cancel
  • Integrates with escrow TTL when enabled
  • Emits batched events when supported
  • Performs rollback on failure

Use CurrencyHoldTxn when currency must be reserved first --- not immediately spent.


CurrencyPurchase

Convenience helpers for affordability checks and best-effort multi-currency spends/grants.

Internally applies operations sequentially and attempts rollback on failure. Final atomicity depends on the composed service stack.


CurrencyAwaiters

Task-based and coroutine-based awaiters that complete when wallet conditions change.

  • Subscribes to OnWalletChanged (event-driven)
  • Includes safe cancellation, timeout handling, and owner/service invalidation detection

Prefer awaiters over manual polling.


CurrencyAudit & CurrencyAuditLive

Helpers for working with audit-enabled stacks.

  • CurrencyAudit provides query helpers when auditing is present
  • CurrencyAuditLive provides safe subscription to live audit events

Stacks without auditing simply return empty results.


CurrencyServiceExtensions

Extension helpers layered on top of ICurrencyService.

  • Audit-aware overloads
  • Cap-aware preview helpers
  • Affordability helpers

These helpers detect optional capabilities without expanding the public contract.


CurrencyRequestId

Utility for generating idempotency tokens.

var rid = CurrencyRequestId.New();

Idempotency convention:

  • "VendorA|rid:<token>" (recommended)
  • "rid:<token>" (also valid)

Idempotency is enforced only by stacks that include the idempotency decorator.


CurrencyEscrowExpiryPump

Scene component that periodically calls ExpireStale() on escrow-enabled services.

Relevant only when escrow is enabled and TTLs are used.

Attach when you want automatic cleanup of expired holds.


Best practices

  • Resolve services via CurrencyResolve
  • Avoid direct use of SceneCurrencyService.Instance
  • Compose stacks using CurrencyFactories
  • Use CurrencyTxn for immediate multi-step actions
  • Use CurrencyHoldTxn for reservation flows
  • Prefer awaiters over polling
  • Enable audit during development
  • Ensure an expiry pump exists when using escrow TTL
  • Route multiplayer mutations through authority

  • Abstractions --- contracts and primitives
  • Bootstrap --- scene-level composition and publishing
  • Internal --- decorator implementations
  • Authority --- authority contracts and binders
  • Persistence --- snapshot capture