Files
BT411/players/play_solo.bat
T
Joe DiPrimaandClaude Fable 5 5fc969ae95 the log day now starts at 6am, because the playtesters are night owls
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>
2026-07-28 17:22:35 -05:00

124 lines
6.5 KiB
Batchfile

@echo off
rem BT411 -- single-player play. Opens the MISSION MENU: pick your mech
rem (all 18), map, experience level, colours, weather, mission length and
rem more, then launch. SOLO MISSION = timed with scoring; RAW SOLO =
rem endless practice. The menu returns after each mission.
cd /d %~dp0
rem ONE unified build (2026-07-21): the exe carries every layer; the GLASS
rem platform env arms the desktop cockpit (clickable MFD buttons, trigger
rem config, bindings.txt keymap).
set BT_PLATFORM=glass
if not exist "build\Release\btl4.exe" goto badpath
if not exist "content\OPERATOR.EGG" goto badpath
set BT_START_INSIDE=1
set BT_DEV_GAUGES=1
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\solo_YYYYMMDD.log
rem -- and always appends, so every session of the day lands in one file with a
rem "===== BT411 SESSION ... =====" header between them.
rem
rem WHY: rotation kept only TWO generations (del *.old.log, then ren *.log
rem *.old.log). On 2026-07-27 a player crashed twice, kept playing, and his own
rem relaunches deleted both crash sessions before anyone could ask for them --
rem the stacks were lost permanently. A per-day file has no rotation window to
rem fall out of. The stem still separates solo from the MULTIPLAYER log, so a
rem player who crashes in MP and then runs solo still cannot destroy their own
rem crash evidence.
set BT_FE_SOLO=1
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 LAUNCH FORENSICS (#41): bracket the exe from outside, so a launch that dies
rem before it can log anything still leaves a record. The exe APPENDS its own
rem block to lastrun_solo.txt at first breath (build, pid, local time, and WHICH
rem day-log it chose -- cmd cannot derive that name itself, %DATE% being
rem locale-ordered and full of '/'). So: delete the file here and do NOT
rem pre-write it -- its ABSENCE afterwards is what means "never reached
rem WinMain". Writing a line here first would make that test always pass.
rem This REPLACES the old "if not exist solo.log" probe, which a per-day log
rem silently breaks: that file survives earlier launches, so the probe could
rem never fire and every healthy run would be reported as blocked.
rem No find/findstr probe -- MSYS shadows both (see the note above :btwait).
if exist lastrun_solo.txt del lastrun_solo.txt
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,"
)
..\build\Release\btl4.exe
set BT_EXITCODE=%ERRORLEVEL%
if not exist lastrun_solo.txt echo THE EXE NEVER REACHED WinMain: blocked before it could run (loader failure or antivirus) > lastrun_solo.txt
echo [%DATE% %TIME%] btl4.exe exited with code %BT_EXITCODE% >> lastrun_solo.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
echo BOTH of these from the content folder:
echo content\lastrun_solo.txt (tiny -- send it EVEN IF there is
echo no solo_*.log at all: that combination
echo is how we spot a blocked launch)
echo content\solo_YYYYMMDD.log
echo (just take the NEWEST solo_*.log -- do not go by the date in the name.
echo A log day runs 6am to 6am, so anything you played after midnight is
echo still filed under the evening you started, which keeps one night in
echo one file. Each session inside starts with a "===== BT411 SESSION"
echo line naming your build and PC, so it identifies itself even if the
echo filename gets changed in transit.)
pause
exit /b
:badpath
echo.
echo ==================================================
echo ERROR: this file is not in the right place.
echo.
echo It must sit in the EXTRACTED game folder, next to
echo the 'content' and 'build' folders.
echo.
echo Fix: right-click the .zip - Extract All, open the
echo extracted folder, and run this file from THERE.
echo (Do NOT run it from inside the zip.)
echo ==================================================
echo.
pause