wgt01: real .mdl/.wok export via Neverblender

Neverblender is installed + enabled in this machine's Blender 4.0.2 config and
confirmed working headless via the flake. Add generator/export_mdl.py:
assembles each tile as a Neverblender-native model (AuroraBase dummy/tile,
trimesh, single aabb walkmesh) in its own scene and calls scene.nvb_mdlexport
to emit real ASCII <resref>.mdl + <resref>.wok for all 40 tiles.

Walkmesh surfacemats via create_wok_materials() slot order (walkable Stone=4,
Nonwalk=7) -> verified correct per tile (CP1 all 4, CN1 all 7, BR_1/CE_S mixed).

flake.nix: add `export` app (nix run .#export -- <blend> <outdir> [CODE...]).
AGENTS.md: record the Neverblender node/surfacemat facts and the kit's tools;
note the slot-index (not material-name) surfacemat gotcha.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-04 17:04:41 +02:00
co-authored by Claude Opus 4.8
parent 60af184be5
commit 1284f15595
3 changed files with 148 additions and 8 deletions
+27 -8
View File
@@ -273,17 +273,31 @@ tracks Blender 3.x4.x, **not** nixpkgs' Blender 5.x. Do not "upgrade" it.
### 6.1 Tools (all on `PATH` in the dev shell)
- **NeverBlender** — Blender addon that exports NWN `.mdl` + `.wok` and defines
node types (trimesh, **AABB walkmesh**, dummy, light). Install a NeverBlender
release compatible with **Blender 4.0.x** into this Blender
(`Edit ▸ Preferences ▸ Add-ons ▸ Install`). It is **not** bundled in the stock
binary — an agent cannot assume it is present; check and tell the user if a
real MDL export is requested.
node types (trimesh, **AABB walkmesh**, dummy, light). It is **not** bundled in
the stock binary, but is **installed and enabled in this machine's Blender 4.0.2
user config** (`~/.config/blender/4.0`) and works headless — verified via the
flake's `blender-4.0.2 --background`. `wgt01/generator/export_mdl.py` drives it
(see below). If working on another machine, don't assume it's present; check
`addon_utils.enable("neverblender")` and tell the user.
Key facts: root = Empty `nvb.emptytype='dummy'` + `nvb.classification='tile'`
(name == resref); geometry meshes `nvb.meshtype='trimesh'`; one walkmesh mesh
`nvb.meshtype='aabb'`. Walkmesh face surfacemat = the mesh's material *slot*
index after `nvb_utils.create_wok_materials(mesh)` fills slots 0..22 in
`nvb_def.wok_materials` order (walkable Stone=4, Nonwalk=7). Export:
`scene.nvb_mdlexport(filepath=..., export_walkmesh=True)` on the active scene.
- **cleanmodels** — cleans/optimizes ASCII MDL, fixes common walkmesh problems.
- **neverwinter-nim** — CLI (`nwn_erf`, `nwn_gff`, …): pack the `.hak`/ERF, and
read/write GFF (the `.itp` is GFF).
- **blender-mcp-nwn** (see `/nix/nixos/blender-mcp-nwn`) — MCP server exposing
`run_blender_script`, `read_blend_metadata`, `export_for_nwn` so Claude can
drive Blender 4.0.2 headless against these `.blend` sources.
- **wgt01 generator kit** (`wgt01/generator/`, driven by `wgt01/flake.nix` apps):
`build.py` (`nix run .#build`) builds the `.blend` tile library from the shared
`tiles.py` table; `export_mdl.py` (`nix run .#export -- <blend> <outdir>`)
exports real `.mdl`+`.wok` per tile via NeverBlender; `make_wok.py`
(`nix run .#wok`) and `make_set.py` (`nix run .#set`) are pure-Python (no
Blender) emitters — an ASCII `.wok` fallback (format validated against
NeverBlender's own output) and a first-pass `.set`.
### 6.2 Build → export → pack
1. **Generate `.blend` source**`nix run .#build -- out.blend` (or drive via the
@@ -353,9 +367,14 @@ tracks Blender 3.x4.x, **not** nixpkgs' Blender 5.x. Do not "upgrade" it.
- **Custom doors not in `doortypes.2da`** (and not merged/shipped) → blank doors.
- **`Transition=0`** disables adjacent placement of groups/features.
- **Group first tile `-1` or non-unique filename** → crash / no autopick.
- **NeverBlender not installed** in this Blender → `export_for_nwn` gives you
OBJ/FBX + an `mdl.json` config, **not** a real `.mdl`. Install the addon for
true MDL/WOK export; say so rather than claiming MDL output.
- **NeverBlender walkmesh surfacemat** comes from the face's material *slot*
index, **not** the material name — you must call
`nvb_utils.create_wok_materials(mesh)` first (fills slots 0..22) then set each
face's `material_index` to the surfacemat id. Naming a lone material `wok_Stone`
is silently ignored (falls back to slot order). `export_mdl.py` does this right.
- **NeverBlender not installed** (other machines) → `export_for_nwn` gives you
OBJ/FBX + an `mdl.json` config, **not** a real `.mdl`. Use `make_wok.py` for an
ASCII `.wok` fallback, or install the addon; say so rather than claiming MDL.
- **Don't upgrade Blender past 4.x** here — breaks NeverBlender/cleanmodels.
---