12 Commits
Author SHA1 Message Date
b62d6e386c [P2-08] Sample game "Marble Run" with autoplay test (#211)
* parity: 86 marble-run sample course with sphere and goal

* parity: 86 add --autoplay inputs.json replay to player binary

* parity: 86 player-driven marble autoplay (Boot + test/autoplay.json + engine_marble_autoplay)

MarbleRun gains Game.Bootstrap.Boot(table, world, renderer): builds the
course into the player's live world and registers FixedUpdate drive +
Update-phase FrameHost (drive blend + respawn + sensor-kEnter drain).
The player prefers Boot over legacy void Main and keeps the host alive
for the run. test/autoplay.json (1500 empty-key frames) exercises the
event-fed input path while the scripted drive finishes in 3.6 s.
engine_marble_autoplay now drives engine-player --autoplay and greps
Finished in.

* parity: 86 offscreen GPU verification notes (build+ctest logs, banned-pattern + ABI checks)

* parity: 86 PR consolidation notes (gate, ABI race, fresh verification)

* parity: 86 resolve Sonar autoplay findings (S6232/S3776/S134/S6197/S6004, Boot/Release helpers)

* parity: 86 notes for Sonar fix push 2306c54

* parity: 86 notes CodeRabbit re-trigger rate-limited

* parity: P2-08 CodeRabbit round 2 (5 fixed, 2 skipped with reason)

---------

Co-authored-by: hermes-agent <hermes-agent@local>
Co-authored-by: Hermes <hermes@local>
2026-11-04 12:39:10 -05:00
BillyOutlast a560fbca34 Merge pull request #193 from Heretek-AI/parity/p4-03-cascaded-shadow-maps-2
[P4-03] Cascaded shadow maps (4 cascades, PCF 3x3, texel snapping)
2026-11-02 14:26:03 -05:00
Claude 59ec67fe5d P2-03: run FixedUpdate systems per fixed step from one native clock
The generator mapped Phase.FixedUpdate to Update and nothing dispatched
by phase, so FixedUpdate systems never ran in the fixed step. There were
also two clocks: the renderer advanced a native Timestep nobody read,
while Time.cs kept its own copy of the math.

- ABI 4.12 frame-clock tail: system_set_phase, world_frame,
  time_set_scale, time_get_f64, time_get_u64.
- The world owns the only clock; world_frame advances it and runs
  generic systems by phase (FixedUpdate once per fixed step, dt 1/50 s).
- Time.cs reads the native clock; the renderer no longer advances one.
- Generator emits FixedUpdate and registers each phase natively.
- Tests: native engine_world_frame; IllusionSample runs a generated
  FixedUpdate system through Time.Frame. HelloCube uses Time.Frame.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfRk1pMqciEq3aZUEZ
2026-11-02 05:10:11 +00:00
hermes-agent 8d43019143 parity: 101 wire shadow toggle into production mesh path (render_world + mesh shader + HelloCube) 2026-11-01 19:09:07 -10:00
e7e3ec28ac [P7-02] macOS presentation via MoltenVK (#182)
* parity: 130 Windows GPU lane in CI (Vulkan SDK + Lavapipe, ENGINE_REQUIRE_GPU=1)

* parity: 131 macOS MoltenVK portability enumeration + SDK CI lane

* parity: 130 Windows GPU lane in CI (Vulkan SDK + Lavapipe, ENGINE_REQUIRE_GPU=1)

* parity: 131 probe SDK layout (list ICDs, don't assume MoltenVK_ICD.json path)

* parity: 130 fix MSVC C4459 vk* shadowing (p_ prefix, volk globals now visible)

* parity: 131 source setup-env.sh in macOS probe (loader env, not raw vulkaninfo)

* parity: 130 fix MSVC C4551/C4505 (swapchain NameEquals, VMA swap wd4505)

* parity: 131 export MoltenVK ICD path to macOS test step (fresh shell needs env)

* parity: 130 real Win32 window for GPU tests (offscreen only on Linux)

* parity: 131 fix macOS env expansion in CI (VULKAN_SDK is shell env, not GH context)

* parity: 131 fix macOS CI env expansion + SDL driver override

* parity: 130 destroy stale image views in Swapchain::recreate (Win32 present path)

* parity: 130 notes for rounds 2-3 (Win32 window, recreate views fix)

* parity: 130 resync FrameContext after swapchain recreate (Win32 present path)

* parity: 131 add DYLD_FALLBACK_LIBRARY_PATH for macOS volk dlopen

* parity: 130 rebuild surface+swapchain+frames after recreate (Win32 present path)

* parity: 131 temporary macOS loader-path diagnostic probe

* parity: 131 fix macOS ICD path + Linux empty-VK_ICD regression

* parity: 130 resync FrameContext after recreate, keep surface alive (Win32 present)

* parity: 131 force bash for cross-platform Test step (Windows ran it as pwsh)

* parity: 131 restore P7-01 FrameContext resync + fix dlprobe heredoc quoting

* parity: 130 instrument post-recreate path (Win32 failure diagnosis)

* parity: 130 resize window before recreate (Win32 currentExtent)

* parity: 130 dedupe golden frame via RenderOrangeFrame helper

* parity: 130 use RenderOrangeFrame in post-recreate block too

* P7-02 review: pin SDK action by SHA, no silent instance-extension truncation, portability subset on headless devices, notes driver

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: try Vulkan SDK 1.4.328.1 on macOS (MoltenVK 1.3) and upload the swapchain capture

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: install the macOS Vulkan SDK with the jakoch action (humbletim v1.2 cannot unpack 1.4.313+)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: HelloCube skips (fails under ENGINE_REQUIRE_GPU=1) when renderer_create finds no device; print the device's required feature flags in the macOS probe

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: drawIndirectCount is optional (MoltenVK on the macOS runner lacks it); indirect test falls back to a plain zero-draw indirect call

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* CI: pass GITHUB_TOKEN to the Vulkan SDK action (anonymous API rate limit hit on Windows)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: no Cocoa event pump off the main thread (live-server test aborted on macOS); unbuffered gpu_indirect log

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: require the GPU on macOS CI; gpu_indirect records no counted draw without drawIndirectCount (MoltenVK SEGV on a draw outside a render pass)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02: on MoltenVK the live GPU-time check requires a resolved (>= 0) value; paravirtual timestamps coincide for a near-empty frame

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

* P7-02 notes: macOS outcome (SDK 1.4.328.1, optional drawIndirectCount, CI capture replaces the manual screenshot)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VjcGdfhMP7fhRLiNVGdbpw

---------

Co-authored-by: vulkan-renderer <[email protected]>
Co-authored-by: hermes-agent <hermes-agent@local>
Co-authored-by: Claude <[email protected]>
2026-11-01 18:03:42 -05:00
BillyOutlastandhermes-agent cab3de1020 parity: PARITY-78 real engine-cli snapshot capture (#166)
* parity: PARITY-77 Rendering from C# Renderer API and HelloCube

* parity: PARITY-78 real engine-cli snapshot capture

* parity: whitespace (dotnet format) + shared SDK-free VkExtent2D stub + stub render_world/device_ parity (macOS/Windows CI)

* parity: ABI 4.4 renderer tail after P2-02 input (merge main fixup)

* parity: guard ecs_render render_world with ENGINE_RENDERER_HAS_VULKAN (fix macOS/Windows duplicate symbol)

* parity: silence MSVC C4251 in mesh_registry.hpp (Windows CI)

* parity: macOS unused-function guard + Windows getenv fix (native CI)

* parity: maybe_unused on ecs_render math helpers (macOS -Werror)

* parity: register render components on SDK-free renderer_create (macOS/Windows CI)

* parity: GPU-gate HelloCube sample (skip-without-GPU, fail-closed under ENGINE_REQUIRE_GPU=1)

* parity: GPU-gate RunRealSnapshot mesh upload (skip-without-GPU, fail-closed under ENGINE_REQUIRE_GPU=1)

* parity: pin AlignOf LocalTransform/WorldTransform to 64 (P0-05 alignas(64); arm64 Vector512 reports 16)

* parity: drop duplicated shader .inc copies (include/engine/renderer/shaders is canonical)

* parity: S1751 loop-can-iterate guard in render_world camera scan

* parity: restore shader .inc copies at spec path (main keeps both; unbreaks Sonar-duplication-only revert)

---------

Co-authored-by: hermes-agent <hermes-agent@local>
2026-10-31 16:28:19 -04:00
hermes-agent 7f6ac551cc illusion: ILLU-M9 illusion sample green 2026-10-30 09:18:37 -09:00
hermes-agent 6d21614ad1 M5-04: ExportSample AOT game (ABI 4.1 live, 10k bulk, frame+boot timings) 2026-10-30 01:35:08 -09:00
hermes-agent 8e49a8fd7b [M2-04] Stateless collectible-ALC hot-reload (ScriptHostManager, dispatcher, schema migration, HotReloadBench)
- Engine.Runtime: ScriptContext (stream-loaded collectible ALC),
  ScriptSystemDispatcher (stable UCO trampolines + fault barrier),
  ComponentSchema/ComponentMigrator (prefix + per-field migration),
  ScriptHostManager (barrier Load/Reload, proven ALC unload).
- Engine.Tests: HotReloadTests (6 checks: stream load, barrier swap +
  unload proof + <100ms, schema evolution, fault isolation, barrier
  guard, zero-alloc dispatch).
- samples/HotReloadBench: 100k-entity milestone gate (barrier 13-17ms,
  row-exact 6*dt, no state loss).
- native comment-only note on ecs_query_changed dirty-flag behavior.
Closes #9.
2026-10-28 20:22:32 -09:00
BillyOutlastandhermes-agent 2eed924788 [TECH-DEBT] Per-dispatch dt via FrameDispatch (ABI 1->2) (#36)
* [TECH-DEBT] Per-dispatch dt via FrameDispatch (ABI 1->2)

- ManagedSystemCallback takes (view, dt) by value; run_systems takes
  FrameDispatch*; NULL dispatch means zero dt.
- MovementSystem drops static s_dt/SetDt; MoveUnrolled(view, dt).
- Codegen validates/emits FrameDispatch + callback shape; regen pins M.
- Layout gates (72B table, 4B dispatch), smoke, Benchmark1M updated.

* Address review batch: FrameDispatch comment, callback void check, dt tracking

- FrameDispatch comment now states pointer-in / by-value-out (was
  claiming by-value struct delivery).
- ParseManagedCallback rejects non-void return types (emitter hardcodes
  void; fail closed instead of silent mismatch).
- CountingCallback accumulates dt; layout gate asserts nonzero dt on the
  frame run and zero dt on the NULL-dispatch run.

---------

Co-authored-by: hermes-agent <hermes-agent@local>
2026-10-29 01:03:40 -04:00
BillyOutlastandhermes-agent 11ff4e15d7 [M1-05] Embed .NET 10 (hostfxr) & 1M Entity Zero-Copy Benchmark (#31)
* [M1-05] Embed .NET 10 (hostfxr) & 1M entity zero-copy benchmark

Implements DotNetHost (hostfxr_initialize_for_runtime_config +
load_assembly_and_get_function_pointer) in native/bridge, wires the
(Local, Velocity) chunk query + parallel row-shard dispatch into
engine_abi run_systems, and adds the Benchmark1M sample proving the
milestone gate: 1M LocalTransform updates from C# in <1.5ms with
0 GC bytes allocated.

Closes #5.

* [M1-05] Fix cross-platform hostfxr: Windows/macOS portability, no-nethost fallback

- dotnet_host.cpp: Windows shims (LoadLibrary/GetProcAddress/FreeLibrary,
  FindFirstFile version-dir scan, _putenv_s), macOS dylib name covered by
  the same POSIX branch; local get_hostfxr_path declaration removed —
  without the pack TryNethost is a stub and ScanFxDir
  (DOTNET_ROOT/host/fxr) resolves hostfxr at runtime.
- bridge CMake: per-OS RID (win-x64/osx-arm64/linux-x64...) pack lookup,
  guarded link (no hard fail when the pack is absent), Windows links
  nethost.lib without CMAKE_DL_LIBS.
- Fixes CI: MSVC C1083 dirent.h, macOS/Linux undefined get_hostfxr_path.

* [M1-05] Fix CI: hostfxr resolution without DOTNET_ROOT + Windows C4996/aligned_alloc

- dotnet_host: ScanFxDir walks DOTNET_ROOT, well-known prefixes
  (/usr/share/dotnet, /usr/lib/dotnet, /usr/local/share/dotnet,
  ~/.dotnet, Program Files/dotnet) and picks newest hostfxr; macOS
  .dylib name; TryNethost is fallback-only.
- Windows: EnvGet (_dupenv_s) + FileReadable (fopen_s) shims replace
  getenv/fopen (MSVC C4996-as-error); FindFirstFile version-dir scan;
  _putenv_s for the dotnet_root override.
- test_hostfxr_smoke: _aligned_malloc/posix_memalign instead of
  std::aligned_alloc (absent on MSVC).
- ci.yml: Setup .NET 10 SDK in the native job so hostfxr fixtures exist
  before CMake configure on all three OSes.

* [M1-05] Fix CI: DOTNET_ROOT export for smoke test, Windows wchar nethost + MSVC shims

- tests CMake: DOTNET_ROOT from 'dotnet --list-sdks' exported to the
  smoke test env, so ScanFxDir finds hostfxr 10 on runners without an
  ambient DOTNET_ROOT (fixes ubuntu/macOS 'hostfxr resolution FAILED').
- dotnet_host: TryNethost wchar path on Windows (C2664 fix), multi-root
  ScanFxDir (env + well-known prefixes + HOME/.dotnet), macOS .dylib,
  EnvGet/FileReadable shims (C4996 fix, no _CRT_SECURE_NO_WARNINGS).
- smoke test: portable aligned alloc (MSVC has no aligned_alloc).
- ci.yml: Setup .NET 10 SDK in the native job before CMake configure.

* [M1-05] Fix CI: runtime-root DOTNET_ROOT + adaptive smoke frames

- tests CMake: DOTNET_ROOT from 'dotnet --list-runtimes'
  (Microsoft.NETCore.App root carries host/fxr); SDK root is fallback.
  Fixes 9.x-vs-10.x hostfxr mismatch on ubuntu/macos runners where
  DOTNET_ROOT pointed at the SDK toolcache without a 10.x fxr.
- smoke test: adaptive frame budget from a pace frame (cap ~120s timed
  work, min 3 frames); fixes macOS runner killed at 118s on frame 0.

* [M1-05] Fix Windows: wcstombs_s instead of wcstombs (C4996-as-error)

* [M1-05] Address review batch: plan invalidation, bulk-init scope, hostfxr SEMVER, GC scope

- engine_abi: bulk init touches only created ids (contiguity-checked
  direct sweep + per-entity fallback); plan reset on bulk_create +
  ecs_query_changed rebuild guard; failure paths use full teardown
  (ECS, hooks, pool); lane fallback runs lane 0 + unstarted lanes only.
- dotnet_host: numeric SEMVER hostfxr selection (prerelease tiebreak),
  rc<0 failure check with ctx close, ENGINE_HAS_NETHOST-gated TryNethost.
- bridge CMake: RID per OS/arch, natural version sort, ENGINE_HAS_NETHOST.
- tests CMake: runtime-root DOTNET_ROOT (list-runtimes first).
- smoke: vector probe buffers, adaptive frame budget (300s-safe).
- Benchmark1M: process-wide GetTotalAllocatedBytes gate (worker threads).

* [M1-05] Fix segfault: EcsQueryDetectChanges flag for ecs_query_changed

ecs_query_changed() without EcsQueryDetectChanges reads uninitialized
change-detection state -> UB/segfault on CI runners (ubuntu + macos).
Local runs passed by luck (zeroed memory). Now set on the chunk query.

* [M1-05] Document single-thread lifecycle contract on dotnet_host_create

* [M1-05] Fix Windows C4996: hand-parse hostfxr SEMVER (no sscanf)

* [M1-05] Fix Windows LNK2019 (DotNetHost exports), cost-model gate, Gen2 GC drain

- dotnet_host.hpp: ENGINE_CORE_API on DotNetHost entry points so the
  Windows test binary links the DLL import lib (was LNK2019 x4).
- tests/CMakeLists: replace hard <1.5ms-everywhere gate with a
  cost-model comment; CI runners (2-4 shared CPUs) measure 2.9-4.3ms
  where local 8-core hardware runs 0.5-0.65ms best-of-11.
- Benchmark1M/Program.cs: blocking Gen2 GC + 50ms BGC drain before the
  audited window (non-blocking Collect deferred ~672B into frame 0).

* [M1-05] Portable roofline gate + serial-first warmup (fix CI physics)

- test_hostfxr_smoke: replace fixed 1.5ms wall-clock gate (a hardware
  spec: >=96GB/s sustained — met at 20% on a 256GB/s workstation,
  unmeetable on a 36GB/s shared CI VM) with a roofline-relative gate:
  serial 1M STREAM probe (same kernel, zero dispatch overhead) vs
  parallel best-of-N; HARD gate parallel <= serial*1.5 (fan-out must
  reach the machine's own bandwidth; fails serial-fallback/extra-pass
  regressions), absolute ms + GB/s + gain LOGGED for humans.
- Serial-first warmup: 4096-row world takes the serial fast path
  (shard floor -> single lane inline), exercising plan/lane/view/UCO
  before the 1M world goes parallel (macOS ARM64 first-frame hang
  guard); per-frame start logging localizes any future hang.
- Measured: local 8-core serial 2.04ms/70GB/s, parallel 0.55ms/261GB/s
  (gain 3.7x); 4-CPU-cgroup serial 2.04ms, parallel 2.1ms (gain 0.97x,
  passes with 1.46x margin).

* [M1-05] Serial-dispatch escape hatch + Apple carve-out (macOS hang)

* [M1-05] Fix MSVC C4996: _dupenv_s for serial-dispatch env read

* [M1-05] Bisect Windows hang: drop static nethost link on WIN32

* [M1-05] Fix Windows fixture build: explicit Any CPU platform (MSB4126)

* [M1-05] Fix DOTNET_ROOT: strip shared/ subpath; sanitize hostfxr errors

* [M1-05] Diagnose Windows 0x80008093: hex-dump hostfxr errors, log config

* [M1-05] Diagnose Windows 0x80008093: log host env vars

* [M1-05] Fix Windows 0x80008093: native backslash DOTNET_ROOT

* [M1-05] Windows 0x80008093: UTF-16-decode hostfxr errors + multilevel probe

* [M1-05] Extend UTF-16 hostfxr decode to full message

* [M1-05] Windows: native backslash paths for hostfxr (0x80008093)

* [M1-05] Windows diag: log init path + raw bytes past message stop

* [M1-05] Windows diag: full narrow-tail hostfxr dump

* [M1-05] Init retry-with-backoff (fresh-fixture Windows race)

* [M1-05] Windows wide-char hostfxr + smoke hook ordering + dead CMake fallback

- dotnet_host.cpp: wchar_t hostfxr entry points on Windows
  (init/load/error-writer) via MultiByteToWideChar; fixes 0x80008093.
- tests/CMakeLists.txt: --list-sdks fallback ran inside a dead elseif
  (tested a var set only in its own branch) -> else().
- test_hostfxr_smoke.cpp: small-world warmup now runs BEFORE world
  creation (world_destroy resets global task hooks); +<algorithm>;
  gate comment states the 1.5x efficiency tolerance honestly.
- MovementSystem.cs: document why SetDt stays (M1-04 ABI freeze, no
  spare channel; publish is race-free by join-before-next-publish).

---------

Co-authored-by: hermes-agent <hermes-agent@local>
2026-10-28 14:21:40 -04:00
f88f9f8ffa [M1-01] Initialize Monorepo, CMake C++20 Build, and .slnx Workspace (#22)
* [M1-01] Initialize monorepo: CMake C++20 build, .slnx workspace, vendored deps, CI

- Root CMakeLists.txt (C++20 strict, PIC) + cmake/EngineHotFlags
  (-Wall/-Werror, -mavx2 x86-64 only, -fno-exceptions/-fno-rtti hot path)
- CMakePresets.json: linux/macos/windows debug+release, ci-* (WERROR)
- native/: engine_core shared lib (version API), core/ecs hot OBJECT
  libs, renderer/physics/audio/bridge stubs with owners
- native/tests: engine_core_smoke CTest (version handshake)
- deps/: flecs v4.1.6 + enkiTS pinned, README with re-vendor recipe
- Engine.slnx + Directory.Build.props (net10.0, AllowUnsafeBlocks,
  TieredPGO, zero-warn) + Bindings/Runtime/Tests/abi_codegen stubs
- .github/workflows/ci.yml: native (CMake+CTest) + managed
  (dotnet build+run) on ubuntu/macos/windows
- Verified: configure+build+ctest green on linux-debug (Clang),
  AVX2/no-exceptions flags confirmed in compile_commands.json

* fix(ci): AbiCodegen assembly name (CA1707), Windows Ninja+MSVC presets

* fix(ci): fail-fast windows test (5min step timeout, 60s test timeout, verbose)

* fix(ci): isolate windows hang — bootstrap control test + unbuffered smoke output

* fix(ci): copy runtime DLLs next to windows test binaries

* fix(ci): only copy DLLs for linked test target

---------

Co-authored-by: hermes-agent <hermes-agent@local>
Co-authored-by: hermes <[email protected]>
2026-10-28 00:58:04 -04:00