Currency
Run-scoped wallets under currencies: an object map keyed by currency id. Each value is a row object with balance, clamp, interest tuning, and optional SFX clip id lists in JSON.
State (Ephemeral.currencies)
Object map: keys are the currency ids used as currencyId in service calls (letters, digits, _ only). Row values are objects:
| Field | Typical | Purpose |
|---|---|---|
currencyId | "money" | Same as the map key / currencyId in service calls; Currency sets it on new rows and fills it if missing. |
currentValue | 0 | Balance |
min / max | 0 / 999 | Clamp |
interestBaseCap | 25 | Balance counted toward interest before divisor |
interestRateDivisor | 5 | Integer interest = min(current, cap) / divisor |
increaseSfx | ["ClipA", …] | Optional: random clip on positive delta |
decreaseSfx | ["ClipB", …] | Optional: random clip on negative delta |
Example in ephemeral.json
{
"Ephemeral": {
"currencies": {
"money": {
"currencyId": "money",
"currentValue": 4,
"min": 0,
"max": 9999,
"interestBaseCap": 25,
"interestRateDivisor": 5,
"increaseSfx": ["MoneyIncrease1", "MoneyIncrease2"],
"decreaseSfx": ["MoneyDecrease1", "MoneyDecrease2"]
}
}
}
}Rules / fromContext
Use the currency id as the path segment (stable; not list order), e.g.:
ephemeral.currencies.money.currentValue
Events
String ids are in GnosisCurrencyEvents (Runtime/GnosisEngine/Source/Services/Ephemeral/Services/CurrencyService/). REQUEST_* events are interceptable by rules (same idea as GnosisTimeEvents on timers). FACT_* events report outcomes after the service updates the store (or no-ops / veto).
| Event id | Kind |
|---|---|
REQUEST_CURRENCY_ADD | Request (balance increase) |
FACT_CURRENCY_ADD | Fact |
REQUEST_CURRENCY_REMOVE | Request (balance decrease) |
FACT_CURRENCY_REMOVE | Fact |
REQUEST_CURRENCY_INTEREST_BASE_CAP_DELTA | Request (interestBaseCap bump) |
FACT_CURRENCY_INTEREST_BASE_CAP_CHANGED | Fact |
Payload field names match PAYLOAD_* on the same class (currencyId, delta, balance, previousBalance, allowed, applied, reason, interestBaseCap, previousInterestBaseCap). Rules may set allowed to false or adjust delta before the fact is emitted.
Functions
Every call includes currencyId (string, matches a map key under currencies).
| Function | Parameters | Result (high level) |
|---|---|---|
AddCurrency | currencyId, amount | { currencyId, balance } |
RemoveCurrency | currencyId, amount | { currencyId, balance } |
GetBalance | currencyId | { currencyId, balance } |
HasEnoughCurrency | currencyId, amount | { currencyId, hasEnough } |
TrySpendCurrency | currencyId, amount | { success, currencyId, balance } |
ApplyInterestOnce | currencyId | { interestAdded, balance, … } |
MultiplyCurrencyBalanceWithCap | currencyId, multiplier (≥1), cap | { multiplier, cap, gain, balance, … } |
AddInterestBaseCapDelta | currencyId, delta | { interestBaseCap, … } |
Statistics
Per currencyId, the service records three run-scoped counters via Statistic.IncrementCounter: earned, spent, and interest (keys currency.<currencyId>.earned / .spent / .interest).
You can read the same values with a dot path, e.g. ephemeral.statistics.currency.money.earned.
{
"Ephemeral": {
"statistics": {
"currency": {
"money": {
"earned": 0,
"spent": 0,
"interest": 0
}
}
}
}
}Audio
If increaseSfx / decreaseSfx are missing or empty, no sound. Otherwise Seed.RangeInt picks an index, then Audio.PlaySound.