Files
LlamaCasty/docs/ai/commercial.md
T
gramps ff5e8d94ae 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
2026-11-02 09:18:03 -08:00

12 KiB
Raw Blame History

Commercial: pricing, entitlement, channels, support

The single source of truth for what LlamaCasty charges, what a licence entitles, how it ships and what support it does and does not include. Read before any pricing, licensing, distribution, storefront, support or promo work. Cause of death for every retired path: decisions.md. Release mechanics (build, depot, SteamPipe upload): Distribution.md.

Model — one purchase, one price

  • Free tier — every feature, every scene, every overlay, free forever, no account, no watermark, nothing nagged inside the output. It is not a trial.
  • Pro is the paid Steam app; the free Demo is associated with it. The paid app is $79 during the announced launch period, then $99 on the announced date. No subscription or third-party checkout.
  • The only delta is output quality. Features are never gated; a payment buys pixels.
  • No watermark, ever, in either edition. The branding flash is retired as a paid delta and stays off (ShowBrandFlash, default false).
  • Clean numbers, no .99, no discount codes, no countdowns. The one dated exception is the introductory price: it is announced in advance, shown where the price is shown, and actually raised on the date — otherwise the next announcement is worthless.
  • The site publishes the model, never the numbers — "free forever, every feature unlocked, a paid edition with higher output quality at launch". Price, tier name, cap and frame rate are published by the app, at the point of sale, not by the page.

Output profile — the one entitlement rule

The cap is a pixel budget plus a frame rate, not the word "720p":

Free Pro
Pixels ≤ 921,600 any shipped tier
Frame rate ≤ 30 fps any shipped tier
Landscape 1280×720 @30 1280×720 @60 · 1920×1080 @30 · @60
Vertical 9:16 720×1280 @30 1080×1920 @60
  • Records too. The cap governs the file the creator keeps as well as the stream; otherwise free 1080p recording is a re-upload hole. There is one ffmpeg process with two output blocks (FLV to RTMP, MP4 to disk) fed by one EncoderOptions, and the profile is resolved once when those options are built (MainViewModel.Streaming.Operations.cs → Models/OutputProfile.cs). There is no second encoder to keep in step and therefore no second check to forget.
  • Fail closed. Unresolved, unreadable or unvalidated entitlement = free tier. Never Pro.
  • The development override exists and never ships. MainViewModel.DeveloperMode bypasses the budget in a Debug build only; the Settings row that toggles it is excluded from the Release compile (ytLive.csproj removes its Page and code-behind), and the setter refuses the value when Helpers/DevBuild.IsDevelopment is false. Not a hidden row — an absent one.
  • Never downgrade a running stream. The gate applies to the next start; pulling quality out of a live broadcast is a worse bug than one free 1080p session.
  • The greyed menu entry is the sales surface. It stays clickable, says what it costs, opens checkout, and is labelled ("720p30 · free tier") — never silently missing, because silence reads as broken.
  • Ownership is checked at app startup and cached in IsAppOwned for that run. Purchases and refunds are reflected on the next app start; there is no subscription lapse or sign-out path.
  • Bitrate follows the profile — a capped user is not offered a 1080p bitrate.

Entitlement — one source

Paid-app ownership is the one entitlement. Steam sells one paid app; its associated free demo is the purchase funnel. Both use the same code. The demo checks whether the current Steam account owns the paid app, then exposes the higher output tiers. The app-wide IsAppOwned value is the binary ownership result used by later feature checks.

  • Steam owns the purchase. The demo calls BIsSubscribedApp(paidAppId) after SteamAPI.Init, behind IEntitlement (Services/Entitlement/). It is a local check against Steam's own state — no server, key, lease, or LlamaCasty account.
  • Fail closed: no paid app ID configured, SteamAPI.Init() false (no client), a thrown native load (missing steam_api64.dll), and "not owned" all resolve to the free tier. None of them may crash the app or grant Pro.
  • Steam down or not running → free profile, with a line explaining why, never a refusal to start. A Steam build launched outside Steam is the common case for people who pin shortcuts.
  • Development builds fake ownership as true. FakeEntitlement is excluded from Release builds.
  • No licence key exists, so nothing to paste, email, lose or reclaim. A refunded purchase stops reporting ownership on the next Steam check.
  • The upgrade path is the Steam store overlay (ActivateGameOverlayToStore) from the greyed tier menu — Valve's own surface, so the purchase stays inside the Steam Wallet rules. Never a checkout of ours, never an external payment page.
  • No leases, no dunning, no portal, no device limits. A one-time purchase has one state: owned or not.

⛔ Subscriptions and third-party checkout are retired for launch — see decisions.md. Polar stays dormant; its design is recorded there so it is not re-derived.

Channels — Steam only

Steam is the distributor. One paid app and its associated free Demo; no direct download, GitHub binary, winget, Scoop/Chocolatey, or Microsoft Store. The store page is the single authoritative source for the download, stats, and reviews.

  • The paid app is one-time purchase. The demo's App ID is separate, but it shares the code and checks ownership of the paid app (ISteamApps::BIsSubscribedApp). No in-app checkout or license server.
  • The website sends people to Steam. It publishes the model and links the store page; it takes no payment, collects no email, and hosts no binaries. One shop, one price, one receipt.
  • No in-app checkout of ours, ever. Steamworks requires in-app purchases to use the Steam Wallet, so the only purchase surface is Steam's own store overlay.
  • Boot shape: the app ships steam_api64.dll beside the exe and calls SteamAPI.Init. Launched without Steam running, the app falls back to the free profile and says so; it never refuses to start.
  • Updates are Steam's. The depot push is the update; the app keeps no updater and no version banner (the old "no self-updater" rule stays, for the same reason: it works differently).
  • Portable mode is no longer a distributable. portable.txt remains as a feature for anyone who copies the installed folder; it is not a delivery mechanism.
  • Steam Direct is $100 per app, recoupable after $1,000 adjusted gross revenue.
  • Price parity is trivially satisfied — there is no off-Steam price to keep in step.

Not channels, ever: direct download, winget/Chocolatey/Scoop, the Microsoft Store, Patreon or any subscription platform of our own, paywalled early access, a paid beta, a Discord. Content is the funnel; Steam is the checkout.

Support surfaces this creates: the Steam store page's support contact, Steam Announcements for known issues and release notes, Steam Discussions left pinned and unread, and one public issue repo for bugs that survive the friction of needing an account.

Signing — not needed for the Steam channel

  • Steam installs never meet SmartScreen. Valve's client delivers the files, so there is no browser download, no Mark-of-the-Web and no "unknown publisher" wall. The certificate that existed only to soften that wall has nothing to do.
  • Artifact Signing (renamed from "Trusted Signing") stays on the shelf: Azure Artifact Signing, $9.99/month Basic, requires a paid Azure subscription, individual identity validation is the slow part. Buy it the day a non-Steam download exists — the zip case, not this one.
  • Never EV, never a certificate with an HSM. Microsoft removed the EV SmartScreen instant-bypass in March 2024; it buys nothing.
  • Steam does not sign our exe either — it just never puts it through the browser gauntlet. Windows may still show a UAC prompt for the app; that is elevation, not publisher trust.

Support

Email. Best effort. No SLA. Refunds granted on request, without argument.

  • There is no training service. "I want people to succeed" is not "I will train them". The app teaches itself — one-click go-live, five scenes, nothing to configure. A how-to question means the app or its docs fell short; the answer is a fix or a video, not a conversation.
  • No helpdesk. No ticketing system, no live chat, no onboarding calls, no hand-holding.
  • A repeated question is a video, not a ticket — see MARCOM.md → support → content loop. The training channel is the support surface.
  • The issue tracker is a filter, deliberately. Bugs go to the public releases repo on GitHub, which requires an account; Steam Discussions stay pinned and unread; Announcements carry known issues and release notes. Steam refunds are Valve's own (2 h / 14 days) and cost us nothing.
  • Nobody is locked out of streaming. If Steam ownership is unavailable or not owned, the app remains usable at the free output profile; no modal or account portal.

The introductory price — the only promotion

Cash cost $0. With one SKU there is no coupon, no founder tier, no pass and no reminder cadence.

  • $79 until a stated date, then $99. The date is announced at launch on the store page, the site and the in-app upgrade panel, and it is honoured — an introductory price that never rises makes the next announcement worthless.
  • No launch discount stacked on top. Two overlapping stories ("introductory" plus "15% off") muddy both, and the increase afterwards triggers Steam's 30-day discount cooldown.
  • No coupons, no keys, no founder badges. A one-time Steam purchase has nothing to administer.

Costs

Item Cost
Domain ~$15/yr
Droplet $0 — serves the existing site
Steam Direct $100 once, recoupable after $1,000 AGR
Steam revenue share 30% → $79 nets $55.30, $99 nets $69.30
Polar $0 — dormant. No subscription at launch
Steamworks, public issue repo, Gitea $0
Azure Artifact Signing — not needed Steam installs don't meet SmartScreen
Microsoft Store — not used —

Fixed year one ≈ $115 (domain + Steam Direct, one time). At $79, three sales cover the year. The Steam cut is the price of not running a storefront, a certificate or an update path.

Signing is now moot as a launch cost. Steam installs never meet SmartScreen, so the certificate that existed only to soften that wall has no job. Artifact Signing stays on the shelf for the day a non-Steam download exists.

Anti-piracy posture

Any check that runs on the user's machine can be removed. The goal is a crack that is pointless and a leak that is traceable — not an unbreakable binary.

  • The free tier is the real defence. If the only delta is pixels above 921,600, a cracked build buys almost nothing and forfeits updates, support and the publisher's signature.
  • Steam DRM is optional and not needed. The app ownership check is the entitlement; adding Valve's DRM wrapper buys nothing a determined crack respects, and it can break an exe on a machine that never runs Steam.
  • The distribution is not a handout. Steam deliveries go through Valve's client and account, so there is no public zip for a mirror site to repackage, and no hash pin for us to maintain.
  • Steam is the ownership state — a refunded purchase stops reporting ownership on the next check. The app holds no customer account or license key.

⛔ Rejected, do not re-propose: a native helper DLL for "IP protection", obfuscation, hardware locking, remote code that downloads and executes, and gating asset downloads as an auth check. None of them make a licence enforceable; the first three add failure modes without buying anything, the fourth needs the server this plan exists to avoid, and the fifth is Store policy 10.2.2.