Files
nix-everquest/docs/eqlogparser-wine.md
T
2026-05-26 14:35:45 -07:00

282 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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