Changelog

1.0.0 — the first release#

The first release. What changed since 0.2.0-preview.1:

Changed#

  • Dependencies are declared in the package manifest: Unity UI (com.unity.ugui), because the save menu builds its own screen, and the Unity Test Framework (com.unity.test-framework) for the package's own test suite (editor-only; nothing extra reaches a player build). Neither was declared before, so a project that did not already have Unity UI could not compile the package.
  • Every piece of session state is reset at the start of every play session: the save folder and slot a game chose, the cloud provider and its settings, the protection passphrase and its cost, the offline cap and clock policy, the retired list, the key renames, the registered migrations, the asset registry a game assigned, the caches built from the scene, and the last result. Behaviour is now identical whether or not a project reloads the script domain when it enters Play mode.
  • The licence is stated: LICENSE.md names the Unity Asset Store End User License Agreement, and records that no third-party code is bundled.
  • Verified: 462 Edit Mode and 74 Play Mode tests (0 failures, Unity 6000.3.25f1); a Windows x64 IL2CPP player built with 0 errors and run twice from a clean save folder (77 checks, 0 failures, exit 0 both runs); a clean install into a project created from scratch; and the three demo scenes played and saved from.

Compatibility#

A save written by any 0.1.0-preview.8 or later loads unchanged: the saved-data format is still format 2, and the public API is unchanged. Nothing has to be migrated, and nothing has to be re-saved.

0.2.0-preview.1 — cloud copies, migrations, and the field-level release#

Added#

  • Retiring something for good. Persist.Retire(id) records that the player destroyed something permanently, so a later load of a save that still lists it does not rebuild it; Unretire, IsRetired, RetiredCount, Retired() and ForgetRetired() sit beside it, Spawn refuses a retired id with PK-INSTANCE-001, and SaveInstances leaves a retired object out of the write. Objects, scenes and retirement also writes down what identity means across additive scenes, unloads and DontDestroyOnLoad.
  • Three more samples that run: a clicker with capped offline progression, a physics sandbox whose crates are saved, restored and retired for good, and a top-down game with three save slots through the real save menu.
  • A measured performance page in the package, with the probe that produced the numbers.
  • An Input System fix: the save menu's Event System helper used to add a classic input module in every project, which throws every frame where input is read through the Input System package.
  • A cloud provider contract, and two complete providers. FolderCloudProvider keeps saves in a folder that something else synchronises — Dropbox, OneDrive, a network share, a USB stick — with no account, no SDK and no package. RestCloudProvider talks to any HTTP endpoint, with conditional writes through If-Match, metadata through HEAD, deletion, progress, cancellation and a documented mapping from HTTP status to code. A third, MemoryCloudProvider, is an in-memory double for tests and for trying the workflow.
  • The whole cloud behaviour, above the seam. Deciding which copy wins, refusing to overwrite a copy that moved, remembering what was uploaded, marking a save made offline and sending it later, and reporting every failure with a code — the same for every provider.
  • Conflicts are a question. PK-CLOUD-004 and an explicit choice: KeepLocal, KeepRemote or KeepBoth. The last exists because there is always an answer that loses nothing.
  • Migrations. SaveMigration and Persist.Migrations: rename a key, add a default, remove one, convert a value, or run your own code, as ordered steps from one saved-data version to the next. Preview first, a copy before writing, validate before committing, and roll back if the write fails.
  • Editor assistants. Cloud status, upload, download, sync and conflict answering; migration preview and apply; both through the same public API a game uses.
  • Lists of references. Persist.SaveReferences and Persist.LoadReferences save a party, an inventory or the buildings on a grid in one call, each item written the way a single reference is. The order is the list: an item that cannot be found leaves an empty position and is reported, so nothing shifts along. One list holds one kind — mixed lists are refused with the sentence saying so.
  • Inspector help for the two new components. PersistKitAutoSave and PersistKitSaveMenu read their settings back in plain words, name the combinations that quietly never save anything, and point out the one scene dependency a menu has. In Play mode they show the live state.
  • A save inspector and diff (Tools ▸ PersistKit ▸ Inspect or Compare Saved Games). The file, its status with the exact code when it cannot be read, every key with its kind in words and its stored text, and what changed between two saves. It never writes, never repairs and never switches the game's slot.

Fixed#

  • A saved game with a picture beside it no longer brings the save menu down. A row with a thumbnail asked for a RawImage on the same game object that already carried the row's background Image, and Unity allows one Graphic per game object. It reports the refusal by returning null from AddComponent, so the line after it threw a NullReferenceException: the menu worked until a player actually saved a game with a picture on it, and then the screen failed to open at all. The picture now has a game object of its own inside the holder, and a new PlayMode test writes a real picture beside a real save and opens the menu.
  • The package did not compile in a project that did not already have Unity UI. The runtime uses UnityEngine.UI and UnityEngine.EventSystems (the save menu builds its own screen), but package.json declared no dependencies at all, so a brand-new Unity project failed with CS0234: The type or namespace name 'UI' does not exist in the namespace 'UnityEngine'. com.unity.ugui is now a declared dependency. A clean-install test found this, which is the only kind of test that could have: every project used during development already had Unity UI.
  • PersistKitAutoSave.AutomaticSaving and IntervalSeconds described a clock that had not started when read before the game runs. They now answer from the Inspector's settings until the game starts, and a value set from code before Awake is no longer overwritten a frame later.

Compatibility#

A save written by 0.1.0-preview loads unchanged: the file format and the saved-data layout are the same, and the version gate now measures "newer" against the version this build writes, so a game that raises its schema version with a migration never refuses a save it just wrote itself.

0.1.0-preview — the field-level and reference release#

  • Field-level saving: two flags per field — save and load — chosen in the Inspector, with PersistKitFieldSet for the same choices from code. A field that is not chosen is not in the file at all.
  • Asset references: a save can point at a Sprite, a ScriptableObject or a prefab by the key it is registered under in a PersistKitAssetRegistry, and find it again in a player build. Never a path, a GUID or an instance id.
  • Runtime prefab instances: Persist.Spawn, SaveInstances and LoadInstances remember which prefab an object came from and which instance it is, and never duplicate one on a second load.
  • Protection: Persist.Protection.SetPassphrase turns on AES-256-CBC with HMAC-SHA256 authentication and PBKDF2 key derivation; compression when it genuinely makes a file smaller.
  • Slots, metadata, backups and the recovery ladder: named slots with their own files and descriptions, rotating backups, and a load that completes a damaged save from the newest copy that still works.

How each release is checked#

The full Edit Mode and Play Mode suites (462 and 74 tests on 1.0.0, all passing), a source guard that refuses reflection, background threads and JIT-only APIs in the runtime, an assembly-boundary guard, and a package-version guard. What was run, and what was not, is on the platforms page — including the in-player IL2CPP checks for this version and the clean-install test, both of which found real defects. Performance claims come from the measured numbers and the probe that produced them, in the package's Documentation~/performance.md, never from a feeling.