From 1fe84be64a52807a4a84f5b4f6df967ff575dce0 Mon Sep 17 00:00:00 2001 From: gramps Date: Sun, 1 Nov 2026 07:23:29 -0800 Subject: [PATCH] =?UTF-8?q?build(steam):=20stage=20steam=5Fapi64.dll=20bes?= =?UTF-8?q?ide=20the=20exe=20=E2=80=94=20one=20file,=20not=20the=20whole?= =?UTF-8?q?=20SDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SDK zip is 24 MB of headers, examples and tools we never build. The runtime dependency is one native library, so scripts/steam-sdk.sh extracts exactly sdk/redistributable_bin/win64/steam_api64.dll into steam/ (gitignored, like ffmpeg/ — the script is the audit trail) and writes steam_appid.txt = 480, Valve's Spacewar app, so SteamAPI.Init() resolves an app id locally before LlamaCasty has one of its own. Two csproj details that would have cost a debugging session: - Link="steam_api64.dll" puts it BESIDE the exe; without Link, None items keep their relative path and it lands in steam/, where the loader does not look. - ExcludeFromSingleFile, for the same reason ffmpeg needed it: a native DLL otherwise gets swallowed into the single-file bundle and cannot be loaded at runtime. steam_appid.txt is Debug-only — Valve's guidance is not to ship it — and the publish output confirms it: dll present at the root, no appid file, exe still 127 MB (proof the DLL was not bundled). Also queued, as asked: preview undo (Ctrl+Z / Ctrl+Shift+Z) in edit mode, noted as the partner to the defaults-vs-current split — undo covers the slip, defaults cover the mess. --- .gitignore | 4 ++++ Distribution.md | 9 ++++++--- TASKS.md | 1 + scripts/steam-sdk.sh | 45 ++++++++++++++++++++++++++++++++++++++++++++ ytLive.csproj | 15 +++++++++++++++ 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 scripts/steam-sdk.sh diff --git a/.gitignore b/.gitignore index 5434925..83a2896 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ CREDENTIALS.md .aider* ffmpeg/ BuildCounter.txt + +# Steamworks runtime (steam_api64.dll, 312 KB) — extracted from the SDK zip, never committed; +# scripts/steam-sdk.sh documents which file and why. Same rule as ffmpeg/: the pin is the audit trail. +steam/ diff --git a/Distribution.md b/Distribution.md index ed4d48d..2430da5 100644 --- a/Distribution.md +++ b/Distribution.md @@ -46,9 +46,12 @@ dotnet publish ytLive.csproj -c Release -r win-x64 --self-contained true \ the DLC app ID is what the app passes to `BIsDlcInstalled`. 3. **Depot.** One depot holding the publish output; the base app and the DLC share the install directory, and the DLC package grants no files of its own — it is entitlement only. -4. **Steamworks SDK.** Drop `steam_api64.dll` (+ `steam_appid.txt` for local runs) into the publish - output; the managed side is a thin wrapper (`Steamworks.NET` or hand-written interop) behind - `IEntitlement`. +4. **Steamworks SDK.** `./scripts/steam-sdk.sh ~/Downloads/steamworks_sdk_165.zip` extracts + `steam_api64.dll` from `sdk/redistributable_bin/win64/` into `steam/` (gitignored) and stages + `steam_appid.txt` = 480 — Valve's Spacewar app, so `SteamAPI.Init()` works locally before + LlamaCasty has an App ID. The csproj copies the DLL **beside the exe** (`Link`) with + `ExcludeFromSingleFile`, and copies `steam_appid.txt` in Debug only — never into a depot. The + managed side is the `Steamworks.NET` package (`SteamApps.BIsDlcInstalled`). 5. **Store page** configured and made public **two weeks before release** — Valve's rule, and it is the window where wishlists accumulate. diff --git a/TASKS.md b/TASKS.md index 1afaa52..c582933 100644 --- a/TASKS.md +++ b/TASKS.md @@ -42,6 +42,7 @@ Dog test. | 34 | ☐ | Scheduled streams (Text-drawer version) | [`task-34`](TASKS/task-34-scheduled-streams.md) | | 35 | ☐ | Scene-linked audio | [`task-35`](TASKS/task-35-scene-linked-audio.md) | | 37 | ☐ | Defaults vs current layout split (build-id); enables one-click revert to defaults | [`task-37`](TASKS/task-37-defaults-current-split.md) | +| — | ☐ | **Preview undo (Ctrl+Z / Ctrl+Shift+Z)** — in edit mode, revert the last preview change (drag, resize, add, remove, property edit); bounded stack, cleared on scene change or layout load. The natural partner to 37: undo covers the slip, defaults cover the mess | this line | | 39·2 | ☐ | YPP slice 2: Analytics scopes, watch-hours/Shorts velocity + ETA | [`task-39`](TASKS/task-39-ypp-journey-tracker.md) | | 49 | ☐ | Chat profanity filter: local, opt-in, **non-persistent**, user-supplied word list | [`task-49`](TASKS/task-49-chat-profanity-filter.md) | | 50 | ☐ | One-button publish of the local recording (resumable upload) | [`task-50`](TASKS/task-50-publish-recording.md) | diff --git a/scripts/steam-sdk.sh b/scripts/steam-sdk.sh new file mode 100644 index 0000000..3a109a0 --- /dev/null +++ b/scripts/steam-sdk.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# steam-sdk.sh — extract the one file the app needs from the Steamworks SDK, and stage the +# local-only app id. +# +# Why not unzip the whole SDK: it is ~24 MB of C++ headers, examples and tools we never build. +# The runtime dependency is exactly one native library, and the release tooling (ContentBuilder) +# is only needed on the machine that uploads a depot. +# +# ./scripts/steam-sdk.sh ~/Downloads/steamworks_sdk_165.zip +# +# steam_api64.dll is Valve's redistributable — shipping it beside a Steam-published exe is +# permitted by the Steamworks terms. It is NOT committed: steam/ is gitignored, like ffmpeg/. + +set -euo pipefail + +ZIP="${1:-$HOME/Downloads/steamworks_sdk_165.zip}" +ROOT="$(cd "$(dirname "$0")/.." && pwd)" + +[ -f "$ZIP" ] || { echo "❌ SDK zip not found: $ZIP" >&2; echo " Download it from partner.steamgames.com/downloads/steamworks_sdk.zip while signed in." >&2; exit 1; } + +mkdir -p "$ROOT/steam" + +python3 - "$ZIP" "$ROOT" <<'PY' +import sys, zipfile, pathlib + +zip_path, root = sys.argv[1], pathlib.Path(sys.argv[2]) +want = "sdk/redistributable_bin/win64/steam_api64.dll" +dest = root / "steam" / "steam_api64.dll" + +with zipfile.ZipFile(zip_path) as z: + with z.open(want) as src, open(dest, "wb") as out: + out.write(src.read()) + +print(f"✓ {dest.relative_to(root)} ({dest.stat().st_size // 1024} KB)") +PY + +# steam_appid.txt is a LOCAL TESTING affordance: it lets SteamAPI.Init() resolve an app id +# without going through the Steam client. 480 is Valve's public Spacewar test app, so the app +# can be exercised before LlamaCasty has an app id of its own. It is Debug-only in the csproj +# and must never ship in a depot — Valve's guidance is to remove it from release builds. +printf '480\n' > "$ROOT/steam/steam_appid.txt" +echo "✓ steam/steam_appid.txt = 480 (Spacewar, local Debug testing only)" + +echo "" +echo "Next: the entitlement seam (IEntitlement + SteamApps.BIsDlcInstalled)." diff --git a/ytLive.csproj b/ytLive.csproj index e2069ad..266426b 100644 --- a/ytLive.csproj +++ b/ytLive.csproj @@ -100,6 +100,21 @@ + + + + + + + +