04 — Offline Progress and Persistence¶
Goal¶
Understand how Crafting jobs can be saved, restored, and advanced using real-world elapsed time.
This scene teaches the offline progress lifecycle:
Inspect live jobs → Save snapshots → Restore later → Let CraftingService decide the outcome
🎓 What This Scene Demonstrates¶
This scene shows how CraftingService can capture and restore active crafting jobs.
You’ll see how to:
- inspect live jobs for an owner
- save active jobs to JSON using
SaveActiveJobs() - inspect the saved snapshot payload
- restore jobs using
RestoreJobs() - simulate offline time by aging
acceptedAtUtc - observe whether restored jobs resume, complete, or fail
The key lesson is:
Offline progress is not a magic save system.
CraftingService provides job snapshot and restore behaviour.
Your game still owns the actual persistence layer.
🧭 What To Look For¶
The panel is organised around three tabs:
- Setup shows the service, owner, saved JSON state, and offline configuration ownership.
- Jobs & Save shows active jobs, lets you save snapshots, clear active jobs, and configure simulated offline time.
- Restore & JSON shows the raw snapshot payload and restore controls.
The important flow is:
- Start one or more real crafting jobs.
- Save active jobs to JSON.
- Store or copy that JSON.
- Restore the JSON later.
- Let
CraftingServicedecide whether each job resumes, completes, or fails.
💾 Persistence Responsibility¶
RevFramework does not provide a full save system.
The Crafting system exposes snapshot APIs:
SaveActiveJobs(...)RestoreJobs(...)
Your game is responsible for:
- save slots
- files
- cloud storage
- profiles
- platform persistence
- stable owner IDs
- stable recipe IDs
- resolving those IDs on restore
- deciding when save and restore happen
This scene demonstrates the snapshot pattern only.
It is not a production save-slot, cloud-save, profile, or persistence framework.
⏱️ Offline Progress Model¶
Offline progress depends on the current CraftingService offline configuration at restore time.
At a high level:
- Offline Progress OFF — restore behaves more like saved remaining-time restoration.
- Offline Progress ON — restore can compare saved
acceptedAtUtcwith the current UTC wall clock. - If enough time has elapsed, a job may complete immediately during restore.
- Completion and delivery can still fail if normal delivery rules fail.
The same snapshot can behave differently if the service settings change before restore.
Offline settings live on CraftingService, not on this teaching panel.
🧪 Simulated Offline Time¶
The panel includes an Advance Seconds field and a Simulate Offline + Restore action.
This is a teaching shortcut.
It simulates time away by shifting acceptedAtUtc backward before restore.
That lets you test offline completion without actually closing the application and waiting.
Important:
- this is not a real app lifecycle simulation
- it only changes visible behaviour when offline progress is enabled on the service
- restore still flows through normal service logic
- restore-time completion can still fail
⚠️ Sample Scope¶
This is a demo scene, not a production persistence system.
It focuses on:
- active job inspection
- snapshot JSON
- owner/recipe ID mapping callbacks
- restore behaviour
- simulated offline time
- service-owned offline settings
- delivery success or failure after restore
It does not focus on:
- production save slots
- cloud saves
- account profiles
- cross-device sync
- database persistence
- multiplayer reconciliation
- custom platform storage
Those are your game’s responsibility.
🧩 How To Use¶
- Enter Play Mode.
- Seed the required items/currency using the sample panels if needed.
- Start one or more crafting jobs, for example through the Quickstart panel.
- Open or view the
CraftingOfflineProgressPanel. - Use the Setup tab to confirm the service and owner bindings.
- Use Jobs & Save to inspect active jobs.
- Click Save Active to capture the active jobs into JSON.
- Use the snapshot summary to inspect what was saved.
- Use Restore & JSON to inspect, copy, paste, or edit the raw payload.
- Click Restore to restore the current JSON as-is.
- Click Simulate Offline + Restore to age the snapshot first, then restore.
- Watch whether restored jobs resume, complete immediately, or fail through normal service behaviour.
🔎 Failure Behaviour¶
Failures are intentional teaching signals in this scene.
Common examples:
- no active jobs → there is nothing to save
- empty JSON → restore cannot run
- invalid JSON → payload cannot be parsed
- missing job list → payload is not a valid snapshot wrapper
- unresolved owner ID → restore cannot map the snapshot back to an owner
- unresolved recipe ID → restore cannot map the snapshot back to a recipe
- delivery failure → restored completion still failed normal service delivery rules
- no output space → completed job cannot deliver its outputs
The important rule is:
Restore is not a bypass.
Restored jobs still go through CraftingService logic.
They can resume, complete, or fail depending on the current service state and configured rules.
⚠️ Clear Active Behaviour¶
The Clear Active button is a cleanup helper.
It calls CancelJob(..., refund: true) for active jobs owned by the current owner.
Refund behaviour still depends on the service and adapters.
This is not a production save-system rule.
⚠️ Authority Note¶
This scene may include a local sample authority setup configured to allow crafting.
That means:
- crafting behaves permissively in this sample
- authority is not the focus of this scene
- this is not a multiplayer or server-authority implementation
To enforce real authority:
- provide an
ICraftingAuthorityimplementation - wire it into
CraftingService - do not rely on simply adding a component to the scene
🌐 Networking Reminder¶
RevFramework does not implement:
- networking
- replication
- prediction
- rollback
- reconciliation
These samples demonstrate local behaviour and persistence patterns only.
Cross-device sync and multiplayer behaviour are your responsibility.
⚙️ Behind The Scenes¶
The panel uses public CraftingService APIs only, including:
SaveActiveJobs(...)RestoreJobs(...)GetJobs(...)CancelJob(...)
Snapshot save/restore uses public mapping callbacks:
- owner ID selector
- recipe ID selector
- owner resolver
- recipe resolver
The panel does not:
- reflect into private fields
- mutate private offline configuration
- bypass delivery rules
- pretend to be a production save system
Restore-time completion still flows through normal service logic.
🧾 Recipe Type Used In This Scene¶
This scene may use RecipeCore assets directly to keep snapshot/restore behaviour explicit.
RecipeCore is the runtime recipe format used by CraftingService.
Wrapper assets are authoring conveniences that resolve into RecipeCore at runtime.
Using RecipeCore directly in this scene keeps the persistence example easier to inspect and debug.
Important:
- this is not a requirement for using persistence
- wrapper-based recipes can still be used if they resolve correctly in your project
- your own project should use stable recipe IDs suitable for your save system
💡 Key Takeaway¶
Offline progress is based on saved job snapshots and real elapsed time.
When a player returns, restored jobs may:
- resume
- complete immediately
- fail during restore-time delivery
The Crafting system provides the job snapshot and restore API.
Your game owns persistence, storage, stable IDs, and restore timing.
That separation is the point of this scene.
Panel: CraftingOfflineProgressPanel
Scene Path:
Assets/RevFramework/Samples/Systems/Crafting/Scenes/04_Offline_Progress_Persistence/