A midnight boundary splits one evening across two files at exactly the moment the session is most worth reading whole: the 01:30 crash lands in a different file from the 23:00 run that set it up. And a 02:00 session is "last night" to everyone who was in it, so filing it under the new calendar date reads wrong even when nothing goes bad. So shift the clock back 6h before taking the date for the FILENAME. The log day runs 06:00 -> 06:00 and one night stays in one file. Only the filename moves. The session header and the lastrun breadcrumb each call GetLocalTime separately (three distinct SYSTEMTIMEs in this function), so every timestamp a human reads is still true local time -- checked the scoping rather than assuming it, since sharing one variable would have silently backdated the header by six hours. FileTimeToSystemTime carries the month and year boundaries, verified against a scratch harness rather than reasoned about: 2026-07-28 20:00 -> solo_20260728.log one playtest night, 2026-07-28 23:59 -> solo_20260728.log start to finish, 2026-07-29 00:01 -> solo_20260728.log in a single file 2026-07-29 05:59 -> solo_20260728.log 2026-07-29 06:00 -> solo_20260729.log the boundary 2026-08-01 01:00 -> solo_20260731.log month 2027-01-01 03:00 -> solo_20261231.log year 2026-03-01 02:00 -> solo_20260228.log non-leap February Nothing in the tooling parses these filenames -- the operator app's own log is operator_relay.log and _collect_egg is mission settings, not logs -- so the console auto-transfer is unaffected. The player-facing text did need fixing though: the bats and README told players to send the log "dated today", which is now wrong for anyone who plays past midnight. They now say to take the NEWEST one and ignore the date, with a note on why. That was already the safer instruction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
112 lines
5.8 KiB
Batchfile
112 lines
5.8 KiB
Batchfile
@echo off
|
|
rem BT411 -- STEAM play (EXPERIMENTAL, dev testers). Launches the glass
|
|
rem front-end menu: HOST a Steam lobby or JOIN one from the menu -- there
|
|
rem is no address to configure; sessions form through the Steam lobby.
|
|
rem Requires: the Steam client RUNNING and logged in, and the steam build
|
|
rem extracted next to content\.
|
|
cd /d %~dp0
|
|
if not exist "build\Release\btl4.exe" goto badpath
|
|
if not exist "content\BTL4.RES" goto badpath
|
|
set BT_PLATFORM=glass
|
|
set BT_STEAM_NET=1
|
|
rem Cockpit view + MFD gauges -- the same client flags the join bats set
|
|
rem (field report: players booted 3rd-person without them). Inherited by
|
|
rem the menu's mission relaunch.
|
|
set BT_START_INSIDE=1
|
|
set BT_DEV_GAUGES=1
|
|
rem full menu here (all modes + steam buttons); clear the solo trim in
|
|
rem case this shell ran play_solo.bat first
|
|
set BT_FE_SOLO=
|
|
rem LOGGING (2026-07-28): the bat no longer names or rotates the log. With
|
|
rem BT_LOG unset the exe names a PER-DAY file itself -- content\steam_YYYYMMDD.log
|
|
rem -- and always appends, so every session of the day lands in ONE file, each
|
|
rem starting with a "===== BT411 SESSION ... =====" header naming the build,
|
|
rem machine and pid (so it identifies itself even if the filename is changed
|
|
rem in transit). Rotation used to keep only TWO generations: on 2026-07-27 a
|
|
rem player crashed twice, kept playing, and his own relaunches deleted both
|
|
rem crash sessions before anyone could ask for them.
|
|
rem Clear any INHERITED BT_LOG: with it set the exe uses that path verbatim
|
|
rem and, with no BT_LOG_APPEND, TRUNCATES it -- the exact evidence loss this
|
|
rem change removes. Empty forces the per-day self-named file + append.
|
|
set BT_LOG=
|
|
cd content
|
|
rem ------------------------------------------------------------------
|
|
rem OUR GENERATION ONLY (2026-07-27). The wait loop below used to hold
|
|
rem this window open for ANY btl4.exe on the machine -- a second client,
|
|
rem the operator's own pod, or an orphan left by a crash. The window
|
|
rem then never printed the sign-off and looked hung: the reported "it
|
|
rem leaves the terminal open". Snapshot the PIDs alive BEFORE we launch;
|
|
rem those belong to somebody else and must not hold us here.
|
|
rem ------------------------------------------------------------------
|
|
setlocal EnableDelayedExpansion
|
|
set "BT_PRE=,"
|
|
for /f "tokens=1,2" %%P in ('%SystemRoot%\System32\tasklist.exe /FI "IMAGENAME eq btl4.exe" /NH 2^>nul') do (
|
|
if /I "%%P"=="btl4.exe" set "BT_PRE=!BT_PRE!%%Q,"
|
|
)
|
|
rem LAUNCH RECORD (#41 forensics -- NEW on the Steam path, 2026-07-28). This
|
|
rem bat never had the outside bracket the join/solo bats carry, which is why a
|
|
rem Steam player whose exe was killed before WinMain left no evidence at all.
|
|
rem The exe appends its own block to lastrun_steam.txt at first breath; delete it here
|
|
rem so its ABSENCE afterwards means the exe never started.
|
|
if exist lastrun_steam.txt del lastrun_steam.txt
|
|
..\build\Release\btl4.exe
|
|
set BT_EXITCODE=%ERRORLEVEL%
|
|
if not exist lastrun_steam.txt echo THE EXE NEVER REACHED WinMain: blocked before it could run (loader failure or antivirus) > lastrun_steam.txt
|
|
echo [%DATE% %TIME%] btl4.exe exited with code %BT_EXITCODE% >> lastrun_steam.txt
|
|
|
|
rem ------------------------------------------------------------------
|
|
rem HANDOFF WAIT (2026-07-25). The front end does NOT stay resident: it
|
|
rem CreateProcess()es the mission generation and ExitProcess(0)s itself
|
|
rem (btl4console.cpp). So OUR child exiting means "the menu handed off",
|
|
rem NOT "the game closed" -- without this wait the window announced "The
|
|
rem game has exited" while the game was still loading, which reads as a
|
|
rem crash to a playtester. Wait for the handed-off generation(s) to go.
|
|
rem
|
|
rem NO EXTERNAL TOOLS: `find`, `findstr` and `timeout` are all shadowed by
|
|
rem Git-Bash / MSYS / GnuWin32 builds of the same names when those are on
|
|
rem PATH (a dev box, or a player who installed git). The MSYS `find` is
|
|
rem the Unix one and dies with "find: '/I': No such file or directory",
|
|
rem and GNU `timeout` takes different arguments. So: parse tasklist with
|
|
rem a pure-cmd for/f, and call both helpers by ABSOLUTE System32 path.
|
|
rem A genuinely dead exe leaves no process and falls straight through, so
|
|
rem the #41 launch forensics above still work. If tasklist is missing
|
|
rem entirely the loop degrades to reporting immediately -- the old
|
|
rem behaviour, never a hang.
|
|
rem ------------------------------------------------------------------
|
|
:btwait
|
|
set "BT_STILL_RUNNING="
|
|
for /f "tokens=1,2" %%P in ('%SystemRoot%\System32\tasklist.exe /FI "IMAGENAME eq btl4.exe" /NH 2^>nul') do (
|
|
if /I "%%P"=="btl4.exe" (
|
|
rem a PID that was NOT in the pre-launch snapshot is ours
|
|
set "BT_STRIP=!BT_PRE:,%%Q,=!"
|
|
if "!BT_STRIP!"=="!BT_PRE!" set "BT_STILL_RUNNING=1"
|
|
)
|
|
)
|
|
if defined BT_STILL_RUNNING (
|
|
%SystemRoot%\System32\timeout.exe /t 2 /nobreak >nul 2>nul
|
|
goto btwait
|
|
)
|
|
echo.
|
|
echo The game has exited. If it closed unexpectedly, send the operator BOTH
|
|
echo content\lastrun_steam.txt (tiny -- send it EVEN IF there is no
|
|
echo steam_*.log at all: that is how we spot
|
|
echo a launch blocked before it ran)
|
|
echo content\steam_YYYYMMDD.log (just the NEWEST one -- ignore the date.
|
|
echo A log day runs 6am to 6am, so a session
|
|
echo after midnight stays filed under the
|
|
echo evening you started.)
|
|
echo Steam not running = the menu still works but lobbies will not appear.
|
|
pause
|
|
exit /b
|
|
:badpath
|
|
echo.
|
|
echo ==================================================
|
|
echo ERROR: this file is not in the right place, or
|
|
echo the zip was not fully extracted.
|
|
echo.
|
|
echo It must sit in the EXTRACTED game folder, next to
|
|
echo the 'content' and 'build' folders.
|
|
echo ==================================================
|
|
echo.
|
|
pause
|