Skip to content

RevFramework – Sample Scene: 08_Currency_Awaiters

Goal

Teach event-driven waiting for currency changes:

Owner + Currency + ICurrencyService.OnWalletChanged → await condition → complete, timeout, or cancel.


What This Scene Demonstrates

This scene shows how to wait for wallet changes without polling.

The flow is:

Owner → ICurrencyService → selected CurrencyId → awaiter subscribes to OnWalletChanged → matching change event → condition check → completion

  • Awaiters observe public service events
  • Awaiters do not mutate balances
  • Awaiters do not poll every frame
  • Awaiters complete only when the selected condition is met
  • Awaiters can timeout or be cancelled
  • Existing waits are cancelled if the service instance changes

Awaiters are event-driven helpers.

The service event is the trigger.


What To Look For

Use the CurrencyAwaitersPanel to compare Task-based and Coroutine-based wait flows.

  • Setup tab

  • Owner is the wallet being observed

  • Service shows the resolved ICurrencyService stack
  • Currency selection provides the CurrencyId being matched
  • Live balance shows the current state before starting waits

  • Tasks tab

  • WaitForBalanceAtLeastAsync completes when balance is at least the target

  • WaitForAnyChangeAsync completes on the first matching owner/currency change
  • WaitForDeltaAsync captures the starting balance and waits for an absolute delta threshold
  • WaitForPredicateAsync completes when the supplied predicate returns true
  • Each task has timeout and cancellation controls

  • Coroutine tab

  • Coroutine WaitForBalanceAtLeast teaches the same pattern without async/await

  • The coroutine completes, times out, cancels, or exits if owner/service context becomes invalid

  • External mutation source

  • Use another panel or gameplay to change the observed balance

  • The awaiter panel waits; it does not create the wallet change itself

Sample Scope

This scene covers:

  • Event-driven currency waiting through OnWalletChanged
  • Task-based awaiters
  • Coroutine-based awaiters
  • Balance-at-least waits
  • Any-change waits
  • Delta-threshold waits
  • Predicate waits
  • Timeout and cancellation behaviour
  • Service swap cancellation

This scene does NOT cover:

  • Mutating balances directly from the awaiter panel
  • Polling loops
  • Internal service inspection
  • Custom production quest systems
  • Full reactive UI architecture
  • Multiplayer replication or networking

Those are project-level integration concerns.


Authority Note

This scene may include a permissive sample authority setup so it runs without additional configuration.


Networking Reminder

RevFramework does not include networking.

For multiplayer projects, wallet changes should come from server/host-approved mutations. Awaiters can react to local service events, but they are not a networking or authority layer.


How To Use

  1. Enter Play Mode.
  2. Toggle the CurrencyAwaitersPanel with F8.
  3. In Setup:

  4. Confirm Owner is assigned

  5. Confirm ICurrencyService is resolved
  6. Select a valid currency
  7. Check the live balance
  8. In Tasks:

  9. Configure the target, delta, predicate value, or timeout

  10. Start one of the task awaiters
  11. Use another panel or gameplay to mutate the selected owner/currency
  12. Watch the status update when the condition completes, times out, or is cancelled
  13. In Coroutine:

  14. Enter a target and timeout

  15. Start the coroutine awaiter
  16. Mutate the selected owner/currency externally
  17. Watch the coroutine status complete or cancel
  18. Cancel running waits when you no longer need them.

Failure Behaviour

Failures or exits are shown through dependency messages, awaiter statuses, or result messages.

Common causes:

  • Play Mode required

  • Awaiters listen to live runtime service events

  • Fix: enter Play Mode

  • Service missing

  • No ICurrencyService was resolved

  • Fix: add a scene currency service, add CurrencyServiceBootstrap, or publish a composed service

  • Owner missing

  • No wallet owner is selected

  • Fix: assign an owner or tag the player GameObject as Player

  • No currencies bound

  • No CurrencyDefinition assets are available

  • Fix: assign currencies in the Inspector or provide a CurrencySet

  • Invalid CurrencyId

  • The selected CurrencyDefinition has an invalid Id

  • Fix: correct the CurrencyDefinition asset

  • Bad input

  • Target, delta, predicate, or timeout values are invalid

  • Fix: enter values within the panel’s accepted ranges

  • Timeout

  • No matching event satisfied the condition before timeout

  • Fix: increase the timeout or trigger a matching owner/currency mutation

  • Cancelled

  • The user cancelled the awaiter, the panel disabled, or context changed

  • Fix: start the awaiter again when ready

  • Service changed

  • Existing waits are tied to the previous service instance

  • Fix: restart awaiters against the new service

  • No completion despite balance changes

  • The awaited owner/currency did not match the emitted change

  • Fix: check owner binding, selected currency, service reference, and whether OnWalletChanged fires for that mutation

Behind The Scenes

The panel uses real Currency awaiter APIs:

  • CurrencyResolve.ServiceFrom

  • resolves the active ICurrencyService

  • ICurrencyService

  • GetBalance

  • OnWalletChanged

  • CurrencyAwaiters

  • WaitForBalanceAtLeastAsync

  • WaitForAnyChangeAsync
  • WaitForDeltaAsync
  • WaitForPredicateAsync
  • WaitForBalanceAtLeast coroutine variant

  • CancellationTokenSource

  • cancels Task-based waits

  • Unity coroutine host

  • runs the coroutine awaiter

The panel observes service events only.

It does not inspect internals.

It does not mutate balances directly.


Key Takeaway

Awaiters wait for real wallet events.

They complete when the selected condition becomes true.

Use them when you want reactive currency logic without manual polling.