openDecal/CLAUDE.md
erik 84e3cb5a77 Update docs with Phase 6 progress
CLAUDE.md: Update status to Phase 6 in progress, add new pitfalls
and key files discovered during verification.

PLAN.md: Mark Steps 1, 2, and 2b complete with results (50/50 CLSIDs,
13/13 DAT tests). Add DecalDat functional test as Step 2b.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 00:15:06 +01:00

3.8 KiB

OpenDecal - Project Context

What This Is

Open-source rebuild of Decal, the plugin framework for Asheron's Call. The original v2.9.8.3 is closed-source. This project produces a fully open-source drop-in replacement with identical COM interfaces and GUIDs for plugin compatibility.

Current Status: Phase 6 — Verification In Progress

The solution compiles with 25 C# projects, 0 errors. Most COM server methods are stubs that need real implementations. See docs/PLAN.md for the full plan.

What's built (Phases 1-5):

  • Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
  • Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  • Phase 3: C++ shims — Inject.DLL (D3D9 hooking) + LauncherHook.DLL
  • Phase 4: DenAgent WinForms tray app replacing the MFC original
  • Phase 5: WiX installer + build script

Phase 6 Progress:

  • DecalDat: WORKING — 13/13 tests pass against real AC DAT files
  • COM Registration: PASS — 50/50 CLSIDs register and verify (0 GUID mismatches)
  • Tools: tools/Test-ComRegistration.ps1 — regasm + registry verification
  • Tests: Managed/Decal.DecalDat.Tests/ — console app smoke tests

What's next:

  • Smoke test DenAgent tray app
  • Integration test — swap one DLL at a time vs original Decal
  • Plugin compatibility (VTank, Mag-Tools)

Key Files

  • Managed/Decal.sln — Main solution (25 projects)
  • Managed/Directory.Build.props — Shared build settings (net472, x86)
  • Managed/Decal.Interop.*/ — COM interface contracts (the spec for everything)
  • Managed/Decal.DecalDat.Tests/ — Smoke tests for DAT file I/O
  • tools/Test-ComRegistration.ps1 — COM registration verification (regasm + registry check)
  • Native/InjectModern/ — Inject.DLL C++ source (~530 lines)
  • Native/LauncherHookModern/ — LauncherHook.DLL C++ source (~330 lines)
  • Native/ — Old C++ source (reference for algorithms, NOT part of the build)
  • Installer/Package.wxs — WiX v5 MSI package
  • build.cmd — Top-level build script
  • docs/PLAN.md — Full project plan with all phases and next steps

Build Commands

# Managed (.NET) — works on Linux/WSL or Windows
dotnet build Managed/Decal.sln

# Native C++ — Windows only, requires VS 2022
cd Native
cmake -G "Visual Studio 17 2022" -A Win32 -B build
cmake --build build --config Release

Architecture

  • 10 COM servers (C#): DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters, Decal.Core, DecalControls, DecalRender, D3DService
  • 2 native DLLs (C++): Inject.DLL (D3D9 vtable hooking), LauncherHook.DLL
  • 1 tray app (C# WinForms): DenAgent
  • All COM servers use [ComVisible], [Guid], [ClassInterface], [ProgId]
  • Original CLSIDs preserved exactly for plugin compatibility

Common Pitfalls

  • record types need IsExternalInit — unavailable in net472, use class instead
  • CollectionsMarshal.AsSpan unavailable in net472
  • LongValueKey enum: correct names are keyStackCount, keyContainer
  • tagPOINT defined in Interop.Inject, needed by Interop.Render → add ProjectReference
  • ICommandEvents delegates ambiguous between Interop.Controls and Interop.Inject → use using aliases
  • GenerateAssemblyInfo=False → use [assembly: InternalsVisibleTo()] attribute, not MSBuild items
  • AppendTargetFrameworkToOutputPath=false → DLLs at bin\Release\, NOT bin\Release\net472\
  • 32-bit regasm registers to WOW6432Node on 64-bit Windows — check both registry views
  • DAT file BTree root is at offset 0x160, NOT 0x148 (old C++ code was wrong)
  • BTree entries are 24 bytes (not 12) — see dat-format.md in memory

Goal

Pixel-perfect drop-in replacement for closed-source Decal v2.9.8.3, targeting the original AC client.exe. Existing community plugins (VTank, Mag-Tools, etc.) should load and work without modification.