Skip to main content

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:
    • OwnerGovernedAssetLedgerService
    • SolanaNFTMintService
    • LevelEditorMintService
  • Wrap these in game-specific façade services if needed
  • Expose async methods like:
    • MintLevelAsync
    • UpdateManifestAsync
    • VerifyOwnershipAsync

Avoid

  • Creating Transaction objects 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 IToolbeltUiBridge to 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 SolanaNftAccessManager as 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

  1. Connect wallet
  2. Verify OGAL ownership
  3. Mint a simple asset
  4. Update a manifest
  5. 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.