RevFramework – Currency FAQ¶
This FAQ answers decision questions about using the Currency system: how to integrate it, which extension point to use, and what is supported vs. discouraged.
It does not repeat the README content. If you’re looking for APIs, examples, or behaviour details, see the Currency READMEs.
How do I integrate Currency into my project?¶
Minimal runtime setup
- Add
SceneCurrencyServiceto the scene. - (Recommended) Add
CurrencyServiceBootstrapand configure Caps / Audit / Authority as needed. - Resolve the service via
CurrencyResolve.ServiceFrom(this)wherever you need it.
Inventory-backed setup (optional)
- Use
CurrencyInventoryFactories.*helpers (requiresREV_INVENTORY_PRESENT). - Wrap with Caps / Audit / Authority using
CurrencyFactories.
Rule of thumb
Resolve services; do not depend on concrete implementations.
Is this the right extension point?¶
I want to change balances¶
Use: ICurrencyService (resolved via CurrencyResolve).
Avoid: referencing SceneCurrencyService.Instance.
SceneCurrencyService is the default implementation, but it is not part of the supported public API surface. Accessing it directly bypasses the composed decorator stack.
I want to enforce min/max limits¶
Use: CurrencyPolicy + CurrencyFactories.WithCaps(...).
Avoid: clamping values manually in gameplay or UI code.
I want audit logs (who changed what and why)¶
Use: CurrencyFactories.WithAudit(...) and query via CurrencyAudit.Get(...).
Avoid: custom logging wrapped around currency calls.
I want atomic multi-step operations (shops, trades)¶
Use: CurrencyTxn or CurrencyPurchase helpers.
For stronger guarantees with escrow-enabled stacks, use CurrencyHoldTxn.
Avoid: chaining multiple Credit / Debit calls without orchestration.
Transactions provide:
- ordered execution
- best-effort rollback
- optional batch event emission
Rollback may be blocked by outer decorators such as policy, authority, escrow requirements, or idempotency.
I want escrow / holds¶
Use: CurrencyFactories.WithEscrow(...).
If you need to enforce escrow usage:
Enable CurrencyPolicy.RequireEscrow.
This adds a guard that blocks direct Debit / Transfer when escrow is not present.
Important
RequireEscrow does not add escrow automatically.
It only blocks operations when escrow is missing.
I want multiplayer-safe retries¶
Use: CurrencyFactories.WithIdempotency(...) and include:
|rid:<token>
inside the sourceId.
Avoid: relying on non-audit overloads — idempotency applies only to audit-aware overloads.
Note:
Replay short-circuits may not emit wallet events or audit entries, depending on decorator order.
I want authority (server / host only)¶
Use: CurrencyFactories.WithAuthority(...) with an ICurrencyAuthority implementation.
Single-player
Use CurrencyAuthorityBinder (alwaysTrue = true).
Avoid
Calling currency mutations from non-authoritative contexts.
Can I do X with Y?¶
Can I use Currency without Inventory?¶
Yes.
Inventory adapters are optional. Currency works with SceneCurrencyService alone.
Can I use Inventory items as currency?¶
Yes.
Use CurrencyInventoryFactories.* (when the inventory module is present).
Can I save / load balances?¶
Yes.
Use:
CurrencyPersistencehelpers (per-owner)CurrencyJsonSave(scene-wide utility)
Persistence restore respects the composed decorator stack (policy, authority, etc.).
Can I show balances in UI?¶
Yes.
Optional UI components:
CurrencyBar(UGUI)CurrencyBarTMPCurrencyBarUITK
Or subscribe to:
ICurrencyService.OnWalletChanged
Can I exchange currencies?¶
Yes.
Use CurrencyExchangeTable + CurrencyFactories.BuildExchange(...).
Always TryQuote before TryExchange.
Can I change balances directly from UI code?¶
No.
UI should observe currency state, not mutate it.
All balance changes must go through ICurrencyService.
Can I call SetBalance in multiplayer?¶
Yes — but only from the authoritative side.
SetBalance writes an absolute value and bypasses debit/credit semantics.
It still flows through policy, authority, and other decorators.
Do not call SetBalance on clients unless your authority model allows it.
Prefer debit/credit flows when modelling gameplay actions
What should I avoid?¶
- ❌ Newing decorator classes directly
- ❌ Bypassing
CurrencyFactories - ❌ Hardcoding currency logic in UI
- ❌ Polling for balance changes
- ❌ Treating
CurrencyDefinitionas gameplay logic - ❌ Assuming escrow is automatic
- ❌ Assuming decorator order does not matter
What guarantees does Currency provide?¶
Currency guarantees:
- deterministic currency mutations
- explicit decorator composition
- orchestrated multi-operation flows
- event-driven observation
- a stable, minimal public API
Currency does not guarantee:
- full transactional atomicity across arbitrary decorator stacks
- networking replication
- automatic escrow usage
See SystemGuaranteesMatrix.md for the formal guarantee definitions.
When should I contact support?¶
Before contacting support, please check:
- Are you resolving the service via
CurrencyResolve? - Is your decorator order intentional?
- Are you using audit-aware overloads when expecting idempotency?
- Is
RequireEscrowenabled without composing escrow? - Are wallet owners assigned a valid
StableId(for persistence)?
If reporting an issue, include:
- Unity version
- Active decorators
- Repro steps
- Relevant
CurOpResultcodes / messages
Summary¶
Currency is designed to be:
- modular
- explicit
- authority-aware
- transaction-capable
- UI-agnostic
If you resolve via CurrencyResolve, compose via CurrencyFactories, and keep logic out of UI, you are using the system correctly.