Both jobs failed, at genuinely informative points:
- linux-x64: DllNotFoundException loading lingua_physics — the .so
committed for scripts/run-sample.sh's local-dev convenience was built on
this dev machine's own (newer) glibc, and didn't load on ubuntu-latest's
runner. liblingua_audio.so, built the same way, loaded fine there — this
wasn't a generic "the file isn't where expected" problem, it was
specific to what that one binary happened to require. Fixed by having CI
rebuild and overwrite the native libs fresh for both platforms, every
run, rather than trusting the committed one for anything but casual
local use — only a binary built on the actual target platform is
trustworthy on it.
- win-x64: "WGL: The driver does not appear to support OpenGL" — from
inside the --headless verification run. --headless only controls
whether Engine.Host's own loop pumps a window; it does nothing to stop
a *loaded* engine.windowing/engine.render from creating a real window
and GL context regardless, which the full PhysicsDemo project always
does. Fine on a real desktop, fatal on windows-latest's GPU-less
runner. Fixed with a separate, minimal verification stage — engine.
physics only, project.ci-headless.json/scene.ci-headless.json, no
windowing/render/audio/game plugin at all — alongside the original full
stage, which still produces the real uploaded artifact. engine.physics
needs no display, so this is what CI can actually check without one;
audio's own correctness is separately covered by Engine.Audio.Tests
(forced onto miniaudio's null backend already) on both platforms.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N1qPfzq8TDCUMFMV3UwV5N
The literal thing nothing on this dev machine can verify: whether the
build actually runs on Windows at all. Solved by having real CI do it —
ubuntu-latest and windows-latest both build the native Box3D/miniaudio
shims from source via CMake, build and test the full .NET solution, stage
a shippable configuration (engine.windowing/assets/render/input/physics/
audio + physics-demo-game — engine.editor deliberately excluded, that's
M4's actual "done when"), and then run it headless against samples/
PhysicsDemo for 200 frames, asserting DemoBox settled at y≈1.0 in the
resulting dump. Real physics, real scene load, real plugin loading,
proven on both platforms, not just built.
Required restructuring the native Content items into per-OS ItemGroups
(native/linux-x64/ vs native/win-x64/, selected via
$([MSBuild]::IsOSPlatform(...))): linux-x64's .so is committed (built and
verified here); win-x64's .dll is never committed — nothing here can
build or run one to verify — and only ever exists as something the
Windows job produces fresh, in-place, right before `dotnet build`.
Caught one real bug dry-running this exact staging locally before
trusting it to a workflow run: PluginHost.Load calls Assembly.
LoadFromAssemblyPath, which throws on a relative path — the verification
step's `--plugins ../../plugins` failed immediately with "is not an
absolute path." Every manual verification earlier this session happened
to always pass an absolute --plugins path, which is exactly why this
never surfaced before. Fixed by resolving to an absolute path before
invoking Engine.Host.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N1qPfzq8TDCUMFMV3UwV5N