BT_STEAM restored as THE compile gate (license) -- default OFF

The unification flattened BT_STEAM into the always-on exe; the user flagged
the constraint that makes it the one legitimate compile gate: the Steamworks
SDK license bars a public release with Steam inside, so a release build must
exclude it entirely.

- CMakeLists: option(BT_STEAM OFF) restored around the Steamworks block --
  an OFF configure touches no SDK headers, no steam_api.lib, no DLL copy.
  BT_GLASS stays retired (always defined); ONE build dir either way.
  Dev checkout: build/ configured once with -DBT_STEAM=ON.
- mkdist: reads BT_STEAM from build/CMakeCache.txt.  Steam-OFF zips exclude
  play_steam.bat + steam_api.dll (explicitly filtering a STALE DLL left by
  an earlier ON build), strip the README steam section ({STEAM} line
  markers), and take a -nosteam name suffix so the flavors never clobber
  (found live: both stamped 4.11.436 and the release zip overwrote the dev
  zip).

Verified both flavors:
  ON  (dev build):  steam smoke degrades to Winsock without the client;
      zip carries play_steam.bat + steam_api.dll + README steam lines.
  OFF (scratch build-relcheck, deleted after): 0 compile errors; exe dir =
      btl4.exe + OpenAL32.dll only; boots + simulates; BT_STEAM_NET=1 inert
      (transport not in the binary); end-to-end zip has zero steam bits and
      a clean README.

KB: context/glass-cockpit.md unified-build section records the license gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-21 10:40:03 -05:00
co-authored by Claude Opus 4.8
parent dd74d13120
commit d53fcf61ad
4 changed files with 85 additions and 38 deletions
+41 -26
View File
@@ -13,18 +13,29 @@ set(DXSDK "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)" CACHE PATH
#===========================================================================#
# ONE BUILD (unified 2026-07-21; was pod / glass / steam compile splits).
# Everything compiles into the single exe; behavior is selected at RUNTIME
# by env gates only -- BT_PLATFORM=glass arms the desktop-cockpit profile
# (PadRIO clicks, bindings.txt keymap, plasma window, miniconsole menu),
# BT_STEAM_NET=1 arms the Steam transport (steam_api.dll is DELAY-LOADED,
# so machines without the DLL run fine while the gate stays off). A bare
# boot (no env, no args) behaves like the old pod build: DEV profile, no
# menu, waits for the console egg -- the cabinet default is unchanged.
# The BT_GLASS/BT_STEAM macros remain (always defined) as seam markers.
# by env gates -- BT_PLATFORM=glass arms the desktop-cockpit profile
# (PadRIO clicks, bindings.txt keymap, plasma window, miniconsole menu).
# A bare boot (no env, no args) behaves like the old pod build: DEV
# profile, no menu, waits for the console egg -- the cabinet default is
# unchanged. The BT_GLASS macro remains (always defined) as a seam marker.
#
# THE ONE COMPILE GATE: BT_STEAM (default OFF). The Steamworks SDK's
# license means a RELEASE build must exclude Steam entirely (no SDK
# headers, no steam_api.lib, no DLL). When ON: the transport compiles in,
# steam_api.dll is DELAY-LOADED, and BT_STEAM_NET=1 arms it at runtime --
# machines without the DLL still run everything else.
# Dev checkout: configure build/ once with -DBT_STEAM=ON.
#===========================================================================#
option(BT_STEAM "Steam transport + lobby (Steamworks SDK -- EXCLUDE from public releases)" OFF)
message(STATUS "bt411: BT_STEAM=${BT_STEAM}")
set(BT_DEFS WIN32 _WINDOWS UNICODE _UNICODE NOMINMAX
_CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS
_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
BT_GLASS BT_STEAM)
BT_GLASS)
if(BT_STEAM)
list(APPEND BT_DEFS BT_STEAM)
endif()
set(BT_OPTS /permissive /W0 /wd4996 /EHsc /bigobj /MP)
#===========================================================================#
@@ -368,24 +379,28 @@ target_link_libraries(btl4 PRIVATE
# UNRESOLVED tolerates the dead offline-tool factory in mech3.cpp. See docs.
target_link_options(btl4 PRIVATE /FORCE)
# Steam transport: compiled in, DELAY-LOADED. steam_api.dll is only mapped
# when the first SteamAPI call runs, and every call site gates on
# BT_STEAM_NET=1 (btl4main step-4b bring-up; L4NET's BTSteamNet_* short-
# circuit on steamActive) -- so a machine without the DLL runs everything
# except Steam sessions.
set(STEAMWORKS "${CMAKE_SOURCE_DIR}/extern/steamworks_sdk_164")
target_sources(munga_engine PRIVATE "engine/MUNGA_L4/L4STEAMNET.cpp")
target_sources(btl4 PRIVATE "game/glass/btl4lobby.cpp")
target_include_directories(munga_engine PRIVATE "${STEAMWORKS}/public")
target_include_directories(btl4 PRIVATE "${STEAMWORKS}/public")
target_link_libraries(btl4 PRIVATE
"${STEAMWORKS}/redistributable_bin/steam_api.lib"
delayimp)
target_link_options(btl4 PRIVATE "/DELAYLOAD:steam_api.dll")
add_custom_command(TARGET btl4 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${STEAMWORKS}/redistributable_bin/steam_api.dll"
"$<TARGET_FILE_DIR:btl4>")
# Steam transport (BT_STEAM=ON only -- the license gate): DELAY-LOADED.
# steam_api.dll is only mapped when the first SteamAPI call runs, and every
# call site gates on BT_STEAM_NET=1 (btl4main step-4b bring-up; L4NET's
# BTSteamNet_* short-circuit on steamActive) -- so even the steam-enabled
# exe runs without the DLL as long as the env gate stays off. A BT_STEAM=OFF
# configure touches NO Steamworks bits: no SDK headers, no lib, no DLL copy
# (and mkdist then leaves play_steam.bat + steam_api.dll out of the zip).
if(BT_STEAM)
set(STEAMWORKS "${CMAKE_SOURCE_DIR}/extern/steamworks_sdk_164")
target_sources(munga_engine PRIVATE "engine/MUNGA_L4/L4STEAMNET.cpp")
target_sources(btl4 PRIVATE "game/glass/btl4lobby.cpp")
target_include_directories(munga_engine PRIVATE "${STEAMWORKS}/public")
target_include_directories(btl4 PRIVATE "${STEAMWORKS}/public")
target_link_libraries(btl4 PRIVATE
"${STEAMWORKS}/redistributable_bin/steam_api.lib"
delayimp)
target_link_options(btl4 PRIVATE "/DELAYLOAD:steam_api.dll")
add_custom_command(TARGET btl4 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${STEAMWORKS}/redistributable_bin/steam_api.dll"
"$<TARGET_FILE_DIR:btl4>")
endif()
# Copy the OpenAL runtime DLL next to the built exe. (libsndfile is gone: its
# repo DLL was a no-op STUB -- L4AUDRES now loads the soundbank WAVs with an
+11 -3
View File
@@ -27,9 +27,17 @@ version skew (a stale steam exe shipped 2 days behind), tripled build time, and
| `BT_STEAM_NET=1` | the Steam transport (FakeIP/SDR; degrades to Winsock without the Steam client). `steam_api.dll` is **DELAY-LOADED** (`/DELAYLOAD` + delayimp) — machines without the DLL run everything else |
| (nothing) | the old pod-build behavior byte-for-byte: DEV profile, no menu, waits for the console egg — **the cabinet default is unchanged** |
- The `BT_GLASS`/`BT_STEAM` macros are now ALWAYS defined (seam markers only — the `#ifdef`
sites remain as documentation of the layer boundaries). Every gated code path was audited:
all are instance-guarded (`PadRIO::activeInstance`, `steamActive`) or env-gated at runtime.
- The `BT_GLASS` macro is now ALWAYS defined (a seam marker only — the `#ifdef` sites remain
as documentation of the layer boundary). Every gated code path was audited: all are
instance-guarded (`PadRIO::activeInstance`, `steamActive`) or env-gated at runtime.
- **`BT_STEAM` stays a COMPILE gate (the LICENSE gate, default OFF, restored 2026-07-21):**
the Steamworks SDK terms bar a public release with Steam inside, so a release configure
must be able to exclude it entirely — no SDK headers, no `steam_api.lib`, no DLL. The dev
checkout configures `build/` once with `-DBT_STEAM=ON`. `mkdist.py` reads the answer from
`build/CMakeCache.txt`: steam-OFF zips carry no `play_steam.bat`, no `steam_api.dll`
(including a STALE one from an earlier ON build), a README with the steam section stripped,
and a `-nosteam` name suffix so the two flavors never clobber. Verified both flavors:
OFF exe has no steam bits + `BT_STEAM_NET=1` is inert; ON exe degrades to Winsock.
- **Menu guard (cabinet protection):** the miniconsole previously claimed any zero-arg launch;
unified, it requires `BT_PLATFORM=glass` (or `BT_FE_MENU=1`) — a bare cabinet boot can never
land in the menu (btl4main.cpp, platform parse moved above the fe_menu_mode computation).
+2 -2
View File
@@ -9,8 +9,8 @@ TO JOIN AN INTERNET GAME: double-click join.bat
(waits for the operator's session if it's not up yet)
TO JOIN A LAN GAME: double-click join_lan.bat (operator's LAN)
SINGLE-PLAYER PRACTICE: double-click play_solo.bat (no network)
STEAM INTERNET PLAY: double-click play_steam.bat (EXPERIMENTAL --
needs the Steam client running; host or join from the menu)
{STEAM}STEAM INTERNET PLAY: double-click play_steam.bat (EXPERIMENTAL --
{STEAM} needs the Steam client running; host or join from the menu)
Your seat and mech are assigned automatically by the operator.
If the game closes unexpectedly, send the operator content\join.log.
+31 -7
View File
@@ -43,17 +43,31 @@ def main():
githash = subprocess.check_output(
["git", "rev-parse", "--short", "HEAD"]).decode().strip()
name = "BT411-%s-%s" % (time.strftime("%Y-%m-%d"), githash)
zpath = os.path.join(outdir, name + ".zip")
tracked = subprocess.check_output(
["git", "ls-files", "-z", "content/"]).decode().split("\0")
tracked = [t for t in tracked if t]
# ONE unified build (2026-07-21): every layer (pod game + glass cockpit +
# Steam transport) lives in the single exe; steam_api.dll is delay-loaded.
# ONE unified build (2026-07-21): every layer lives in the single exe.
# THE LICENSE GATE: BT_STEAM is compile-time (Steamworks SDK terms bar a
# public release with Steam inside). Read the configure's answer from
# the CMake cache; a steam-OFF zip must carry neither play_steam.bat nor
# steam_api.dll (a stale DLL can linger from an earlier ON build).
steam_on = False
try:
cache = open("build/CMakeCache.txt", encoding="utf-8", errors="ignore").read()
steam_on = "BT_STEAM:BOOL=ON" in cache
except OSError:
pass
print(" BT_STEAM=%s (from build/CMakeCache.txt)" % ("ON" if steam_on else "OFF"))
if not steam_on:
name += "-nosteam" # distinct name: never clobbers the dev-flavor zip
zpath = os.path.join(outdir, name + ".zip")
exes = ["build/Release/btl4.exe"]
bats = ["players/play_solo.bat", "players/join.bat", "players/join_lan.bat",
"players/play_steam.bat"]
bats = ["players/play_solo.bat", "players/join.bat", "players/join_lan.bat"]
if steam_on:
bats.append("players/play_steam.bat")
for p in exes + bats:
if not os.path.exists(p):
sys.exit("MISSING: %s -- build/refresh it first" % p)
@@ -63,8 +77,12 @@ def main():
for exe in list(exes):
d = os.path.dirname(exe)
for f in sorted(os.listdir(d)):
if f.lower().endswith(".dll"):
exes.append(d + "/" + f)
if not f.lower().endswith(".dll"):
continue
if f.lower() == "steam_api.dll" and not steam_on:
print(" (steam OFF: leaving stale %s out of the zip)" % f)
continue
exes.append(d + "/" + f)
# System runtime DLLs the exe needs on a bare tester machine (32-bit
# d3dx9 + MSVC runtimes -- carried in redist/, shipped next to the exe;
@@ -79,6 +97,12 @@ def main():
if os.path.exists("players/README.txt"):
readme = open("players/README.txt", encoding="utf-8").read()
readme = readme.replace("{VERSION}", name.replace("BT411_", ""))
lines = readme.splitlines(True)
if steam_on: # keep steam lines, drop marker
lines = [l.replace("{STEAM}", "") for l in lines]
else: # steam-free zip: strip them
lines = [l for l in lines if "{STEAM}" not in l]
readme = "".join(lines)
z.writestr(name + "/README.txt", readme)
for p in bats: # bats at the zip ROOT (next to
arc = os.path.basename(p) # content\ + build\, per the guard)