feat(entitlement): pivot to paid app ownership

Check Steam ownership of the paid app with BIsSubscribedApp; keep Debug fake ownership out of Release. Ref: https://partner.steamgames.com/doc/api/ISteamApps#BIsSubscribedApp
This commit is contained in:
2026-11-02 09:18:03 -08:00
parent 54902cb838
commit ff5e8d94ae
17 changed files with 229 additions and 217 deletions
+8 -10
View File
@@ -199,9 +199,9 @@ Live channel policy, the artifact and costs: [`commercial.md`](commercial.md). B
mechanics: [`Distribution.md`](../../Distribution.md). Retired routes and cause of death:
[`decisions.md`](decisions.md).
**One vector: Steam.** A free app on Steam with the paid edition as a Steam **DLC**; the monthly
plan is sold outside Steam and is never purchasable inside a Steam build (Steamworks requires the
Steam Wallet for in-app purchases). No direct download, no winget, no Microsoft Store.
**One vector: Steam.** One paid app plus its associated free Demo. They use the same code; the Demo
checks ownership of the paid app to unlock higher output quality. No direct download, no GitHub
binary, no winget, no Microsoft Store, and no subscription.
**Consequences that are architecture, not packaging detail:**
@@ -209,7 +209,7 @@ Steam Wallet for in-app purchases). No direct download, no winget, no Microsoft
app keeps nothing that downloads or executes, for the same Store-policy reason it always had.
`ytLive.Tests/StorePackagingTests.cs` must keep asserting that no self-updater returns.
- **⛔ `steam_api64.dll` is a functional dependency**, not the rejected "native helper DLL for IP
protection" — Steam DLC ownership cannot be read without it. The app must start without Steam
protection" — Steam app ownership cannot be read without it. The app must start without Steam
running and fall back to the free profile.
- **The MSIX package stays buildable but is now unused** — `scripts/package-msix.sh` (TASK 48
slice 2) still produces `artifacts/LlamaCasty.msix` from `Packaging/Package.appxmanifest` +
@@ -265,11 +265,10 @@ a non-Steam download exists:
### Distribution and licensing are independent — the channel never decides billing
The Steam build sells the lifetime as **Steam DLC** and reads it with `BIsDlcInstalled`, while the
monthly plan is billed by **Polar** outside Steam. Steamworks forbids taking payment inside the app
with anything but the Steam Wallet, so the app states where the monthly lives and never sells it.
The lesson worth keeping: the licensing choice rides on a **monetization** decision, not on a
distribution decision.
Steam distributes the paid app and its associated free demo. They use the same code; the demo asks
Steam whether the current account owns the paid app, and the answer controls access to higher output
quality. The paid app is a one-time purchase: $79 during the announced launch period, then $99 on
the announced date. The app's EULA must expressly allow commercial and monetized streaming use.
### ⛔ "Only when the user says so" is enforced by Windows, not by us
@@ -311,4 +310,3 @@ nothing. COPPA is very unlikely to bind (not child-directed), but note the enfor
(FTC Sept 2025 *Apitor*: operators are responsible for what third-party components collect) —
so the answer is a documented inquiry, and ours is "no third-party analytics or ad SDKs, no
persisted chat or reward payloads."