Files
healer-man/scripts/runewaker-pipeline
2026-09-12 11:07:25 -04:00
..
2026-09-09 16:43:37 -04:00
2026-09-12 11:07:25 -04:00
2026-08-14 15:56:39 -04:00
2026-09-12 11:07:25 -04:00
2026-09-08 10:40:26 -04:00
2026-09-12 11:07:25 -04:00
2026-09-05 11:40:50 -04:00
2026-08-14 15:56:39 -04:00
2026-08-14 15:56:39 -04:00
2026-08-14 15:56:39 -04:00
2026-09-08 10:40:26 -04:00
2026-09-12 11:07:25 -04:00

RuneWaker dungeon pipeline

This pipeline converts preserved RuneWaker .ros dungeon assets into the same browser-facing GLB roles used by HealerMan's WoW dungeon pipeline:

  1. the preserved Rune engine reads every WDB descriptor and exports each unique ROS once into a normalized-path cache validated by the source SHA-256;
  2. Microsoft texconv decodes each cached resource's legacy DDS textures to PNG;
  3. Blender converts the Y-up resources to reusable visual and collision GLBs;
  4. the assembler applies every placement's full translation/quaternion/scale transform relative to the reviewed primary WDB anchor;
  5. glTF Transform instances and optimizes the assembled visual with meshopt;
  6. HealerMan's Recast stage bakes static navigation and the Khronos validator gates every GLB.

Run the Forsaken Abbey pilot from the HealerMan root:

npm run runewaker:forsaken

Optional environment variables:

  • RUNEWAKER_ROOT: preserved backup root containing Resource and Tools
  • BLENDER_BIN: Blender 5 portable executable
  • TEXCONV_BIN: Microsoft DirectXTex texconv.exe
  • MSVC_V142_ROOT: portable MSVC v142 root used by the native build script

The shipping environment is written to src/assets/game/dungeons/forsaken-abbey and registered as a playable dungeon. The build reads all 184 WDB entity descriptors, uses the primary ROS placement only as the server-to-local coordinate anchor, reads the entrance from Resource/luascript/03242.lua, and requires that entrance to project within 2 meters of the generated navmesh.

All valid ROS placement resources are assembled by default. Use --primary-only only for a deliberate compatibility/debug build. The build writes wdb-placement-manifest.json with stable placement IDs, source TRS, the complete primary-local Three.js matrix, resource-cache keys, bounds, flags, asset status, and reviewed dynamic-object metadata. Static placements enter visual, collision, and navigation assets. Explicit dynamic placements ship separately so runtime state can move, hide, or replace them without baking their collision into the static world.

Audit the checked-in WDB coverage without regenerating GLBs:

npm run runewaker:audit:environment-assembly

See RUNEWAKER_ENVIRONMENT_ASSEMBLY_REPORT.md for unsupported types and dynamic candidates that still need source review.

Population and creature assets are separate, offline-capable stages:

npm run runewaker:forsaken:actors
npm run runewaker:forsaken:population

Source-shaped combat coefficients and boss loot are refreshed independently:

npm run runewaker:spells:refresh
npm run runewaker:loot:refresh

See RUNEWAKER_FORMULA_AND_LOOT.md for the exact formula mapping boundary and RUNEWAKER_LOOT_IMPORT_REPORT.md for every boss's loot status.

Only an explicit forensic refresh connects to the isolated development SQL instance:

npm run runewaker:forsaken:population:refresh

The normal population build consumes the checked-in 251-row Zone 102 snapshot and never connects to SQL Server. It packages 150 combat spawns, eight boss objectives, and nine authentic native-animation creature GLBs. The remaining 101 rows are retained in the source report for later quest-object, door, transport, script, and treasure passes.

All configured instances

The generalized batch now packages and registers all 30 configured RuneWaker instances (Forsaken Abbey plus 29 generated definitions). The normal workflow is fully local and does not use SQL:

npm run runewaker:prepare:all
npm run runewaker:build:all
npm run runewaker:register:all

runewaker:prepare:all consumes the portable forensic JSON already under runewaker-export-work. runewaker:build:all is resumable and writes a result after every dungeon. runewaker:register:all exposes only instances whose full validation report is green.

Creature animation policy is audited separately:

npm run runewaker:audit:animations

The audit opens every referenced creature GLB, checks its glTF header and animation table, resolves every spawn and entity in all 30 runtime definitions, and exercises the available native or procedural state paths. Pasper's Shrine is the compact direct-mesh reference package. The full batch now uses original GR2 skeletons and sampled RAS clips for validated direct actors, while runtime paperdoll containers are assembled into exact image-specific actors from a portable appearance snapshot. Genuinely unsupported pose-only or triangle-free displays remain explicit exceptions rather than silently claiming native motion. See ORIGINAL_ANIMATION_IMPORT.md for the reproducible conversion and rollout process, and RUNEWAKER_ANIMATION_AUDIT.md for the package historical baseline and current all-dungeon status.

Paperdoll appearance recovery is an explicit forensic refresh, separate from normal builds:

npm run runewaker:paperdolls:refresh
npm run runewaker:build:all -- --phase actors,population --force

The refresh restores ObjectEdit.bak under a temporary read-only database, exports only combat-template image rows, writes the checked-in portable runewaker-paperdoll-appearances.json, and drops the temporary database in finally. Normal actor builds, tests, production builds, and browser play use that JSON and packaged GLBs with SQL stopped. Appearance provenance preserves component names and color layers; any unresolved composite-mask color bake is reported explicitly in the actor manifest.

Portable populations, source spells, and objective routes

NPC spell evidence is exported from the preserved read-only RuneWaker client catalogs into a checked-in portable snapshot:

npm run runewaker:bosses:refresh
npm run runewaker:build:all -- --phase population --force
npm run runewaker:forsaken:population
npm run runewaker:audit:gameplay

The existing all-instances runner starts a separate Node population-builder process for each of the 29 generalized packages. Forsaken Abbey keeps its special pilot builder. Both builders emit ordinary TypeScript definitions and JSON reports; the browser never opens the original client catalogs or SQL backups.

Spell conversion is deliberately fail-closed. Only a MagicObject component positively classified as direct HP damage becomes an executable HealerMan attack. Buffs, healing, summons, plot hooks, and unknown effects remain evidence-only. The portable mapping preserves source spell identity, name, damage family, school, range, cooldown, source power fields, and source-code formula provenance. Live damage uses a labeled HealerMan baseline adapter because the required native ATK/MATK, DEF/MDEF, weapon, resistance, critical, level-rate, and global-rate inputs are not packaged; it is not represented as source-exact.

runewaker:bosses:refresh first rebuilds that portable spell snapshot, then statically follows each packaged boss's preserved AutoPlot/template callbacks and writes modular rw-<dungeon>-<entity-id> kits to dungeon-pipeline/boss-mechanics.json. Each special is an independent record with stable ID, trigger, target, effects, and explicit circle, cone, or line telegraph geometry. Both population builders copy those IDs into combat.mechanicIds, so the same runtime loadout boundary is shared by Runewaker and WoW encounters and can later support reviewed randomization.

Source-backed records identify the RuneWaker Lua and spell evidence they came from. If the preserved scripts expose only encounter-progression hooks, the importer creates a conservative playable mechanic marked source.kind: "healer-man-source-gap"; it never labels that fallback as an original RuneWaker ability. Edit or append a boss kit in the shared catalog, then rerun the population build and gameplay audit to update an encounter.

The gameplay audit also:

  • verifies every executable attack.spellId against both its source template assignment and the portable spell catalog;
  • rejects evidence-only spell IDs if they enter runtime combat data;
  • requires every boss objective to resolve a modular catalog kit and validates its source label, telegraph, timed trigger, and health trigger;
  • reuses the live party-navigation graph to inspect boss approach points projected to the retained surface within 6m;
  • validates native animation families, with Rune Device's missing locomotion documented as a stationary-device exception while its attack/activation clips remain mandatory.

The generated RUNEWAKER_GAMEPLAY_CONTENT_REPORT.md is the current cross-dungeon content baseline. The generalized population builder currently falls back to straight-line distance from the entrance when ordering bosses. That fallback is labeled healerMan-distance-derived: an unreachable heuristic leg is navigation/order review evidence, not a claimed source-authored structural failure. A future explicit recipe order must include preserved local source evidence before it can become authoritative. The builder accepts that reviewed override only as bossObjectiveOrder: { kind: "source-authored", spawnIds: [...], evidence: [...] }; it rejects missing evidence, duplicates, or an order that does not account for every boss spawn.

The same gameplay audit also regenerates the deterministic RUNEWAKER_ENCOUNTER_IMPLEMENTATION_REPORT.md and its exhaustive JSON companion. The ledger records all deferred source spawn rows and direct mechanics evidence with stable IDs, source files and hashes, fidelity, implementation status, blocker, next work, and a clearing test. Category totals are overlapping review labels, never a claimed count of unique mechanics. Unproven behavior remains deferred-source-gap instead of being silently inferred from a name or regex match.

Run only that ledger and its pipeline tests with:

npm run runewaker:audit:encounters

Run the component-level navigation review separately:

npm run runewaker:audit:navigation

It writes RUNEWAKER_NAVIGATION_GAP_REPORT.md, measures every unreachable heuristic leg against all raw Recast components, and records reviewed source evidence for support-pad environments, authored room placements, doors, drops, and teleports. It never writes navigation links. No automatic links are currently approved: the observed gaps either depend on mechanics/order evidence or on modular environment assembly, so bridging them would bypass gates or cross missing geometry.

The forensic source refresh is intentionally separate:

npm run runewaker:refresh:all

It requires the isolated HEALERMAN_RW SQL service to be running, restores both backups read-only under temporary names, exports all configured zones, drops the temporary databases in finally, and regenerates the portable snapshots. Stop the SQL service again before running the normal build or game.

See INSTANCE_IMPORT_GUIDE.md for provenance, coordinate rules, special WDB cases, mechanics review, validation, and the step-by-step process for adding future instances.