Common Patterns
This document collects repeatable, battle-tested patterns for integrating OGAL and the Solana Toolbelt into real Unity projects.
These are not theoretical examples. They reflect how the system is intended to be used in production, and how the existing Toolbelt and OGAL codebases are structured today.
If you follow these patterns, you will:
- Avoid fighting the Toolbelt
- Keep your gameplay code clean
- Preserve upgrade flexibility
- Get predictable, debuggable behavior
Pattern 1: Treat OGAL as Read-Mostly Infrastructure
Principle
Most gameplay systems should read OGAL state, not mutate it.
Why
- Ownership and mutability rules are enforced on-chain
- Reads are cheap and permissionless
- Writes are intentional, explicit user actions
Recommended
- Query OGAL manifests to verify ownership
- Use OGAL state to gate features, not drive frame logic
- Centralize all OGAL writes in a small number of services
Avoid
- Calling OGAL instructions directly from gameplay scripts
- Sprinkling manifest updates throughout the codebase
Pattern 2: Centralize Blockchain Flows Behind Services
Principle
Gameplay code should never assemble transactions.
Why
- Transaction composition is error-prone
- Error handling becomes inconsistent
- UX suffers when logic leaks into scenes
Recommended
- Use:
OwnerGovernedAssetLedgerServiceSolanaNFTMintServiceLevelEditorMintService
- Wrap these in game-specific façade services if needed
- Expose async methods like:
MintLevelAsyncUpdateManifestAsyncVerifyOwnershipAsync
Avoid
- Creating
Transactionobjects in MonoBehaviours - Mixing RPC calls and gameplay state machines
Pattern 3: Explicit User Actions for All Writes
Principle
Every on-chain write must correspond to a clear user action.
Why
- Wallet prompts are disruptive
- Silent writes break trust
- Retry semantics are explicit by design
Recommended
- Tie writes to buttons, confirmations, or editor actions
- Use
IToolbeltUiBridgeto surface:- Progress
- Errors
- Wallet prompts
Avoid
- Background writes
- “Auto-save” behavior that triggers transactions
- Retrying writes without user confirmation
Pattern 4: One Service Owns One Responsibility
Principle
Services should map cleanly to responsibilities.
Examples
- Ownership checks →
OwnerGovernedAssetLedgerService - Minting NFTs →
SolanaNFTMintService - Uploading JSON →
INftStorageUploader - Access gating →
SolanaNftAccessManager
Why
- Easier testing
- Easier upgrades
- Easier reasoning about failures
Avoid
- God services that handle minting, uploading, UI, and gameplay
- Cross-calling services in circular ways
Pattern 5: Prefer Events at Boundaries, Not Everywhere
Principle
Use Unity events at integration boundaries, not deep inside logic.
Good places for events
- Wallet connected / disconnected
- Ownership state changed
- Mint completed or failed
- Access granted or revoked
Bad places
- Inside mint loops
- Inside RPC retry logic
- Inside low-level services
Why
- Events are for coordination, not control flow
- Too many events make behavior non-deterministic
Pattern 6: Treat Failures as First-Class Outcomes
Principle
A failed transaction is a valid result, not an exception.
Why
- Toolbelt avoids implicit retries
- Users must stay in control
- Network conditions are variable
Recommended
- Model results as:
- Success
- User rejected
- Network failure
- Validation failure
- Surface errors clearly to the UI
- Let players decide when to retry
Avoid
- Catch-and-ignore patterns
- Automatic retry loops in gameplay code
Pattern 7: Keep Metadata and Runtime Separate
Principle
Do not assume metadata drives gameplay directly.
Why
- Metadata is off-chain
- Gateways can degrade
- Runtime assets must be validated
Recommended
- Treat OGAL manifest hash as the source of truth
- Validate metadata before using it
- Cache reconstructed assets locally when appropriate
Avoid
- Pulling JSON every frame
- Trusting metadata without hash validation
Pattern 8: Access Control Is a Cache, Not Truth
Principle
Access managers reflect OGAL truth, they do not define it.
Why
- Ownership can change outside your app
- Caches can go stale
- OGAL is the authority
Recommended
- Use
SolanaNftAccessManageras a convenience layer - Periodically refresh ownership
- Treat access flags as hints, not guarantees
Pattern 9: Configuration Over Hardcoding
Principle
Everything that can vary should live in configuration assets.
Examples
- RPC endpoints
- Rate limits
- Bundlr funding thresholds
- Retry policies (where applicable)
Why
- Faster iteration
- Safer updates
- Easier environment switching
Avoid
- Hardcoded RPC URLs
- Magic numbers in mint flows
- Environment-specific logic in code
Pattern 10: Ship a Thin Vertical Slice First
Principle
Prove one full flow before expanding.
Recommended first slice
- Connect wallet
- Verify OGAL ownership
- Mint a simple asset
- Update a manifest
- Reconstruct and consume the asset
Why
- Surfaces real constraints early
- Validates assumptions
- Prevents architectural drift
Summary
If you remember nothing else:
- OGAL is truth, not logic
- The Toolbelt is orchestration, not magic
- Writes are explicit
- Failures are visible
- UX decisions belong to you
Follow these patterns and the system will stay predictable, debuggable, and scalable as your project grows.