519 lines
19 KiB
Markdown
519 lines
19 KiB
Markdown
# OpenWC
|
||
|
||
Портирование клиента **World of Warcraft 3.3.5a (12340)** на **Godot 4.6**.
|
||
|
||
Текущий фокус проекта: загрузка данных из клиента, разбор форматов WoW и отображение мира в Godot так, чтобы его можно было смотреть и дальше редактировать уже средствами движка.
|
||
|
||
Сейчас проект уже умеет:
|
||
|
||
- открывать MPQ-архивы клиента через editor plugin;
|
||
- извлекать файлы из MPQ в `res://data/extracted`;
|
||
- читать `BLP2` текстуры;
|
||
- читать `ADT`-тайлы terrain;
|
||
- рендерить terrain из `ADT` с текстурными слоями `MCLY/MCAL`;
|
||
- учитывать `holes` в `MCNK`;
|
||
- читать и рендерить воду из `MH2O`;
|
||
- стримить мир чанками с LOD в runtime;
|
||
- стримить мир в **editor preview** по мере движения камеры в 3D viewport;
|
||
- читать `WMO` в отдельный `Dictionary` и собирать его в `Node3D` вручную.
|
||
|
||
Что пока не доведено до полноценного world renderer:
|
||
|
||
- автоматическая подстановка `WMO` и `M2` в мир из `ADT/WDT`;
|
||
- вода без простого базового материала: нет нормального water shader, depth fade, shoreline blending, анимации;
|
||
- world-level `WDT` loader;
|
||
- импорт обратно в форматы WoW;
|
||
- полноценные инструменты редактирования мира в editor.
|
||
|
||
## Текущее состояние
|
||
|
||
### Реализовано
|
||
|
||
- `MPQManager`
|
||
- открытие клиентских архивов;
|
||
- список архивов по приоритету;
|
||
- listing/extract по фильтру.
|
||
- `BLPLoader`
|
||
- чтение `BLP2` из файла или из байтов;
|
||
- поддержка основных сжатых форматов, достаточная для terrain textures.
|
||
- `ADTLoader`
|
||
- `MTEX`, `MMDX/MMID`, `MWMO/MWID`;
|
||
- `MDDF`, `MODF`;
|
||
- `MCVT`, `MCNR`, `MCLY`, `MCAL`;
|
||
- `holes`;
|
||
- `MH2O`.
|
||
- `ADTBuilder`
|
||
- сборка terrain в `Node3D`;
|
||
- terrain material с 4 слоями;
|
||
- legacy/big/compressed alpha;
|
||
- chunk-level LOD;
|
||
- первый проход рендера воды.
|
||
- `StreamingWorld`
|
||
- runtime streaming тайлов и чанков;
|
||
- editor streaming вокруг камеры viewport;
|
||
- отдельные `ADT`-узлы под `Terrain` в дереве сцены.
|
||
|
||
### Частично реализовано
|
||
|
||
- `WMOLoader`
|
||
- root/group parsing есть;
|
||
- `WMOBuilder` собирает mesh по группам;
|
||
- в общий world streaming пока не интегрировано.
|
||
|
||
### Не реализовано
|
||
|
||
- `M2` renderer;
|
||
- `WDT` streaming metadata;
|
||
- сохранение terrain/liquid/object placement обратно в WoW-форматы;
|
||
- редакторские инструменты изменения ADT/WMO данных.
|
||
|
||
## Структура проекта
|
||
|
||
- `sources/`
|
||
- исходный клиент WoW 3.3.5a, без модификаций.
|
||
- `data/extracted/`
|
||
- извлечённые из MPQ файлы, с которыми работает Godot.
|
||
- `data/cache/`
|
||
- generated/offline cache: baked terrain, M2 GLB cache, WMO scene cache. Эти файлы не являются исходниками проекта и игнорируются git.
|
||
- `addons/mpq_extractor/`
|
||
- editor plugin и GDScript-сборщики сцен.
|
||
- `src/native/`
|
||
- C++ GDExtension: MPQ, BLP, ADT, WMO.
|
||
- `src/scenes/`
|
||
- готовые сцены для просмотра мира.
|
||
- `src/tools/`
|
||
- bake/conversion scripts.
|
||
- `src/resources/`
|
||
- Godot resources, generated GLB assets and runtime resource scripts.
|
||
- `reference/`
|
||
- external reference sources/tools: Blender WoW Studio, wow.export and Noggit RED. Runtime-project must not depend on this directory.
|
||
- `reference/noggit-red/`
|
||
- Noggit RED source reference for WoW 3.3.5 map editing, ADT/WMO/M2 placement behavior and UID workflows.
|
||
- внешние reference sources и tools для сверки форматов. Runtime-проект не должен зависеть от этой директории.
|
||
- `third_party/`
|
||
- `godot-cpp`, `StormLib` и другие зависимости.
|
||
|
||
## Требования
|
||
|
||
- Windows
|
||
- Godot `4.6`
|
||
- Visual Studio 2022 с C++ workload
|
||
- CMake
|
||
- клиент **WoW 3.3.5a (12340)**
|
||
|
||
## Сборка
|
||
|
||
Собрать GDExtension:
|
||
|
||
```bat
|
||
cd src\native
|
||
build.bat Release
|
||
```
|
||
|
||
После успешной сборки DLL появится в:
|
||
|
||
```text
|
||
addons/mpq_extractor/bin/
|
||
```
|
||
|
||
VS Code/CMake использует `src/native` как `cmake.sourceDirectory`.
|
||
|
||
## Подготовка данных
|
||
|
||
По умолчанию plugin смотрит на клиент в:
|
||
|
||
```text
|
||
res://sources
|
||
```
|
||
|
||
И извлекает файлы в:
|
||
|
||
```text
|
||
res://data/extracted
|
||
```
|
||
|
||
### Через editor plugin
|
||
|
||
1. Открой проект в Godot.
|
||
2. Убедись, что plugin `MPQ Extractor` включён.
|
||
3. Внизу editor открой панель `MPQ Extractor`.
|
||
4. Укажи путь к клиенту WoW 3.3.5a.
|
||
5. Выбери locale.
|
||
6. Нажми `Open Client Archives`.
|
||
7. Для полной распаковки используй фильтр `*` и `Extract`.
|
||
|
||
Для terrain/world обычно нужны как минимум:
|
||
|
||
- `World/Maps/...`
|
||
- `Textures/...`
|
||
- `World/wmo/...`
|
||
- `DBFilesClient/...` если позже понадобится работа с DBC
|
||
|
||
## Основные классы GDExtension
|
||
|
||
### `MPQManager`
|
||
|
||
Доступен из GDScript. Основные методы:
|
||
|
||
- `open_client(base_path, locale)`
|
||
- `list_files(filter="*")`
|
||
- `extract_files(filter, output_dir)`
|
||
- `read_file(internal_path)`
|
||
|
||
### `BLPLoader`
|
||
|
||
Читает WoW `BLP2` и возвращает `Image`.
|
||
|
||
Основные методы:
|
||
|
||
- `load_image(path)`
|
||
- `load_image_from_bytes(bytes)`
|
||
|
||
### `ADTLoader`
|
||
|
||
Читает `ADT` и возвращает `Dictionary` с terrain, texture layers, placements и liquid.
|
||
|
||
Основные поля результата:
|
||
|
||
- `textures`
|
||
- `m2_names`
|
||
- `wmo_names`
|
||
- `m2_placements`
|
||
- `wmo_placements`
|
||
- `chunks`
|
||
|
||
Каждый chunk содержит:
|
||
|
||
- `index_x`, `index_y`
|
||
- `origin`
|
||
- `heights`
|
||
- `normals`
|
||
- `holes`
|
||
- `layers`
|
||
- `alpha_maps`
|
||
- `liquids`
|
||
|
||
### `WMOLoader`
|
||
|
||
Читает root/group файлы `WMO` и возвращает `Dictionary` с `materials` и `groups`.
|
||
|
||
Это уже можно использовать вручную, но в world streaming оно пока не подключено.
|
||
|
||
## Export/bake scripts
|
||
|
||
Все проектные скрипты экспорта и запекания лежат в `src/tools/`. Скрипты с расширением `.gd` запускаются через Godot headless и требуют собранный GDExtension, потому что используют `ADTLoader`, `M2Loader` и `WMOLoader`. Перед запуском данные клиента должны быть извлечены в `res://data/extracted`.
|
||
|
||
Если `godot` не добавлен в `PATH`, используй путь из `.vscode/settings.json`, например:
|
||
|
||
```powershell
|
||
& 'c:\Godot 4.6\Godot_v4.6.1-stable_win64.exe' --headless --path . --script res://src/tools/bake_all.gd -- --map Azeroth --force
|
||
```
|
||
|
||
### `src/tools/bake_all.gd`
|
||
|
||
Запекает terrain, M2 doodads и WMO objects за один проход.
|
||
|
||
```powershell
|
||
godot --headless --path . --script res://src/tools/bake_all.gd -- --map Azeroth --force
|
||
```
|
||
|
||
Основные аргументы:
|
||
|
||
- `--map Azeroth`
|
||
- `--extracted res://data/extracted`
|
||
- `--terrain-output res://data/cache/baked_terrain_v2`
|
||
- `--m2-output res://data/cache/m2_glb`
|
||
- `--wmo-output res://data/cache/wmo_tscn`
|
||
- `--full-texture-size 2048`
|
||
- `--coarse-texture-size 512`
|
||
- `--skip-terrain`, `--skip-m2`, `--skip-wmo`
|
||
- `--force`
|
||
|
||
### `src/tools/bake_adt_terrain_cache.gd`
|
||
|
||
Запекает terrain tiles в `.res` ресурсы `BakedADTTile`. Runtime streaming читает их из `baked_tile_cache_dir`.
|
||
|
||
```powershell
|
||
godot --headless --path . --script res://src/tools/bake_adt_terrain_cache.gd -- --map Azeroth --output res://data/cache/baked_terrain_v2 --force
|
||
```
|
||
|
||
Основные аргументы:
|
||
|
||
- `--map Azeroth`
|
||
- `--extracted res://data/extracted`
|
||
- `--output res://data/cache/baked_terrain_v2`
|
||
- `--tile-x 32`, `--tile-y 48` для одного тайла
|
||
- `--full-texture-size 2048`
|
||
- `--coarse-texture-size 512`
|
||
- `--texture-size N` legacy alias для обоих размеров
|
||
- `--force`
|
||
|
||
### `src/tools/bake_m2_cache.gd`
|
||
|
||
Сканирует ADT tiles, собирает уникальные M2 paths и запекает M2 doodads в `PackedScene` `.tscn`.
|
||
|
||
```powershell
|
||
godot --headless --path . --script res://src/tools/bake_m2_cache.gd -- --map Azeroth --output res://data/cache/m2_glb --force
|
||
```
|
||
|
||
Основные аргументы:
|
||
|
||
- `--map Azeroth`
|
||
- `--extracted res://data/extracted`
|
||
- `--output res://data/cache/m2_glb`
|
||
- `--force`
|
||
|
||
### `src/tools/bake_wmo_cache.gd`
|
||
|
||
Сканирует ADT tiles, собирает уникальные WMO paths и запекает WMO world objects в `PackedScene` `.tscn`.
|
||
|
||
```powershell
|
||
godot --headless --path . --script res://src/tools/bake_wmo_cache.gd -- --map Azeroth --output res://data/cache/wmo_tscn --force
|
||
```
|
||
|
||
Основные аргументы:
|
||
|
||
- `--map Azeroth`
|
||
- `--extracted res://data/extracted`
|
||
- `--output res://data/cache/wmo_tscn`
|
||
- `--force`
|
||
|
||
### `src/tools/collect_world_m2_list.gd`
|
||
|
||
Сканирует ADT tiles и сохраняет список уникальных M2 paths. Полезно перед массовой конвертацией или для оценки объема M2 cache.
|
||
|
||
```powershell
|
||
godot --headless --path . --script res://src/tools/collect_world_m2_list.gd -- --map Azeroth --output res://data/cache/m2_glb/Azeroth_m2_list.txt
|
||
```
|
||
|
||
Основные аргументы:
|
||
|
||
- `--map Azeroth`
|
||
- `--extracted res://data/extracted`
|
||
- `--output res://data/cache/m2_glb/Azeroth_m2_list.txt`
|
||
|
||
### `src/tools/m2_to_gltf.py`
|
||
|
||
Python converter для WoW 3.3.5 M2 v264 в GLTF 2.0 `.glb`. Также экспортирует texture layers рядом с GLB. Для DXT BLP decoding нужен `Pillow`.
|
||
|
||
Один M2:
|
||
|
||
```powershell
|
||
python src/tools/m2_to_gltf.py data/extracted/Character/BloodElf/Female/BloodElfFemale.M2 src/resources/characters/BloodElf/Female
|
||
```
|
||
|
||
Рекурсивная конвертация:
|
||
|
||
```powershell
|
||
python src/tools/m2_to_gltf.py --all data/extracted/Character --out src/resources/characters
|
||
```
|
||
|
||
Аргументы:
|
||
|
||
- `input` путь к одному `.M2`
|
||
- `output_dir` директория вывода для одного `.M2`
|
||
- `--all SEARCH_DIR` рекурсивно конвертирует все `.M2` под директорией
|
||
- `--out OUT_ROOT` root вывода для `--all`; по умолчанию `src/resources`
|
||
|
||
### Reference-only export scripts
|
||
|
||
В `reference/` лежат внешние скрипты и исходники для сверки форматов, включая Blender/WoW export tools из `reference/` и `reference/wow.export/`. Они не являются частью project pipeline, не вызываются runtime-кодом и не должны использоваться как источник project cache без явного переноса в `src/tools/`.
|
||
|
||
Найденные reference scripts, связанные с export/conversion:
|
||
|
||
- `reference/blender-wow-studio-3.4-1.1.0_Experimental/io_scene_wmo/m2/export_m2.py`
|
||
- `reference/blender-wow-studio-3.4-1.1.0_Experimental/io_scene_wmo/m2/operations/convert_m2_bones.py`
|
||
- `reference/blender-wow-studio-3.4-1.1.0_Experimental/io_scene_wmo/m2/operations/m2_export_validation.py`
|
||
- `reference/blender-wow-studio-3.4-1.1.0_Experimental/io_scene_wmo/wmo/export_wmo.py`
|
||
- `reference/wow.export/addons/blender/io_scene_wowobj/animation_processor.py`
|
||
- `reference/wow.export/addons/blender/io_scene_wowobj/import_wowobj.py`
|
||
- `reference/wow.export/addons/blender/io_scene_wowobj/__init__.py`
|
||
|
||
`toolbar.py` files в reference UI directories относятся к Blender UI этих внешних tools и не являются самостоятельными export/bake entrypoints.
|
||
|
||
`reference/noggit-red/` is not an export script collection. It is a source reference for WoW 3.3.5 map editing behavior: ADT/WMO/M2 placement, UID handling, map editing workflows and related editor code.
|
||
|
||
## GDScript-сборщики
|
||
|
||
### `ADTBuilder`
|
||
|
||
Файл: `addons/mpq_extractor/loaders/adt_builder.gd`
|
||
|
||
Умеет:
|
||
|
||
- собрать весь `ADT` в `Node3D`;
|
||
- собрать отдельный chunk с нужным LOD;
|
||
- собрать water root для тайла;
|
||
- создать layered terrain material;
|
||
- загрузить BLP-текстуры через `BLPLoader`.
|
||
|
||
### `WMOBuilder`
|
||
|
||
Файл: `addons/mpq_extractor/loaders/wmo_builder.gd`
|
||
|
||
Умеет:
|
||
|
||
- собрать `Node3D` из данных `WMOLoader`;
|
||
- создать по одному `MeshInstance3D` на группу;
|
||
- назначить базовые материалы.
|
||
|
||
## Сцены просмотра
|
||
|
||
### `src/scenes/streaming/test.tscn`
|
||
|
||
Файл: `src/scenes/streaming/test.tscn`
|
||
|
||
Тестовая сцена, которая грузит квадрат тайлов вокруг центра карты.
|
||
|
||
Скрипт: `src/scenes/streaming/test_world_loader.gd`
|
||
|
||
Подходит для:
|
||
|
||
- быстрой проверки terrain;
|
||
- отладки парсинга `ADT`;
|
||
- проверки AABB и координат.
|
||
|
||
### `src/scenes/preview/adt_tile_preview.tscn`
|
||
|
||
Файл: `src/scenes/preview/adt_tile_preview.tscn`
|
||
|
||
Preview одного `ADT` прямо в editor.
|
||
|
||
Скрипт: `src/scenes/preview/adt_tile_preview.gd`
|
||
|
||
Полезно для:
|
||
|
||
- проверки одного конкретного тайла;
|
||
- отладки terrain layers;
|
||
- проверки воды и дыр по отдельному `ADT`.
|
||
|
||
Основные export-поля:
|
||
|
||
- `map_name`
|
||
- `tile_x`
|
||
- `tile_y`
|
||
- `reload_now`
|
||
|
||
### `src/scenes/streaming/eastern_kingdoms_streaming.tscn`
|
||
|
||
Файл: `src/scenes/streaming/eastern_kingdoms_streaming.tscn`
|
||
|
||
Главная сцена для стриминга мира.
|
||
|
||
Скрипт: `src/scenes/streaming/streaming_world_loader.gd`
|
||
|
||
Умеет:
|
||
|
||
- находить все доступные `ADT` тайлы в `World/Maps/Azeroth`;
|
||
- загружать/выгружать тайлы по мере перемещения;
|
||
- строить chunk mesh по LOD;
|
||
- отдельно добавлять воду на тайл;
|
||
- работать и в runtime, и в editor.
|
||
|
||
## Editor streaming
|
||
|
||
`StreamingWorld` теперь умеет подгружать мир прямо в editor по мере движения камеры viewport.
|
||
|
||
Ключевые export-поля:
|
||
|
||
- `editor_preview_enabled`
|
||
- `editor_follow_view_camera`
|
||
- `editor_preview_center_x`
|
||
- `editor_preview_center_y`
|
||
- `editor_preview_tile_radius`
|
||
- `editor_reload_now`
|
||
|
||
Логика такая:
|
||
|
||
- `editor_preview_center_x/y` задают anchor, который сдвигается к `origin`, чтобы мир было удобно смотреть в Godot;
|
||
- при `editor_follow_view_camera = true` стриминг идёт вокруг положения editor camera в 3D viewport;
|
||
- тайлы и их children появляются под `Terrain` в Scene Tree.
|
||
|
||
Это нужно, чтобы визуально проверить, что мир действительно собирается по мере перемещения по карте, а не только как статичный превью-блок.
|
||
|
||
## Runtime streaming и LOD
|
||
|
||
В runtime `StreamingWorld`:
|
||
|
||
- подгружает `ADT` тайлы по расстоянию;
|
||
- для terrain использует chunk-level LOD;
|
||
- хранит дальний мир на грубом chunk LOD;
|
||
- отдельно создаёт воду на тайл.
|
||
|
||
Основные параметры:
|
||
|
||
- `tiles_per_tick`
|
||
- `chunk_ops_per_tick`
|
||
- `lod0_radius_chunks`
|
||
- `lod1_radius_chunks`
|
||
- `lod2_radius_chunks`
|
||
- `lod2_tile_radius`
|
||
|
||
## Управление камерой
|
||
|
||
Файл: `src/scenes/camera/fly_camera.gd`
|
||
|
||
Управление:
|
||
|
||
- `RMB` удерживать для обзора;
|
||
- `WASD` движение;
|
||
- `Q/E` вниз/вверх;
|
||
- `Shift` ускорение.
|
||
|
||
## Что именно уже исправлено в terrain pipeline
|
||
|
||
По сравнению с самым ранним состоянием проекта уже поправлены:
|
||
|
||
- layout `MCNKHeader`;
|
||
- offsets внутри `MCNK`;
|
||
- чтение `MCVT`;
|
||
- чтение `MCNR`;
|
||
- legacy `MCAL`;
|
||
- big alpha / compressed alpha;
|
||
- корректные local coordinates внутри `ADT`-узла;
|
||
- holes;
|
||
- chunk winding/culling;
|
||
- editor preview одного тайла;
|
||
- streaming всего `Azeroth`;
|
||
- первый проход `MH2O`.
|
||
|
||
## Ограничения текущей версии
|
||
|
||
- terrain текстурирование уже рабочее, но ещё не 1:1 как в клиенте/Noggit во всех edge cases;
|
||
- water renderer сейчас базовый, без настоящих WoW water materials;
|
||
- `WMO` читается отдельно, но world placement пока не подключён;
|
||
- `M2` placements из `ADT` парсятся, но renderer нет;
|
||
- `WDT` ещё не управляет составом мира;
|
||
- проект сейчас ориентирован на просмотр и исследование данных, а не на полный round-trip import/export.
|
||
|
||
## Ближайшие логичные шаги
|
||
|
||
1. Подключить `WDT`, чтобы мир собирался не по сканированию папки, а по данным карты.
|
||
2. Интегрировать `WMO` placement в `StreamingWorld`.
|
||
3. Добавить `M2` loader/renderer.
|
||
4. Довести water shader.
|
||
5. Начать editor-side инструменты для редактирования terrain/liquid/object placement.
|
||
6. Подготовить формат сохранения обратно в WoW-совместимые структуры.
|
||
|
||
## Быстрый старт
|
||
|
||
1. Положить клиент WoW 3.3.5a в `sources/` или указать путь через plugin.
|
||
2. Собрать расширение:
|
||
|
||
```bat
|
||
cd src\native
|
||
build.bat Release
|
||
```
|
||
|
||
3. Извлечь данные в `res://data/extracted` через `MPQ Extractor`.
|
||
4. Открыть одну из сцен:
|
||
- `src/scenes/preview/adt_tile_preview.tscn`
|
||
- `src/scenes/streaming/test.tscn`
|
||
- `src/scenes/streaming/eastern_kingdoms_streaming.tscn`
|
||
|
||
Если нужен именно просмотр мира в editor по движению камеры, используй:
|
||
|
||
- `src/scenes/streaming/eastern_kingdoms_streaming.tscn`
|
||
- `editor_preview_enabled = true`
|
||
- `editor_follow_view_camera = true`
|