init: EQLogParser

This commit is contained in:
Isuldor
2026-05-26 14:35:45 -07:00
commit 1968b51912
7 changed files with 635 additions and 0 deletions
+281
View File
@@ -0,0 +1,281 @@
# Wine on Nix — notes for EQLogParser
This document captures troubleshooting lessons from packaging EQLogParser on Linux with Wine and Nix. It is meant for maintainers and anyone running the app outside Bottles/Flatpak.
For day-to-day usage, see [eqlogparser.md](./eqlogparser.md). The reference implementation is [packages/eqlogparser/package.nix](../packages/eqlogparser/package.nix), which mirrors the upstream [Bottles manifest](https://github.com/kauffman12/EQLogParser/blob/master/bottles/Games/eqlogparser.yml).
---
## What EQLogParser needs under Wine
EQLogParser is a **.NET 8 WPF** Windows app. Under Wine that implies:
| Requirement | Why |
|-------------|-----|
| **64-bit Wine prefix** (`WINEARCH=win64`) | Release builds are x64 ([`bottles/Games/eqlogparser.yml`](https://github.com/kauffman12/EQLogParser/blob/master/bottles/Games/eqlogparser.yml)) |
| **wine-mono** in the prefix | Wines `mscoree` shim; without it you get the interactive *“Wine could not find a wine-mono package”* dialog |
| **.NET Desktop Runtime 8 (x64)** | WPF needs the *desktop* runtime, not plain `dotnet-runtime` or wine-mono alone |
| **GDI D3D renderer** | WPF on Wine is unstable with default GL/Vulkan paths; Bottles sets `renderer=gdi` |
| **No DXVK / VKD3D** | Bottles explicitly disables them for this app |
| **Piper TTS installer** (recommended) | Wine x64 cannot use Windows SAPI voices; use `EQLogParser-install-pipertts-*.exe` |
The app also expects **`WINELOADER`** to be set so it disables hardware acceleration (software rendering only). See upstream `EQLogParser/App.xaml.cs` — this matches [Linux known issues](https://github.com/kauffman12/EQLogParser/blob/master/website/documentation.md#known-issues-with-linux).
---
## Choosing a Wine package in nixpkgs
nixpkgs exposes several Wine variants. They are **not** interchangeable for this project.
| Package | Use for EQLogParser? | Notes |
|---------|----------------------|-------|
| `pkgs.wine64` | **No** (alone) | Often breaks during `wineboot` / `winetricks` (`syswow64\rundll32.exe` / `ntdll.dll` errors). Prefix may be half-initialized. |
| `pkgs.wineWow64Packages.stableFull` | **Yes** | WOW64 + `embedInstallers = true` bundles **wine-mono** and gecko MSIs under `share/wine/mono/`. This is what the flake uses. |
| `pkgs.wine` (default 32-bit WOW) | **No** | Wrong architecture for a win64-only bottle. |
| `pkgs.wine64Packages.full` | **Maybe** | Has `embedInstallers`, but lacks the 32-bit side WOW64 often needs for installers and `msiexec`. Prefer `wineWow64`. |
**Rule of thumb:** match Bottles — **64-bit bottle, Wine runner, no DXVK**. On Nix that is `wineWow64Packages.stableFull` with no DXVK in `PATH` or `WINEDLLOVERRIDES`.
```nix
wine = pkgs.wineWow64Packages.stableFull;
```
Verify mono is present:
```bash
ls "$(nix-build '<nixpkgs>' -A wineWow64Packages.stableFull --no-out-link)/share/wine/mono/"
# e.g. wine-mono-10.0.0-x86.msi
```
---
## wine-mono vs .NET Desktop Runtime
These solve **different** problems. Installing only one leads to confusing errors.
### wine-mono
- Ships with Wine when `embedInstallers = true` (`stableFull`, `full` variants).
- Installed **into the prefix** via MSI, e.g.
`wine msiexec /i "$WINE_PKG/share/wine/mono/wine-mono-"*.msi /qn`
- Satisfies Wines .NET Framework / `mscoree` path and stops the mono download dialog.
- **Not** a substitute for .NET 8.
### .NET 8 Desktop Runtime
- Microsoft installer, same as Bottles dependency `dotnetcoredesktop8`
([`dotnetcoredesktop8.yml`](https://github.com/bottlesdevs/dependencies/blob/main/Essentials/dotnetcoredesktop8.yml)).
- For win64 bottles, the **x64** installer is enough (Bottles also installs x86; we only install x64).
- Example (version pinned in the package):
`windowsdesktop-runtime-8.0.12-win-x64.exe /quiet`
- Winetricks verb `dotnetdesktop8` is equivalent but failed in our tests (see below).
### Install order (important)
```
1. wineboot -u
2. wine-mono MSI (/qn)
3. .NET Desktop Runtime (/quiet)
4. renderer=gdi (registry)
5. EQLogParser installer (/VERYSILENT …)
```
Installing EQLogParser or the .NET runtime **before** mono triggers the mono dialog and can leave a broken prefix.
---
## Mapping Bottles settings to Nix/Wine
| Bottles (`eqlogparser.yml` + deps) | Nix / shell equivalent |
|-----------------------------------|-------------------------|
| `Arch: win64` | `export WINEARCH=win64` |
| `Runner: Wine`, `dxvk: false`, `vkd3d: false` | `wineWow64Packages.stableFull`; do not add DXVK to the environment |
| `dotnetcoredesktop8` | `windowsdesktop-runtime-8.0.12-win-x64.exe /quiet` |
| `allfonts` | Copy Nix font packages into `drive_c/windows/Fonts`, register them, and avoid `winetricks allfonts` |
| `renderer=gdi` | `wine reg add 'HKCU\Software\Wine\Direct3D' /v renderer /t REG_SZ /d gdi /f` |
| Piper TTS installer | `EQLogParser-install-pipertts-*.exe` with Inno flags |
| (implicit) wine-mono | `msiexec` on bundled `wine-mono-*.msi` |
Inno Setup silent flags used successfully:
```text
/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
```
---
## Prefix location and mutability
### Do not use `/nix/store` as `WINEPREFIX` during setup
Wine refuses to create a configuration directory when ownership checks fail:
```text
wine: '/nix/store' is not owned by you, refusing to create a configuration directory there
```
This happens if:
- `WINEPREFIX` points at `$out` before copy, or
- `HOME` is unset and defaults under `/nix/store`.
**Build-time prefix in the Nix store:** possible in theory (build under `$NIX_BUILD_TOP`, then `cp` to `$out`), but the EQLogParser package uses **first-run setup** in `$XDG_DATA_HOME/eqlogparser/wine` instead — simpler and avoids sandbox/fontconfig/XDG issues.
### Recommended layout
| Variable | Value |
|----------|--------|
| `WINEPREFIX` | `$XDG_DATA_HOME/eqlogparser/wine` (or `~/.local/share/eqlogparser/wine`) |
| `HOME` | Users real home (or a writable temp dir during one-off setup) |
| `WINEARCH` | `win64` |
| `WINELOADER` | Path to `wine` binary (EQLogParser uses this to detect Wine) |
Reset a bad prefix:
```bash
rm -rf ~/.local/share/eqlogparser/wine
nix run .#eqlogparser
```
---
## Winetricks on Nix
`winetricks` from nixpkgs works, but several verbs failed in testing **even after** a healthy `wineboot` and mono install:
```text
warning: wine cmd.exe /c echo '%AppData%' returned empty string
```
Affected verbs included `allfonts`, `renderer=gdi`, and `dotnetdesktop8`. The prefix was usable; winetricks `%AppData%` probe was not.
**Workarounds:**
- **GDI renderer:** set the registry directly (see table above).
- **.NET Desktop Runtime:** use Microsofts `.exe` from Bottles dependency URL, not winetricks.
- **Fonts:** copy Nix font packages into `drive_c/windows/Fonts`, register them under the Windows `Fonts` registry key, and set Wine font replacements for common Windows UI fonts.
---
## Graphics: GDI, DXVK, and WPF
WPF on Wine is sensitive to the renderer:
- Bottles sets **`renderer=gdi`** via winetricks; we set the same registry value.
- **Do not enable DXVK/VKD3D** for this app (Bottles `dxvk: false`, `vkd3d: false`).
- EQLogParser forces **software rendering** when `WINELOADER` is set. Confirm in logs:
`RenderMode: SoftwareOnly` under
`…/AppData/Roaming/EQLogParser/logs`.
If you see rendering glitches, verify GDI is set:
```bash
WINEPREFIX=~/.local/share/eqlogparser/wine wine reg query 'HKCU\Software\Wine\Direct3D' /v renderer
```
---
## Common errors and fixes
### “Wine could not find a wine-mono package”
**Cause:** Prefix has no mono MSI installed, or wrong Wine package (no embedded MSI).
**Fix:**
1. Use `wineWow64Packages.stableFull`.
2. Install mono before anything else:
`wine msiexec /i "$(wine --prefix 2>/dev/null; echo $WINE_PKG)/share/wine/mono/wine-mono-"*.msi /qn`
3. Or use `nix run .#eqlogparser` and let [package.nix](../packages/eqlogparser/package.nix) run setup.
### `failed to start L"C:\\windows\\syswow64\\rundll32.exe": c0000135`
**Cause:** `pkgs.wine64` prefix without proper WOW64 support.
**Fix:** Switch to `wineWow64Packages.stableFull` and recreate the prefix.
### App installs but crashes on start / “.NET not found”
**Cause:** Desktop Runtime 8 x64 missing (only mono or only ASP.NET runtime installed).
**Fix:** Install `windowsdesktop-runtime-8.0.x-win-x64.exe` with `/quiet`.
### `wine cmd.exe` / `%AppData%` empty (winetricks)
**Cause:** Known winetricks + Wine prefix quirk on Nix; not always fatal.
**Fix:** Avoid winetricks for dotnet/gdi; use direct installers and `reg add`.
### Fontconfig / `XDG_RUNTIME_DIR` during Nix builds
**Cause:** Building a Wine prefix inside `runCommand` without a full graphics/font stack.
**Fix:** Prefer **runtime** prefix creation (current package design), or add `fontconfig` / `XDG_RUNTIME_DIR` to the builder if you revisit store-time prefixes.
---
## Debugging checklist
1. **Wine version:** `wine --version` (from the wrapped `PATH`).
2. **Prefix arch:** `grep '#arch=' "$WINEPREFIX"/*.reg` → expect `win64`.
3. **Mono installed:**
`test -d "$WINEPREFIX/drive_c/windows/mono"` or check Add/Remove in `wine uninstaller`.
4. **.NET 8 desktop:**
`ls "$WINEPREFIX/drive_c/Program Files/dotnet/shared/Microsoft.WindowsDesktop.App/8.*"`
5. **App binary:**
`test -f "$WINEPREFIX/drive_c/Program Files/EQLogParser/EQLogParser.exe"`
6. **EQLogParser log:**
`$WINEPREFIX/drive_c/users/$USER/AppData/Roaming/EQLogParser/logs`
7. **Render mode:** log line should show `SoftwareOnly` under Wine.
8. **Piper TTS:** log should mention `piper-tts` if using the piper installer.
Run with more Wine noise:
```bash
WINEDEBUG=+pid,+process wine …
```
---
## Why the package uses first-run setup
We tried baking the prefix into the Nix store at build time. Blockers included:
- Wine refusing `/nix/store` paths for initial config
- Fontconfig and `XDG_RUNTIME_DIR` in the sandbox
- Long, brittle builds that still produced prefixes winetricks could not post-process
**Current approach:** ship Wine + installers in the store; run `eqlogparser-setup-prefix` on first launch (and on version bumps). Trade-off: first start takes several minutes; later starts are fast.
---
## Manual reproduction (without Nix)
Equivalent to Bottles + [upstream manual install docs](https://github.com/kauffman12/EQLogParser/blob/master/website/documentation.md#manually-installing-without-flatpakbottles):
```bash
# Use wine-wow64 from your distro or nix shell wineWow64Packages.stableFull
export WINEARCH=win64
export WINEPREFIX="$HOME/.local/share/eqlogparser/wine"
export PATH="/path/to/wine-wow64/bin:$PATH"
wineboot -u
wine msiexec /i /path/to/wine-mono-*.msi /qn
wine windowsdesktop-runtime-8.0.12-win-x64.exe /quiet
wine reg add 'HKCU\Software\Wine\Direct3D' /v renderer /t REG_SZ /d gdi /f
wine EQLogParser-install-pipertts-2.3.54.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
export WINELOADER="$(command -v wine)"
wine "$WINEPREFIX/drive_c/Program Files/EQLogParser/EQLogParser.exe"
```
---
## References
- [EQLogParser Linux support (website)](https://github.com/kauffman12/EQLogParser/blob/master/website/documentation.md#linux-support)
- [Bottles game manifest](https://github.com/kauffman12/EQLogParser/blob/master/bottles/Games/eqlogparser.yml)
- [Bottles `dotnetcoredesktop8` dependency](https://github.com/bottlesdevs/dependencies/blob/main/Essentials/dotnetcoredesktop8.yml)
- [Wine Mono wiki](https://gitlab.winehq.org/wine/wine/-/wikis/Wine-Mono)
- [Nix usage](./eqlogparser.md)
- [packages/eqlogparser/package.nix](../packages/eqlogparser/package.nix) — maintained install script