Updates and auto-patching
How every platform stays up to date — the Windows launcher/patcher (signed manifest, delta downloads, verify, atomic swap, rollback), content updates through Unity Addressables, store updates and the "update required" gate on Android/iOS, and why the browser still needs a version check.
Decision (owner, round 6): downloaded games (Windows, Android, iOS) must patch themselves. Versions follow
release.json (MAJOR.MINOR.PATCH+build); the server rejects a client whose MAJOR.MINOR differs ("Update required").
◆Two kinds of update
| Kind | What changes | How it ships | Store review? |
|---|---|---|---|
| Content update | zones, models, textures, audio, balance data, events, UI art | Unity Addressables remote catalog on the CDN; the client checks it at start and at login and downloads only changed bundles | no |
| Binary update | C# code, engine version, native plugins | new build per platform | Android/iOS: yes |
Most patches should be content updates, so players rarely wait for a store.
◆Windows: launcher + patcher
- A small launcher (separate from the game; it can update itself) downloads a signed manifest: version, files, sizes, SHA-256 hashes, and delta patches from the previous versions.
- It downloads deltas when available (otherwise whole files) from the CDN, resumes interrupted downloads, and verifies every file's hash.
- It installs into a new version folder and switches atomically; the previous version stays for one-click rollback. A failed or corrupted update never leaves a half-patched game.
- Then it hands the session to the game (the sign-in from Accounts and sign-in).
- Code-signing the launcher and game avoids Windows SmartScreen warnings; the certificate is a yearly cost → owner decision (OPEN-10). Shipping on a store such as Steam later would replace this launcher with the store's updater.
◆OPEN-10 explained: Windows code signing
What it is. When a player downloads a program on Windows, the system checks who published it. A program signed with a code-signing certificate shows your studio name; an unsigned one shows a blue "Windows protected your PC — unknown publisher" screen (SmartScreen) and some antivirus tools flag it. The certificate is a file that proves "this exact build came from us and was not changed", and it must be bought from a certificate authority.
Do you need it now? No. For your own tests and the closed alpha, testers can click "More info → Run anyway" (or you can tell them to expect it). It only matters when you want strangers to install without friction.
What the options cost (typical ranges, verify before buying): a normal code-signing certificate is about US$200–500 per year (the authority checks your identity or company; the private key must live on a hardware token or a cloud signing service); Microsoft's own cloud signing service ("Trusted Signing") is about US$10/month but only for eligible developers in some countries; no certificate at all if you publish through Steam or the Microsoft Store, because the store signs or vouches for the package.
What it does not cover. Android and iOS builds are signed through Google Play and Apple (their developer programs, OPEN-5), and the Web build needs no signing.
Suggestion. Skip it for the alpha. Decide when you choose how to ship the Windows build: a store (no certificate needed) or your own download page (buy a certificate, set aside the yearly cost under the PHP 5,000 rule).
◆Android and iOS
- Content updates through Addressables as above (a progress screen on start when something changed).
- Binary updates through the stores. On start the client asks
/v1/statusfor the minimum supported version:- below it → a blocking Update required screen with a button to the store page (Android uses the Play in-app updates flow, immediate mode);
- newer optional version → a dismissible "Update available" banner (Android flexible in-app update).
- Keep mobile builds backward compatible with the server for one MINOR version whenever possible, so a store review delay doesn't lock players out.
◆Browser (Web build)
Mostly automatic — a reload always loads the newest build — but two things still need handling:
- Open tabs keep the old build. The client checks
/v1/statusat login, on reconnect and every 5 minutes; an incompatible version shows "A new version is ready — reload" (forced at the next login; never mid-fight). - Caching: build files are content-hashed and cached forever; the page itself (
index.html) and the Addressables catalog are served with short cache times, so a deploy is picked up on the next load. No aggressive service worker.
◆Server rollouts
Announce maintenance on the site and in game (release.json patch notes), restart channels in turn, keep the previous
server build ready for rollback, and raise the minimum client version only when the protocol changes.
◆Tests
- Patcher: v1 → v2 delta, corrupted download (hash mismatch → retry), interrupted download (resume), failed install (rollback), launcher self-update.
- Addressables: catalog update downloads only changed bundles; offline start uses the cached content.
- Version gate: an old client gets "Update required"; the Web build shows the reload banner (Playwright).
Source: zoen/docs/tech/PATCHING.md · 854 words · edit the Markdown, not this page.
