Skip to content

💰 Currency – Internal

Namespace: RevGaming.RevFramework.Currency.Internal

⚠️ Hands off. Internal plumbing.

This folder contains internal implementation seams used by the Currency system. These types exist to support clean composition, auditing, batching, escrow, and idempotency without expanding the public API surface.

Nothing in this folder is intended for direct use by gameplay code, UI, editor tooling, or external systems.

If a type lives here, it is deliberately not part of the supported extension surface.


Purpose

  • Keep the public ICurrencyService contract small, stable, and readable.
  • Allow decorators to share extended capabilities internally (audit metadata, batch emission, escrow enforcement, idempotency).
  • Prevent implementation-only details from leaking into public namespaces.
  • Enable advanced behaviour (audit + idempotency + batch events) without forcing all services to support it.

This folder exists so the outside API can stay clean.


Key internal seams

IAuditAwareCurrencyService

Internal extension interface implemented by decorators that need to preserve audit metadata (reason, sourceId) while still presenting themselves as a plain ICurrencyService to the outside world.

internal interface IAuditAwareCurrencyService
{
    CurOpResult Credit(GameObject owner, CurrencyId currency, Money amount, string reason, string sourceId);
    CurOpResult Debit(GameObject owner, CurrencyId currency, Money amount, string reason, string sourceId);
    CurOpResult SetBalance(GameObject owner, CurrencyId currency, Money newBalance, string reason, string sourceId);
    CurOpResult Transfer(GameObject from, GameObject to, CurrencyId currency, Money amount, string reason, string sourceId);
}

Why this exists

  • ICurrencyService intentionally does not include reason / sourceId parameters.
  • Exposing them publicly would bloat the core contract and force all implementations to support them.
  • This interface allows audit-capable decorators (Audit, Idempotency, Escrow when present) to forward metadata only when supported.

How it is used

  • Decorators probe for this interface at runtime.
  • If present, metadata-aware overloads are used.
  • If absent, calls safely fall back to the plain ICurrencyService methods.

This keeps audit metadata optional, internal, and non-breaking.


ICurrencyBatchEmitter

Internal helper interface that allows a decorator to emit batch events without exposing emission control publicly.

internal interface ICurrencyBatchEmitter : ICurrencyBatchEvents
{
    void EmitBatch(IReadOnlyList<CurrencyDelta> deltas);
}

Why this exists

  • ICurrencyBatchEvents exposes only the subscription surface.
  • Emitting batch events is an implementation concern, not a public capability.
  • This interface allows batch-aware decorators to raise aggregated events without giving callers a way to trigger them.

How it is used

  • CurrencyBatch captures individual CurrencyDelta events during a multi-op block.
  • On successful commit, it checks whether the composed service implements ICurrencyBatchEmitter.
  • If present, a single aggregated batch event is emitted.

Gameplay and UI code may subscribe to batch events, but never emit them directly.


Other internal helpers (overview)

  • CurrencyBatch — captures per-op deltas and controls when batch events are emitted.
  • CurrencyPolicyUtil — shared helpers for applying cap policies (clamp vs fail).
  • CurrencyRequestId (internal) — request-id helper used by idempotency/correlation.
  • Decorators — concrete implementations for:
  • Audit
  • Escrow
  • Idempotency
  • Batch events
  • Escrow enforcement guards

These types cooperate internally but are never part of the public API.


Design rules (non-negotiable)

  • All types here are internal by design.
  • They may change between versions without notice.
  • They are not supported extension points.
  • Reflection may be used here; public APIs and Teachables should not depend on it.

If you think you need to reference something in this folder:

You almost certainly want a higher-level API instead.

Check first: - CurrencyFactories - CurrencyServiceExtensions - CurrencyBatching (public wrapper) - CurrencyEditorApi (editor tooling)


  • Abstractions — public contracts (ICurrencyService, CurrencyDelta, etc.)
  • Core — factories, extension methods, batch capture
  • Policies — caps and escrow rules
  • Editor API — safe editor-facing helpers