State Model in ResultFly
Terminology
- State — the hierarchical data tree available to campaign logic.
- System State — the portion of State managed solely by ResultFly.
- Business State — the portion defined by customers through declared variables.
- Declared Variable — a variable registered ahead of time with a specific scope.
- Scope — the visibility boundary for a declared variable (
user,campaign,app).
1. State Overview
State is the contract between ResultFly campaigns and user data. Campaign logic reads it to decide which step to execute, which reward to grant, and which constraints to enforce. State is not a free-form datastore; only the values described in this document are visible or mutable.
2. Public State Structure
ResultFly exposes a predictable, logical tree:
state
├─ sessionId (system)
├─ user.* (declared variables)
├─ campaign.* (declared variables)
└─ app.* (declared variables)This structure is independent of internal storage or transport formats.
3. System State
System State is created and maintained by ResultFly. Fields such as state.sessionId, the current node pointer, or time-context markers exist to keep the runtime deterministic. Campaign logic cannot write to System State; any attempt to do so results in an execution error. These fields may be readable where necessary (for example, to understand the active session), but they remain immutable from the campaign’s perspective.
4. Declared Business Variables
All business-facing data lives in declared variables:
- Every variable must be declared before it is used.
- The declaration specifies the variable name and scope (user, campaign, or app).
- Undeclared variables cannot be read or modified.
- ResultFly limits the number of declared variables per scope (for example, up to ten) to keep logic predictable and prevent unbounded growth.
- ResultFly does not interpret the meaning of a variable; the campaign defines how it is used.
This mechanism keeps the model deterministic, allows validation before launch, and supports downstream analytics.
5. Variable Scopes and Lifecycle
- User scope (
state.user.*) — shared across campaigns and sessions for the same identity. Suitable for long-lived balances or status flags. - Campaign scope (
state.campaign.*) — available only within a single campaign, but consistent across its apps and executions. - App scope (
state.app.*) — confined to a specific app or game instance inside the campaign. Reinitialized when that app restarts.
Scopes describe how values travel; they do not expose storage or sync internals.
6. State Mutation Rules
State changes only through configured campaign logic (nodes, rules, automations). The following rules apply:
- Direct assignments to System State are forbidden.
- Attempts to update an undeclared variable raise a runtime error.
- Valid mutations apply within the campaign execution context and follow scope semantics (user vs campaign vs app).
7. Session and Cross-Session Semantics
Campaigns may read variables at session start, adjust them during execution, and rely on the updated values in future interactions. Persistence between sessions depends on scope: user variables persist across campaigns, campaign variables persist within the campaign, and app variables typically reset when the app restarts. No additional persistence layers are exposed to authors.
8. Error Semantics (State-Related)
- Writing to System State → execution error; workflow halts until logic is corrected.
- Reading or writing an undeclared variable → execution error; the campaign must declare the variable before retrying.
- Declaring more variables than allowed per scope → configuration error detected during validation.
These errors are non-retriable until the configuration is fixed because they stem from logic design, not transient infrastructure conditions.
9. Security and Isolation Guarantees
Each user’s State is isolated from every other user. Campaign State is isolated per campaign, and app-specific State cannot leak into other apps. There is no access path to another user’s data or to campaigns where the user has no participation. ResultFly enforces these boundaries inside the runtime.
10. Relationship to Other Technical Concepts
- Campaign Runtime consumes State to evaluate conditions and execute actions.
- External Events can mutate declared variables even when the user is offline, provided they reference the correct identity.
- Identity resolution decides which user State tree is loaded for a given request.
These relationships ensure that State remains the single source of truth for campaign logic without exposing runtime implementation details.