Review B3: floor(cycle) % 50 keeps the ring roll continuous across the 1000 s
wrap. B8: publish the ripple clock only while it rains. B7: nudge the wet
sheen half-vector off zero. B6: WORD_WINDOW batches are excluded from wet
darkening.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review P4: emissive_boost now lifts only above a 0.6 knee (equal to the old
gain at 1.0), so additive spells and lava keep their look and the excess feeds
the bloom. Review P3: the window gain applies to static_gx's SIDN light term
before fog, not to the whole fogged batch. Review P6: Low-tier extract taps
scale with the quarter-size target. Review P7: excess capped at 64 (no NaN).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bit 18 aliases the top lane-weight bit and bit 12 of the interior probe slot,
so doorway units and probe-lit interior props swayed like trees. A classified
leaf batch's fade-band exile now gets marked copies of its cutout/blend
materials (clutter_fade.z bit 14, FOLIAGE_WIND_MARKER, not a key axis) and
wow_model.wgsl sways only those.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The wave phase was k*speed(t)*t (its rate grows with session age: ~33 Hz noise
after 10 min) and its spatial term rotated about the world origin with the veer
(hundreds of rad/s at 9k yd from the first second). Now update_wind integrates
travel += speed*dt in f64 and publishes it wrapped at 4096 yd (wind_b.x); every
wave rate is a whole number of cycles per wrap, so the wrap is seamless. The
spatial term uses the fixed profile heading (wind_a.z); the veer and gust turn
only the bend. Capture offset WOW_CAPTURE_WIND_T for late-session shots.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Naga Oil treats a trailing digit as an invalid composable-module identifier. Rename the remaining sky, water, and shadow helpers and locals without changing their calculations.
Co-Authored-By: GPT-5.6 Sol (Codex)
Sun-fog strength 0.25 / angle 0.4 / lean 0.4, end-fog lean 0.25: the first
pass turned dusk ridges into flat orange cut-outs against a blue sky. The
dome's low band now MIXES toward the far fog colour by 15 deg (an offset
over-pushed an already warm dusk ring). update_fog_model joins the
ordering test's ALLOWED list (it runs in the resolve set, after it).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wetness ramps up while it rains (~90 s to soaked) and dries over ~4 min; ripple clock;
rainSurfaces resource; env WOW_RAIN_SURFACES / WOW_WETNESS / WOW_WET_T capture overrides.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
naga_oil refuses a composable-module identifier that naga's namer would
rewrite (a trailing digit gets a '_'), which failed every pipeline that
imports monkey_frame / enhanced_water (models, WMOs, liquid invisible).
MonkeyFrame rows are renamed fog_a..fog_d, wind_a/b, wet_a (same order and
layout), and enhanced_water's padding member _sh_c16 becomes _sh_quad.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fog_hook.wgsl: radial exponential fog fitted to the zone's 1.12 start/end
(60 % survival mid-span, closed over the last stretch so the zone end
holds), optional height fog, end-fog colour shift, sun-fog lobe; interior
WMO spans stay classic; the WDL hull pair takes the far colour.
lighting/fog_model.rs fills the MonkeyFrame fog rows each frame (derived
from the 1.12 bands, or LightFogBand.dbc rows); fog_d.x carries the scene
fog end as the Modern flag, fog_d.zw the octahedral sun direction.
resolve.rs: Modern stretches the fog end with farclip past 777 only.
sky.wgsl/sky.rs: the dome's low band eases into the same far colour.
Classic packs zeros and every new path branches out.
Includes the cherry-picked p0 fix 05d6b1ad (MonkeyFrame rows fog_a..).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
naga_oil refuses a composable-module identifier that naga's namer would
rewrite (a trailing digit gets a '_'), which failed every pipeline that
imports monkey_frame / enhanced_water (models, WMOs, liquid invisible).
MonkeyFrame rows are renamed fog_a..fog_d, wind_a/b, wet_a (same order and
layout), and enhanced_water's padding member _sh_c16 becomes _sh_quad.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
naga_oil refuses a composable-module identifier that naga's namer would
rewrite (a trailing digit gets a '_'), which failed every pipeline that
imports monkey_frame / enhanced_water (models, WMOs, liquid invisible).
MonkeyFrame rows are renamed fog_a..fog_d, wind_a/b, wet_a (same order and
layout), and enhanced_water's padding member _sh_c16 becomes _sh_quad.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Classify static alpha-tested tree and bush leaf batches, log accepted model paths, and apply gentle anchor-phased crown sway and flutter in both retained and fade-twin render paths. Keep animated doodads and tree shadows unchanged, and add wind capture instruments.
Co-Authored-By: GPT-5.6 Sol (Codex)
Author bend weight from source-mesh height in clutter UV1, preserve texture coordinates and cutout alpha, and apply WarcraftXL's two-wave gust, lean, phase, variance, and distance fade in the model vertex path. Fill the player plus seven nearest unit benders without per-frame allocation.
Co-Authored-By: GPT-5.6 Sol (Codex)
Preserve p0 fog and MonkeyFrame hooks, water's row-view ABI, and the post lane's emissive, bloom, sun-shaft, grading, cvar, and options work.
Co-Authored-By: GPT-5.6 Sol (Codex)
enhanced_water.wgsl keeps the water lane's row view of the shared light buffer (fixes the WGSL
composer failure); the p0 fog hook reads the MonkeyFrame block through water_monkey() (row 533).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One table of every WarcraftXL-derived file (Benilla file | WarcraftXL module |
Source files | What was taken), pre-filled with the enhanced-water blocks and
the swimmer bob, plus the planned ports. The standard header line
("Ported from WarcraftXL (https://github.com/WarcraftXL) by iThorgrim —
module ..., ...") is added to enhanced_water.wgsl and water_fx/bob.rs.
Linked from README, LIGHTING and WATER. WATER.md no longer says the WarcraftXL
water module is for the 1.12 client: it is a 3.3.5a client module.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`benilla::fog_hook` (fog_linear / fog_sample / apply_fog) replaces the seven
hand-rolled copies of the linear planar-eye-Z fog: terrain, wow_model,
static_gx, liquid, enhanced_water (factor form), wow_effect (scene fog; the
rain streak fade uses fog_linear) and wdl (the hull's own 0..1 yd pair).
Pure functions, values passed as arguments, same expressions in the same
order, so the classic result is bit-identical. `fog_sample` branches on
MonkeyFrame.fog_model (fog3.x) as the FOG lane's extension point, currently
returning the classic result. wow_effect gains a world_pos varying for it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 vec4 rows (256 B) after the point-light table, so no earlier offset moves
(per-frame blob 8528 -> 8784 B, size test updated). Rust side: the
`lighting::MonkeyFrame` resource any system may write, packed each frame by
`global_light::pack_monkey_frame` (which also fills time_of_day / night).
WGSL side: `benilla::monkey_frame::MonkeyFrame`, declared as `monkey` after
`points` in every WowLight mirror (terrain, wow_model, static_gx, liquid,
enhanced_water, wow_effect, wdl). All zero = no visual change. Layout in
LIGHTING.md "Invariants".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 upstream commits: the repo-wide comment rewrite, the hover highlight as the
scene ambient, M2 Mod/Mod2x batches drawing the bare texel, test and contribution
changes. Conflicts were comment-vs-code in 36 files; where upstream changed only
comments our code was kept, and wow_model.wgsl carries both our lighting lanes
and upstream's new unlit/Mod/Mod2x paths.
Follow-ups folded in:
- our nine Advanced Graphics / water / fog options tests take upstream's
wow_data_or_skip! guard
- PostUpdate ambiguity ceiling re-measured under upstream's new census: 466,
with the per-family breakdown in the comment
- LIGHTING.md: new upstream base
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Water (Enhanced/High; Classic stays byte-identical to upstream):
- the enhanced water now lives in its own WGSL library, benilla::enhanced_water
(enhanced_water.wgsl), with its own bindings 103-106; upstream liquid.wgsl
keeps three small hooks only
- depth look: per-channel extinction over the real path through the water,
refraction of an opaque-colour copy bent by the waves (samples landing on
anything in front of the water are refused via the scene depth), caustic
web on sunlit shallow beds
- High: screen-space reflection of the scenery (bisected march against the
scene depth)
- the module fogs its own surface terms only (the refracted/reflected scene is
already fogged); depth+colour copies run both-or-neither
- credits: portions derived from WarcraftXL wxl-experimental-water by
iThorgrim, used with permission (WATER.md)
Volumetric fog (Advanced Graphics -> Volumetric Fog: Off/Low/High, cvar
volumetricFog, env WOW_VOLFOG): own fullscreen pass after the main pass,
near-field haze converging on the zone fog colour, denser at dawn and in
weather, faint indoors, plus sun/moon light shafts from the shadow map.
Tests: addon-harness oracle fixtures no longer require unix symlinks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Water (Enhanced/High only; Classic stays byte-identical to upstream):
- scene depth resolved after the main opaque pass and bound to liquids
(liquid/scene_depth.rs, water_depth.rs)
- procedural multi-band waves with analytic normals; long ocean swell moves
vertices, mirrored on the CPU (liquid/waves.rs)
- separate ocean and inland profiles; depth-driven colour and soft edge
- Fresnel sky reflection, sun path, moon path, point-light glints
- beach surf driven by the shore wave phase: continuous front, dissolving
lace, swash sheet; only where the authored sea bed is shallow, so sunken
objects never foam; thin bed clutter (grass, reeds) ignored for contact foam
- swimmers: wake foam, treading rings, visual-only bob with the swell
- river flow effect tried and removed at the owner's request
Lava: magma surfaces emit warm point lights through the lighting module
(lighting/lava_light.rs, lavaLightGain).
Options: Water Quality + Lava Glow rows (EN, RU strings prepared).
Docs: WATER.md. Credits: design reference WarcraftXL wxl-experimental-water,
author iThorgrim (reuse permitted with attribution).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #41: the comments of `benilla-assets`, Rust and WGSL, rewritten to the rule in `docs/METHOD.md`: what the code does and the reference fact behind it, in a line. 3,872 comment lines become 1,568.
- The citations that were only a private record number go first, mechanically, each edit shown to be a pure removal.
- The rewrite corrects the comments that stated wrong facts: the alpha-key cutoff now cites the reference's per-blend-mode table (`0x85ad20`), the texture-filter note names the subsystems that ignore the global setting, a test doc said an exhausted variation roll returns the last variation (it returns the first), and about twenty more found on the way (renamed or deleted items, a shader flag the doc misread, docs sitting on the wrong function). "Deviation:" now marks only a choice with a reason; an unbuilt behaviour says so plainly.
- Verified: every file strips to identical code, and `cargo fmt --check` is clean. A second reader compared every file old against new, restored the facts the rewrite had dropped, and checked each new citation against the reference.
String literals are untouched; they are #92.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comments that named a chat reporter, cited a chat channel or message id, or quoted a report word for word now state the symptom in their own words. The test fixtures that used real character names use invented ones.
Verified: 52 of the 56 files strip to identical code with their comments removed; the other 4 differ only in the fixture names, and with those mapped back they strip identical too. `cargo fmt --check` is clean, and the `ui_party`, `unit_frame_tests` and `capture` tests pass with the install present and no skips. Record numbers still in these comments go with the comment pass (#41).
Fixes#34🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comments that pointed into the maintainer's private reverse-engineering notes (a note by name, a
path, a section or finding id, the analysis's own name for a client function, a process word) now
carry the fact itself, cited by the reference client's address, by vmangos file and line, or as
"the reference". Nobody outside could follow those pointers.
Comment text only, plus the test-assert and log strings that carried the same pointers. No claim
changes: a comment the notes have since corrected keeps its wording here, and correcting it is
separate work.
The two reference generators, `scripts/gen-reference-globals.py` and
`scripts/gen-reference-verb-events.py`, named the private notes' layout to find their inputs. They
now take the input files as arguments (`--capture`, `--framexml`, `--names`, `--extents`,
`--disasm`). Run on the same inputs, both write the committed tables row for row; only the two
header lines that named the old environment variable change.
Checked per file:
- the code is identical: each file with its comments stripped compares equal before and after; a
changed string literal is compared under a mask that proves only literal text moved and every
literal kept its line count;
- no client address the old text cited was dropped;
- a second reviewer checked every added address against its derivation;
- a detector for the notes' names, paths, ids, function names and process words finds none left;
- `scripts/gates.sh` is green.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The 1.12 highlight is not a fixed 64/255 lift. SetHighlight samples the
scene's committed ambient (read at 0x614576-0x6145bd), and every batch
adds it to its colour before the final clamp, lit or unlit.
0xff404040 is only the fallback before a map's light loads. The
highlight now follows the time of day, zone and weather: roughly
(29, 60, 84)/255 at night to (104, 130, 154)/255 at noon, where it was
always (64, 64, 64)/255.
Unlit M2 batches in blend modes 0 to 4 now draw
texel × clamp(tint·M2Color + highlight), the unlit program's c28 + c29.
They took no highlight before. The reference holds the ambient sampled
when a highlight begins; benilla samples it live, a marked deviation.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
For blend modes 5 and 6 the reference zeroes the tint·M2Color term and
forces the primary colour to the blend identity (0x70c507/0x70c5b8),
keeping only the alpha. benilla multiplied the batch's M2Color (baked
into its vertex colours, or animated through the material tint) and the
body tint into the texel. Mod and Mod2x batches now bake no M2Color, and
the shader draws them from the bare texel; the alpha still reaches them
through the identity lerp.
Of the install's 615 Mod and Mod2x batches, four carry a non-white
M2Color and none an animated one. The Scholomance testing jars (empty,
ghoul and skeleton) lose the (0.93, 1.00, 0.54) cast on their Mod layer,
and Offhand_Naxxramas_D_01's Mod2x sheen loses its (1.00, 0.95, 0.85)
warmth.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The doc said repeat equals clamp for UVs in 0..1. Under linear
filtering a repeating sampler wraps at the edge, so terrain.wgsl insets
the alpha UVs by half a texel to clamp instead.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The pass, the blend and texenv facts with their client addresses, the
precision rules and the two marked deviations stay; history and record
numbers go. Struct field notes now match what the shader and its Rust
mirrors do, and two blocks move onto the items they describe. With
comments stripped the shader is identical.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Each header names its pass and the fixed-function state, blend and
formula it reproduces, with the client address; GPU traps, precision
rules and marked deviations stay. Bevy's own comments in the two
vendored UI shaders stay verbatim so an upgrade re-diffs cleanly. With
comments stripped every shader is identical.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- the trainer window re-derives every service's state when your money, level, spells or talents change, instead of asking the server for a second list after a purchase (2333, 2336)
- the backpack button reads the stock bag scan: with Bagnon holding the bags it stays unlit, as the reference leaves it (2332)
- three unused dev switches retire, and fifteen others are named as instruments (2335)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- the spell owns its lifecycle state: the in-flight cast, the local cancel, the cooldowns and the spell-modifier tables live in one module (2328)
- a malformed MPQ, DBC, M2 or WDT file is refused instead of crashing the client, nine read sites bounded
- a test that needs the install or the addon corpus fails instead of skipping when the data is there; the Bagnon render suite runs again (2329)
- the dev crash injector is armed on every platform, and no instrument writes a path relative to the working directory
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- PlayMusic and StopMusic are in, one engine verb with a NULL arm as the reference has it: the track loops on the Music slider, the zone music fades out under it over 4 s and comes back 6 s after a stop (2309)
- a PlayMusic whose file does not open leaves the zone track alone, and the server-pushed music slot is named — three fades the reference keeps apart that our one slot folds together, the next move (2315)
- an addon's own sound file plays: every by-path asset read walks the patch chain, then the loose AddOns folder — the rule art and fonts already had, now one function that audio shares
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Advanced Graphics page: Lighting Quality preset (Off/Low/Medium/High/Custom, one const table,
Off = the original client's look), shadow rows moved from Graphics, Shadow Resolution, Moon
Shadows, interior/torch/fire/spell/night rows; EN+RU strings; works in player builds.
- Moon shadows: the single shadow rig re-aims at the moon at night (MoonShadowStrength 0.35);
attenuates only the night sky term, never point lights; covers terrain, WMO exteriors, models
and retained doodads; stateful hand-over for clock jumps; blob gated on a built silhouette;
zero cost at strength 0. Signed fog_params.z carries +sun / -moon*strength.
- Area spell lights: SpellLightMode::Area for Flamestrike, Rain of Fire, Consecration, Flare,
Explosive Trap (school-based where the model says nothing); Blizzard/Hurricane/Volley/frost
traps stay dark; repeating impacts deduped; benilla-extract spellvis prints the area block.
1121 world+formats tests; 8/8 WGSL probes; UI and world smoke scenes clean.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Ports the lighting settings into upstream's single settings registry and the lighting plugins
into game_plugins.rs. 1108 world+formats tests green; world scenes (inn, Northshire dusk,
Stormwind) render clean.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- the character-create and main-menu backdrop runs its material animation: the clouds drift on their 20, 30 and 40 second loops, which were seeded once and never sampled (2300)
- Arathi Basin and Alterac Valley are entered and censused beside Warsong Gulch, the flag is picked up, and a match runs to its end (2296)
- the animation variation roll is one clock-seeded stream, as the reference's C runtime is, not four streams seeded 0 (2299, 2301)
- a cancelled channel never turns the bar red and a finished one closes on the bar's own clock, now pinned by tests that drive the real packet sequence (2284)
- the field watch fires one edge per moved descriptor dword, from the merge that holds both sides (2297)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- a panic writes benilla-config/Diagnostics/crash-<time>.txt with the build id, the location, a backtrace and the last 200 log lines, and names the file as its last line, so a bug report can attach it (2266)
- every wire-count allocation hint is capped and the compressed update object reads through the cursor, so a malformed packet can no longer ask for gigabytes (2266)
- the 23 in-world run conditions are one set, the 45 probe variables one registry, the install-gated tests say when they skip, and every gate is timed (2266)
- one workspace-level lint allowance replaces 413 per-site attributes, and the decision corpus gets a lint in the gate (2266)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- a quest objective that carries both a creature and an item is two lines in the quest log, as the reference's four passes enumerate it: Graverobbers shows its Embalming Ichor (2249)
- the quest log's detail follows the live selection inside a frame, so a quest addon's log walk reads the right quest; Questie no longer files a chain quest under its shortest sibling (2247)
- a UI tint change is not a material change: a run's colour rides the batch's instance tag, so the PlayerFrame glow no longer re-prepares a material every frame (2245)
- the workspace lints clean on rustc 1.98: constant-size chunks become as_chunks, one slice fill, two unused globs
- WOW_HOVER_PROBE aims the pick in a headless run, and the inspect card names the tooltip's ladder stage (2248, 2250)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Interiors
- Daylight fixtures (lighting/daylight.rs): PORTAL/APERTURE/BOUNDARY seeds calibrated so the
room law at a door equals the sunlit reference; BLEED fixtures at interior↔interior portals
carry 0.6× the brighter side; interiorDaylight default 0 (daylight only through doors/windows).
- Darkness gains: nightGain 0.45, interiorGain 0.5 (Dim preset), interiorAmbient 0.015, fill 0.08.
- Enclosed day floor + shell candle add + TRANS night floor (capped 1.5× room, sun-gated).
- interiorBakeFloor 0.12: a per-fragment floor from the authored MOCV so fixture-starved rooms
(the Lion's Pride vestibule, 2 % of tex before) are never black; packed in sh_c16.w's fraction.
- TRANS blend continuity: smooth-max replaces the per-channel max whose crossing loci drew a
hard diagonal across the vestibule floor by day.
- Debug panel "Lighting & shadows" (Ctrl+Shift+D) with sliders for every lighting cvar + presets.
Torch cube-map shadows
- Owner exclusion (LightOwner placement/instance + flame-in-bounds) — the swinging lantern.
- torchShadowStrength 0.7 shadow floor (packed with soft into TorchTable.count.y), PCSS-lite
contact hardening (raw depth blocker search), interiorShadowSoft 1.5.
- Moving fixtures (carried lights) re-render every frame (cap 2) instead of publishing a stale map.
- Normal offset on the WMO surface lane (interior + exterior) — the imp's boxy/moiré pool.
Spell and firework lights (benilla-formats fire_light.rs spell route)
- Fire / Holy / Fel effects emit a short-lived point light (kits, missiles, impacts, firework
GO shells); frost/nature/arcane/shadow vetoed by name; lifecycle envelope; cap 24;
WOW_SPELL_LIGHT=0 kill switch.
Exterior point lights
- ≤3-nearest per draw unit → 8 (8-bit ranks, table cap 255), ranked by distance to the chunk's
box; cube occlusion only for ranks 0..2. Removes the chunk-edge "scars" at the Darkmoon Faire
(15 synthesised fixtures in one chunk's reach) and the lit-bench-over-dark-ground disagreement.
Tooling: benilla-extract wmolights --verts <group>; missing-model placements retire instead of
pinning the loading screen.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- a creature spawning or coming into range in water no longer punches a body-shaped hole in the surface at the start of its fade-in: a model crossing its water plane draws on both sides, each half clipped at the waterline (2188)
- the same split covers your own body on login while swimming, stealth and ghost form in the water; Crystal Lake's murlocs streaming in were the scene that showed it (2188)
- helms, shoulders, weapons and hung spell kits clip at their wearer's waterline too, so the fade no longer looks wrong whenever the surface crosses the armour (2190)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>