MarcelineVQ 1ec9d8d433 Smooth Stand→Hold animation transition with 100ms blend
- Set Hold blendTime=100ms in all 5 M2 files (was 0ms, causing jarring snap)
- Play Hold 100ms before Stand ends (3900ms) for overlap blend
- Set Stand.nextAnim=1, Hold.nextAnim=1 in M2 data for engine chaining
- Revert Hold duration from 300000ms (test residue) back to 4000ms
2026-03-02 04:23:56 -08:00

WeirdUtils

All-in-one WoW 1.12.1 (build 5875) utility DLL. Injected as a 32-bit DLL into the game process via Wine/DXVK on Linux. Provides screen-space outlines, screenshots, interaction helpers, and an embedded addon with Lua API + keybindings.

Current Features

Module Description
Outline JFA-based screen-space outlines for targets, raid marks, dead players. See src/outline/README.md.
Screenshot Hooks CTgaFile::Write for screenshot capture.
Interact Nearest NPC/object interaction, bulk looting with queue processing.
Embedded Addon Virtual addon loaded from DLL memory — .toc, .lua, .xml served via file I/O hook. Registers Lua commands and keybindings without any on-disk addon folder.
Lua Protection Bypass Stubs the Lua callback address validator to allow C function registration.

Consolidation Plan

WeirdUtils replaces the standalone utility DLLs in the parent directory. All development happens here — shared code, shared hooking infrastructure, one build system. The standalone DLLs are being retired.

Standalone DLL Purpose Integration Status
../assetfix Loose file loading, permissive MPQ glob patterns, pre-indexed file hash set Not started
../transmogfix Death frame drop fix — coalesces transmog durability update packets Not started
../interact Nearest interact + bulk loot Partially integrated

Compile-Time Feature Gating

Each module is gated behind a build flag. The same codebase produces both the all-in-one DLL and individual feature DLLs — just different compile flags. Users can pick the full package or grab only the features they want.

// build.zig options (planned)
const enable_assetfix = b.option(bool, "assetfix", "Enable asset/MPQ fixes") orelse true;
const enable_transmogfix = b.option(bool, "transmogfix", "Enable transmog coalesce fix") orelse true;
const enable_interact = b.option(bool, "interact", "Enable interact helpers") orelse true;
const enable_outline = b.option(bool, "outline", "Enable outline rendering") orelse true;
# Full build — all features in one DLL
zig build

# Single-feature builds — one DLL per feature for individual distribution
zig build -Dassetfix=true -Dtransmogfix=false -Dinteract=false -Doutline=false
zig build -Dassetfix=false -Dtransmogfix=true -Dinteract=false -Doutline=false
# etc.

Release artifacts:

  • weirdutils.dll — everything
  • assetfix.dll — just asset/MPQ fixes
  • transmogfix.dll — just transmog coalesce
  • interact.dll — just interact/loot helpers
  • outline.dll — just outline rendering

All built from this repo, all sharing the same hook library and codebase.

Per-Feature Named Mutex

A user might load the full DLL alongside one of the smaller single-feature DLLs (e.g. they use weirdutils.dll for everything but also have assetfix.dll from before they switched). Each feature module claims a named mutex on load — if it's already held, that module skips hook installation. This way any combination of DLLs coexists safely with no duplicate hooks.

// Each module creates a process-specific named mutex on init
const mutex = CreateMutexA(null, 1, "Local\\WeirdUtils_AssetFix_{pid}");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
    // Another DLL already owns this feature's hooks — skip
    CloseHandle(mutex);
    return;
}
// First to load wins — install hooks

This is per-feature, not per-DLL. The full DLL claims one mutex per enabled feature. A single-feature DLL claims one mutex. Whichever loads first owns the hooks; the duplicate gracefully becomes a no-op.

Planned: Ground-Projected Markers

World-space markers projected onto terrain, similar to raid markers but driven programmatically. Use cases:

  • Visual range indicators (spell range circles, aggro radius)
  • Waypoint markers for navigation
  • Area-of-effect visualization
  • Custom raid positioning markers

Implementation will require:

  • Projecting screen-space or world-space coordinates onto the terrain mesh
  • Rendering textured quads or circles that conform to terrain height
  • Integration with the D3D9 hook pipeline (rendered during EndScene or as additional geometry injected into the scene)

Distribution

This repo is private (source not published to avoid empowering bad actors). Distribution uses a separate public release repo that contains only a user-facing README and binary releases — no source code.

  • This repo (private): all source, development, docs
  • Public repo (e.g. WeirdUtils): README with feature descriptions + GitHub Releases with DLL downloads

Release workflow:

# Build all variants from this repo
zig build                                              # weirdutils.dll (full)
zig build -Doutline=true -Deverything-else=false       # outline.dll
# ... etc for each single-feature build

# Publish to the public repo
gh release create v1.0 --repo YourName/WeirdUtils \
  --title "v1.0" --notes "Release notes" \
  ./zig-out/lib/weirdutils.dll \
  ./builds/outline.dll \
  ./builds/assetfix.dll

Project Structure

weirdutils/
  build.zig              Build configuration
  src/
    main.zig             DLL entry, Lua API, file I/O hook, embedded addon
    screenshot.zig       Screenshot capture hook
    interact.zig         Interact + loot helpers
    png.zig              PNG encoding for screenshots
    outline/             Outline subsystem (see src/outline/README.md)
      api.zig            Public API, Lua command handler
      d3d9_hook.zig      D3D9 vtable hooks, JFA pipeline, shaders
      model_hook.zig     M2 batch reordering, rendering_outline flag
      tracker.zig        Per-frame object/model tracking
      types.zig          D3D9 constants, outline colors, categories
      offsets.zig        WoW memory addresses and struct offsets
      wow.zig            Game memory access wrappers
    addon/               Embedded addon files (.toc, .lua, .xml)
  libs/
    hook/                Shared x86 inline hooking library (trampoline, fastcall thunks)
  docs/                  Design docs, research notes, shader analysis
  reference/             C reference implementations

Build

cd /media/storage/projects/zig/weirdutils
zig build

Target: x86-windows-msvc (32-bit DLL), Zig 0.15. Host: Linux (Arch), game runs via Wine/DXVK.

Hook Installation Order

Hooks are installed in a specific sequence to handle dependencies:

  1. DLL_PROCESS_ATTACH — Lua protection bypass, file I/O hook, LoadScriptFunctions, LoadAddonsRecursively, interact hooks, GameEngine_MainInitialize, CGGameUI_Shutdown
  2. GameEngine_MainInitialize (one-shot) — screenshot hook, outline model hooks
  3. First model hook callback (deferred) — D3D9 vtable hooks (EndScene, DIP, Reset)

D3D9 hooks are deferred because creating a dummy device during engine init corrupts the d3d9 proxy's state.

S
Description
No description provided
Readme Unlicense 14 MiB
2026-08-02 01:12:59 +00:00
Languages
Lua 61.7%
Zig 26.6%
C 8.6%
Macaulay2 2.8%
Python 0.3%