Files
LlamaCasty/Distribution.md
T
gramps 27f655c8de copy(price): the launch price ends on an event we control, not on Valve's queue
The promo read 'until April 1, 2027', which is a public promise tied to a review queue outside our
control: identity verification and the tax interview are in Valve's hands (they quote up to 30 business
days), and the store page and build reviews follow. If any of that slips, the date becomes untrue.

It now reads '30 days after the store page goes live — after that $99, locked for life', in the About
box and in commercial.md, so the claim cannot be wrong however long Valve takes.

Also recorded: the $100 Steam Direct fee is PAID (creator, 2026-11-05); a store page can be configured
once identity clears. The launch-price deadline no longer depends on Valve's calendar.
2026-11-05 15:13:20 -08:00

8.6 KiB
Raw Blame History

Distribution & release mechanics

How the build becomes an install on someone's PC. Policy — prices, entitlement, why Steam is the only channel, support — is docs/ai/commercial.md. This file is the how.

Superseded twice on 2026-10-31. The 736-line Polar/MSIX/obfuscation plan is in git log -- Distribution.md; the zip-plus-winget plan written earlier the same day is in the same place. The reasoning that survives lives in commercial.md and docs/ai/decisions.md.

1. The artifact

A self-contained win-x64 publish plus the bundled ffmpeg\ folder, uploaded to a Steam depot. No installer, no admin rights, no zip for anyone to mirror.

dotnet publish ytLive.csproj -c Release -r win-x64 --self-contained true \
  -p:PublishSingleFile=true \
  -p:IncludeNativeLibrariesForSelfExtract=true \
  -p:EnableCompressionInSingleFile=true \
  -p:PublishReadyToRun=true -o artifacts/steam-stage
  • PublishTrimmed stays OFF. Trimming breaks WPF's XAML reflection (Binding, DataTemplate, StaticResource). Expect ~110–150 MB in the depot; that is the cost of "no .NET install".
  • ffmpeg stays outside the exe — ffmpeg\ beside it (the app's locator contract, see output.md → "FFmpeg locator").
  • steam_api64.dll ships beside the exe and is loaded at startup; without it the app cannot read DLC ownership. Its absence must degrade to the free profile, never to a crash.
  • WebView2 is the one machine dependency. Valve's Common Redistributables configure the Evergreen bootstrapper as a prerequisite, so the depot declares it instead of us shipping it.
  • AssemblyName is LlamaCasty (renamed 2026-11-01, before the first depot because Steamworks warns about renaming a live exe) → the artifact is LlamaCasty.exe plus its ffmpeg\ folder. scripts/publish.sh stages both and refuses to finish if either is missing.
  • ⛔ ExcludeFromSingleFile="true" on the ffmpeg content. Without it, PublishSingleFile + IncludeNativeLibrariesForSelfExtract swallow the libav*.dll family into the exe — a 182 MB binary with no ffmpeg\ folder beside it, so the locator finds nothing and every stream fails at runtime. The publish output is ~257 MB: 127 MB exe + 129 MB ffmpeg.
  • Portable mode (portable.txt → .\data\) survives as a feature for a copied install; it is not a delivery vector.

2. Steamworks setup, once

The SDK zip is the only download. It is ~24 MB and contains the runtime (sdk/redistributable_bin/win64/steam_api64.dll) and the release tooling (sdk/tools/ContentBuilder/ → steamcmd.exe for Windows, steamcmd.sh for Linux/macOS, plus the app_build_*.vdf / depot_build_*.vdf templates). There is no separate "ContentBuilder download" on the partner dashboard — the dashboard's Downloads page only re-offers the SDK.

Reference links, so nobody hunts again:

What Where
SDK zip (sign in to partner first) partner.steamgames.com/downloads/steamworks_sdk.zip
Docs home partner.steamgames.com/doc/home
SteamPipe upload (steamcmd + VDF fields) partner.steamgames.com/doc/sdk/uploading
Demo configuration partner.steamgames.com/doc/store/application/demos
Paid app ownership (BIsSubscribedApp) partner.steamgames.com/doc/api/ISteamApps#BIsSubscribedApp
Store artwork sizes partner.steamgames.com/doc/store/assets/standard
Coming Soon / 2-week public window partner.steamgames.com/doc/store/coming_soon
Wallet rule (in-app purchases) partner.steamgames.com/doc/features/microtransactions
Recurring subscriptions partner.steamgames.com/doc/store/pricing/subscriptions
Partner support help.steampowered.com/en/wizard/HelpWithPublishing
Steamworks.NET (managed wrapper) nuget.org/packages/Steamworks.NET

Status (updated 2026-11-05 — this is a WAIT on Valve, not a task of ours)

Step State
Partner account created ✅ done by the creator
Identity verification ⏳ pending — Valve reviewing
Tax interview ⏳ submitted; Valve quotes up to 30 business days to review
$100 Steam Direct fee ✅ paid (creator, 2026-11-05) — a store page can be configured once identity clears
App IDs (paid app + free Demo) not yet assigned
Store page not created
Build review not started

Critical path from 2026-11-05, using Valve's own published windows:

  1. identity + tax review — up to 30 business days (~6 calendar weeks) → mid-December
  2. fee paid, app IDs assigned, store page built and submitted
  3. store page review — up to 12 business days (Valve's current backlog; docs still say 3–5)
  4. page public ≥2 weeks before release (Valve's rule)
  5. build review — up to 12 business days

Earliest realistic launch: early-to-mid February 2027. The launch-price deadline is no longer a date: it now ends 30 days after the store page goes live (2026-11-05), so Valve's queue cannot make the public claim wrong.

Nothing below can start until step 1 clears; none of it blocks the app work.

  1. Store page configured and made public two weeks before release — Valve's rule, and it is the window where wishlists accumulate.

3. Release

publish → steam-stage → steamcmd + app_build.vdf → build upload → set live → announcement
  1. Upload the depot with steamcmd +login <user> +run_app_build ..\scripts\app_build_<appid>.vdf +quit. The VDF names the app, depot, content root and branch.
  2. Set the build live in Steamworks → Builds → the new build → Set Build Live on the default branch. That is the release; there is no artifact to hash and no manifest to submit.
  3. Announce with Steam Events (release notes appear in the library and on the store page).
  4. Verify: install the Demo from a clean Steam account, confirm paid-app ownership is false, then test with an account that owns the paid app and confirm the higher tiers unlock.

Updates are the same upload with a higher build ID. The app keeps no self-updater and no version banner — Steam is the update path, and that policy has not changed.

4. Entitlement wiring

  • IEntitlement reports IsAppOwned. Debug uses a fake owned result; Release checks the paid app ID through BIsSubscribedApp. MainViewModel.IsAppOwned is the app-wide binary ownership flag.
  • The paid app ID is not yet configured. Until it is assigned, the Release path fails closed without touching the native library.
  • Fail closed on every path: no id, no client, missing DLL, thrown load, not owned.
  • The EULA should expressly allow commercial/monetized streaming use; confirm with counsel or Valve that this satisfies the Steam Subscriber Agreement's software terms.
  • Never gate a feature. The only delta is the output profile.

5. Release checklist

  • Build clean, 0 warnings (./scripts/verify.sh), tests green.
  • steam_api64.dll present; app starts without Steam and falls back to the free profile.
  • Paid-app ownership false → free profile; true → higher output tiers offered.
  • LlamaCasty.exe rename landed (never rename a live exe).
  • Clean Steam install on a second machine, then an update pushed and observed.
  • Store page public for the full two weeks; support contact and announcements configured.
  • Portable mode: portable.txt present → data lands in .\data\.
  • LICENSE (EULA) forbids redistribution, resale, reverse-engineering and circumvention, and disclaims warranty.
  • PRIVACY.md must name any third party the app contacts — Google/YouTube. Steam itself is named by Valve's own policy, not ours.
  • THIRD-PARTY-NOTICES.txt stays shipped and shown in About; the ffmpeg pin stays lgpl-shared; no GPL component may be linked (see product.md → "Licensing").
  • DMCA: a takedown needs only the notice — host, link, good-faith statement, signature. Statutory damages need a registration ($65). Worth doing once there is something to pirate.
  • What actually protects the product is in commercial.md → "Anti-piracy posture": a useful free tier, Steam's own delivery, and Steam ownership of the paid app. Not obfuscation, not a native DLL, not hardware locking.

7. Effort, once

Step Effort
Steamworks onboarding + $100 fee 0.5–1 day, mostly waiting on verification
Publish profile + steam_api64.dll + IEntitlement Steam path 1 day
Depot + first steamcmd upload 0.5 day, then ~15 min per release
Store page + assets (screenshots, capsule art) 1–2 days
Clean-account Demo install + paid-app ownership test 0.5 day