Patch Notes — v3.0.2 🔧 Startup reliability
Short one. v3.0.1 shipped the first-run installer, but a handful of users on fresh machines hit llama.dll: DllNotFoundException on the very first launch — the bootstrapper downloaded CUDA correctly, we just tried to use it one step too early. This release fixes that (and a couple of other load-time gotchas). Full diff: v3.0.1...v3.0.2.
Important
If v3.0.1 crashed for you with a DllNotFoundException pointing at llama.dll or cudart64_12.dll, drop v3.0.2 next to the existing Resources/ folder and launch. No reinstall needed.
🐛 Fix: fresh-install DLL load order (#26)
Program.Main was pre-loading runtimes/win-x64/native/cuda12/llama.dll before running the bootstrapper and registering the CUDA redistributables. Users without a machine-wide CUDA install hit a DllNotFoundException at startup because llama.dll's transitive deps (ggml-cuda.dll → cudart64_12.dll, cublas64_12.dll) couldn't resolve: the bootstrapped DLLs existed on disk under Resources/cuda/, they just weren't mapped into the process yet.
Fixed by reordering startup:
- Bootstrap runs first (downloads / verifies CUDA redistributables).
PreloadCudaRuntimepinscudart/cublas/cufft/cudnninto the loader.- Then
PreloadLlamaBackendand ONNX Runtime GPU init run — their imports now resolve against the bootstrapped copies.
While we were in there, Program.cs got split for SRP: NativeLibraryLoader owns every CUDA / LLama preload P/Invoke, LoggingConfiguration owns Serilog + global handlers + the LLama log bridge, and Program stays at high-level orchestration only (~120 lines, down from 285).
🎨 Shader robustness (#27)
Every HLSL / GLSL shader now lives on disk under Resources/Shaders/ and flows through a new ShaderRegistry with:
- ASCII validation. Rejects non-ASCII characters (em-dashes, smart quotes, degree signs) with a precise error naming the offending character, line, and column. A recurring source of cryptic "unexpected end of file" failures on users' machines that didn't reproduce locally — IDE autoformat would silently substitute an em-dash and HLSL's code-page-dependent marshalling did the rest.
#includepreprocessor with relative-path resolution and cycle detection.- First-call cache. Shaders are read, validated, preprocessed, and cached once.
ImGui, RouletteWheel, TextRenderer, and every overlay D3D11 pipeline (Arrow, Button, Outline, Icon, Quad) now load through the registry instead of duplicating const string blobs in their .cs files.
🛠️ Dev escape hatch: skip bootstrapper (#28)
Running from Visual Studio / Rider / dotnet run no longer triggers the first-run installer against a populated checkout.
- New
--skip-bootstrapCLI flag. - New
PERSONAENGINE_SKIP_BOOTSTRAPenv var (1/true/yesenable it). Properties/launchSettings.jsonsets the env var automatically for IDE /dotnet runlaunches, with a second "(with bootstrap)" profile if you want to exercise the installer.
End users are unaffected — the published executable still runs the bootstrapper normally.
🔧 Under the hood
- Release pipeline hardening.
build-release.ps1now verifies every shipped shader (GLSL + HLSL) is present before zipping, on top of the fonts + prompts check added in v3.0.1 — catches the "csproj Content glob matched nothing" regression from either side of a directory layout change. ConfigWriter.Flush()— new public sync-drain API. Useful for host shutdown paths that need the on-disk file up-to-date before exit, and it makes the debounce test suite deterministic instead of racing the Timer callback against ThreadPool starvation on CI.- Config template refresh. Default model + current-context fields bumped in
appsettings.template.json. - README. Embedded 3-minute install walkthrough video.