прототип, без успехов. может как-нибудь потом

This commit is contained in:
2026-08-10 21:17:04 +04:00
parent b4a2eb8bc2
commit 87ec8c2ce9
13 changed files with 934 additions and 0 deletions
+39
View File
@@ -0,0 +1,39 @@
# Asset manifest
## Blood Elf Female
- Retail build: `WOW-68887patch12.0.7_Retail`
- Race ID: `10`
- ChrModelID: `20`
- Character model FileDataID: `1100258`
- Option: Demon Hunter Horns
- Retail OptionID: `126`
- Runtime element type: Geoset in an attached collection M2
- Collection model FileDataID: `7760202`
- Collection compatibility: `RETAIL_WITH_WXL`
- Runtime virtual path: `MoonWell\Customization\BloodElfFemale\7760202_be_f.m2`
- Prototype attachment point: `11` (stock head point). Retail collection point `19` is absent from
the 3.3.5 Blood Elf model and cannot safely be force-attached.
| Prototype choice | Retail ChoiceID | Retail ElementID | GeosetID | Compatibility |
|---|---:|---:|---:|---|
| None | 1850 | — | — | RETAIL_WITH_WXL |
| Betrayer | 1851 | 2051 | 2401 | RETAIL_WITH_WXL |
| Beast | 1852 | 2052 | 2402 | RETAIL_WITH_WXL |
| Dreadlord | 1853 | 2053 | 2403 | RETAIL_WITH_WXL |
The source catalog reports two collection textures:
| FileDataID | Internal path | Type | Purpose |
|---:|---|---|---|
| 1277002 | `item\objectcomponents\collections\bloodelf_female_dh_belt.blp` | BLP | Collection material dependency |
| 2764488 | `item\objectcomponents\collections\bloodelffemale_dh_horns.blp` | BLP | Collection material dependency |
Skin files exported with the model are FileDataID `7766030` (base), `7766031`, `7766032`, and
`7766033` (LODs). The MVP requests the base sibling `7760202_be_f00.skin`.
No fallback asset is committed or silently substituted. Classification is `RETAIL_WITH_WXL`, not
`RETAIL_NATIVE`: stock 3.3.5 cannot parse this modern collection without the WarcraftXL modern-M2
extension. If it fails in a real client session, the documented next fallback is a small WotLK M2
mounted at the same virtual path; such a placeholder would be classified `WOTLK_FALLBACK` and must be
recorded here before use.
+12
View File
@@ -0,0 +1,12 @@
# Glue integration follow-up
The runtime prototype intentionally does not alter character creation. WarcraftXL v1.1 exposes typed
Glue/Lua bindings in `game/Glue.hpp` and `game/Script.hpp`, while the existing MoonWell extension shows
the validated `Lua.RegisterFunction` / `Lua.ValidateFunctionPointer` bridge used by build 12340.
A safe follow-up is to register
`ModelFrame:SetMoonwellCustomization(optionID, choiceID)` through that existing bridge, resolve the
Glue model's `CharModelObject`, and pass it to the same `CustomizationState` and renderer used here.
Cleanup must follow Glue model destruction rather than `OnWorldLeave`. This should be implemented only
after the runtime collection attachment has passed interactive visual/lifetime testing; no extra client
offset or duplicate renderer is justified for the current vertical slice.
+92
View File
@@ -0,0 +1,92 @@
# MoonwellCustomization vertical slice
## Scope
`MoonwellCustomization.dll` is a runtime-only WarcraftXL 1.1 extension for WoW 3.3.5a build
12340. It changes only an active Blood Elf Female player. State is kept in memory and is deliberately
separate from rendering; there are no server packets, database changes, AzerothCore changes, or new
Wow.exe offsets.
The data flow is:
`CustomizationOption (126) -> CustomizationChoice -> CustomizationElement (Geoset) -> collection M2`
The explicit prototype state is None plus three retail choices. The renderer owns one independent
collection render context at a time. Reapplying the same choice is a no-op; replacing a choice releases
the old context first. The overlay copies the active character's placement and bone palette without
joining the stock attachment readiness chain. `OnWorldLeave` always releases it and drops all borrowed
player pointers.
## Verified WarcraftXL API
The repository pins `vendor/warcraftxl` to `v1.1.220` (`4895cef`) on the `v1.1` branch. Source code,
not README assumptions, establishes the following behavior:
- `WXL_Query`/`WXL_Load` are the extension entry points; the runtime loads DLLs found below
`Extensions/<name>/`.
- `WXL_Api::UiAddPanel` registers an immediate-mode overlay panel. WarcraftXL v1.1 hard-codes `F9`
as its overlay toggle; press it and select **MoonWell Customization**.
- `world::ActivePlayerGuid` and `world::ResolveObject(..., kTypeMaskPlayer)` find the active player;
`unit::Model` returns its body-model/scene-node binding.
- The upstream typed `SceneNode` and `CharModelObject` views provide owner, race, gender, and root
scene node. The extension adds no offsets.
- `m2::GetRenderCtx` always creates a new scene model; `AttachToScene(..., slot 19, true)` attaches a
collection M2. Core explicitly documents 19 as the collection-M2 attachment point.
- `OnM2SkinFinalize` is the safe pre-finalize window to filter collection geosets. Runtime changes
call `FinalizeSkin` once; a recursion guard prevents its event from re-entering the filter.
- `OnBuildBonePalette` is post-engine and therefore the safe point to copy the parent character bone
palette into the collection model immediately before upload.
- `OnItemSlotChange` and `OnItemSlotClear` schedule a replacement on the next logic tick, after native
equipment work. Native equipment is never overridden.
- `OnWorldLeave` is the cleanup event. Events and UI run on WarcraftXL's main/render paths; no worker
thread calls client model bindings.
## Build
From a Visual Studio 2022 developer environment or PowerShell:
```powershell
.\build-warcraftxl.ps1 -Configuration Release
```
The required artifact is:
`build\warcraftxl-win32\Release\MoonwellCustomization.dll`
The target is Win32. The top-level CMake build compiles the extension together with the existing
WarcraftXL SDK sources; there is no second CMake project.
## Install and run
1. Install the asset files described in `docs/wow-export-assets.md` into a client MPQ.
2. Copy the DLL to
`Extensions\MoonwellCustomization\MoonwellCustomization.dll` under the client directory. The build
script does this automatically when invoked with `-Deploy -ClientPath <client>`.
3. Start the stock build-12340 client through the installed WarcraftXL `d3d9.dll` proxy.
4. Press `F9` to open the WarcraftXL overlay and select **MoonWell Customization**.
5. On Blood Elf Female, press None / Betrayer / Beast / Dreadlord. None must remove the collection;
repeated selections must not stack it. Equip and remove a helmet, then log out and back in.
6. On every other race or gender, the panel reports that the prototype is unsupported and exposes no
choice controls.
Expected log lines are tagged `[MoonwellCustomization]`: `loaded`, `player detected`, race/gender,
apply, model load, attach, detach, unsupported player, and actionable failure text.
## Known limits
- The repository intentionally excludes Blizzard assets. Without the collection M2 and sibling skin,
the client loader can fall back to its placeholder model; that is an asset-install failure, not a
successful visual test.
- Retail collection model 7760202 is a modern MD21 asset. It requires the existing `wxl-modern-m2`,
`wxl-modern-blp`, `wxl-db2`, and FDID extensions in this repository.
- Bone copying assumes the retail Blood Elf Female collection uses the same ordered skeleton as its
parent model. The code clamps to the smaller palette, but a retail build changing bone order would
need an explicit bone map.
- `FinalizeSkin` in WXL 1.1 has small internal re-finalize leaks. The implementation therefore performs
it only on an actual choice change/equipment refresh, never per frame.
- This source-level build proves compilation and packaging. A successful visual result and crash-free
logout still require an interactive client session with the external assets installed.
The next minimal step toward a broader retail-like system is to move the static option table to an
external, versioned catalog and add renderers for Texture and independent M2Attachment elements while
keeping the same `optionID -> choiceID` state boundary.
+42
View File
@@ -0,0 +1,42 @@
# Exporting the Blood Elf Female prototype assets
The local wow.export checkout has no documented headless CLI, so this document does not invent one.
Its MoonWell exporter generated the inspected catalog at:
`moonwell-customization/wotlk-races/catalog.json`
The exact source is retail `WOW-68887patch12.0.7_Retail`. Use wow.export's UI to select that product,
then export the WotLK races customization catalog/asset set. From the generated output, take:
| FileDataID | Exported file / internal path | Type | Why |
|---:|---|---|---|
| 7760202 | `assets/collections/7760202/7760202_be_f.m2` | M2 | Blood Elf Female collection containing Demon Hunter horn geosets |
| 7766030 | `assets/collections/7760202/7760202_be_f00.skin` | SKIN | Base geometry/index profile required by the M2 |
| 1277002 | `item/objectcomponents/collections/bloodelf_female_dh_belt.blp` | BLP | Declared collection texture dependency |
| 2764488 | `item/objectcomponents/collections/bloodelffemale_dh_horns.blp` | BLP | Declared collection texture dependency |
Do not add these files to git. Stage them under the ignored `local-assets/` directory, then put them in
a local MPQ with these virtual names:
```text
MoonWell\Customization\BloodElfFemale\7760202_be_f.m2
MoonWell\Customization\BloodElfFemale\7760202_be_f00.skin
item\objectcomponents\collections\bloodelf_female_dh_belt.blp
item\objectcomponents\collections\bloodelffemale_dh_horns.blp
```
Install that MPQ as a high-priority `Data\patch-*.MPQ` beside the existing MoonWell patches. Keep the
three LOD skins (`7766031``7766033`) locally for later testing, but the current MVP does not request
them explicitly.
To reproduce the DB result without changing wow.export, run the repository's read-only catalog helper:
```powershell
node tools/find_customization_assets.js `
C:\Users\sindo\wow.export\moonwell-customization\wotlk-races\catalog.json `
"Blood Elf" female Horns
```
It must report OptionID `126`, then ChoiceIDs `1851`, `1852`, `1853`. Their skinned-model elements
map geoset type `24` and IDs `1`, `2`, `3` to skin sections `2401`, `2402`, `2403`. The helper reads
already-exported JSON only; it does not access CASC and is not a runtime dependency.