Offline progression
Give a Unity game something to do about time passing while it was closed — energy, crops, daily rewards — with an honest limit on what a client-side clock can prove.
What it is#
Idle games, farming games and anything with energy or daily rewards need the same two facts: *when was the player last here*, and how long has it been. PersistKit keeps the first and works out the second:
PersistOfflineSession session = Persist.Offline.Elapsed();
refillEnergy(session.ElapsedSeconds); // already capped for you
Debug.Log(session.ElapsedText); // class="tok-str">"2 hours 14 minutes" — for a welcome-back messageMarkSeen() records this moment as the player's latest visit. Do that when they finish collecting, not when they arrive, so closing the game in the middle of a collection does not lose it.
Available In the package and covered by tests.
What it refuses to guess#
A clock on a player's machine is not evidence, so PersistKit never pretends it is one. Elapsed() tells you exactly which of three things happened:
| What you get | Meaning |
|---|---|
session.Capped | The time off was longer than MaxOfflineSeconds, so it was capped. You set the cap; 0 means a day. |
session.ClockWentBackwards | The clock now reads earlier than the last visit — code PK-OFFLINE-001. |
session.Accepted | Nothing unusual: the time off was used as it was measured. |
A damaged record is reported as PK-OFFLINE-002 rather than silently becoming "no time has passed".
Choosing what to do about a wrong clock#
Persist.Offline.ClockPolicy is your decision, and it is a one-line one:
- Clamp gives the player nothing for that session. Safe for competitive economies.
- Reject refuses the session outright and reports it, so your own code can decide.
- Accept takes the clock at its word. Kindest for a single-player game where cheating is not the threat.
The calls#
| Call | What it does |
|---|---|
Persist.Offline.Elapsed() | The time since the last visit, with the flags above. Never writes anything. |
Persist.Offline.MarkSeen() | Records this moment as the latest visit. |
Persist.Offline.Begin() | Starts a session deliberately, for a game that wants to control when the clock starts. |
Persist.Offline.Reset() | Forgets the record — for a new game, or a "start over" button. |
Persist.Offline.MaxOfflineSeconds | The longest stretch a single session is allowed to be worth. |
Persist.Offline.HasRecord / LastSeenUtc | Whether there is a record, and when it was made. |
Elapsed() on a first run is not an error: there is simply no record yet, and HasRecord says so.
Something wrong on this page? Every page here describes behaviour that is checked in the repository. If a page and the package disagree, the package wins.
Report a documentation problem · Error codes · Platforms and limitations