Commit Graph
1579 Commits
Author SHA1 Message Date
Sam SungandClaude Opus 5.5 a7e6fc2301 Comments and strings: the passes' leftovers, and a region's template matched as one name (#391)
The comment and string passes' last leftovers, and one lookup made to match the reference.

**Comments that stated a wrong reference fact**, now stating the right one:
- A cast failure clears the GCD, and a failed cooldown-on-event spell also drops its parked record (`0x6e73cc`).
- `SetUnit` is `0x505d70`; `0x476cb0` is the component clone it reaches.
- Interior sound follows the character, where the listener sits, not the camera.
- Template inheritance re-runs `LoadXML` on the one object against each template (`0x76985c`), and reads `name` and `id` from the instance alone (`0x769770`).
- On the ghost-to-alive edge the reference clears its corpse cache and sends nothing (`0x5ee990`, `0x491f50`).
- The name cache has no high-bit miss. An empty-name answer evicts the record in the reference (`0x55f6f0`).
- The combat-log deferred queue (`0xc4e208`) waits only on an item name. A unit name never waits.
- A flying spline's segments are paced by curve length (`0x454320`, `0x453760`), not by chord length.
- A stop within 3 yd of its stop point keeps the arrow nocked (`0x6019e4`).
- A missile's sound id is at `CMissile+0x40`.
- A nil or unresolved `AssistUnit` token is a gap against `0xb8` ERR_GENERIC_NO_TARGET, not a deviation.

**Strings:**
- Test, log and tool messages lose leftover history wording and placeholder labels.
- The extractor's scan summaries describe the current tint and sequence-clock paths.
- The smoke script's failure text carries no private numbers.

**Line continuations:** twelve log, panic and assert strings get back the `\` continuations they had lost. Each printed a run of spaces mid-message. Fixes #106.

**One lookup:** a region's `inherits=` is looked up as one verbatim name, matched case-insensitively (`0x6ee6f0`, `_strnicmp` at `0x6ee747`), as `framexml::expand` already did for frames. The gate before it split on commas and matched case-sensitively, so a texture or font string whose `inherits=` spelled its template in another case never received the template. `a_region_takes_a_mis_cased_template` fails before this change and passes after.

**Tests:** the quest tests stop loading three FrameXML files that no quest file uses.

**In game:** nothing changes for the stock UI. Log lines read as one sentence, and an addon texture that names its template in another case now gets it.

Verified with `scripts/check.sh` on the changed crates, plus the loader and quest tests with the install present.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 08:57:47 +07:00
pkuzicandClaude Opus 5.5 ac9a1ef390 MONKEY (reviewfix-a): zone grading visible in captures; follows the rendered clock
Found by the first runtime capture of the grade: a capture has no avatar, so
CurrentArea stayed None and no zone was ever graded; and the day/night weight
read WorldTime (the server clock, noon offline), so a manual/capture night
graded with the day LUT. Adds CaptureCameraArea (area under the camera, only
under WOW_CAPTURE, never read by the area authority) and grades by the
rendered GameClock minute. LIGHTING.md notes the preset/capture changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 02:25:15 +01:00
pkuzicandClaude Opus 5.5 7661b7d372 MONKEY (reviewfix-a): zone grading visible in captures; follows the rendered clock
Found by the first runtime capture of the grade: a capture has no avatar, so
CurrentArea stayed None and no zone was ever graded; and the day/night weight
read WorldTime (the server clock, noon offline), so a manual/capture night
graded with the day LUT. Adds CaptureCameraArea (area under the camera, only
under WOW_CAPTURE, never read by the area authority) and grades by the
rendered GameClock minute. LIGHTING.md notes the preset/capture changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 02:25:15 +01:00
Sam SungandClaude Opus 5.5 4510a9b284 Quests print their chat lines: accepted, completed, experience, money and items (#390)
Quests printed no chat lines: no "Quest accepted: …", "… completed.", "Experience gained: …" or "Received …". Nothing raised the reference's quest messages.

Fixes #69.

- **Accept** (`0x5ddd80`): a quest-log slot watcher raises "Quest accepted: <title>" when a slot gains a quest, or keeps its quest and loses the fail bit (`0x5dde17`-`0x5dde34`); a slot that swaps quests says nothing. An uncached quest prints when its record arrives. The QUESTADDED sound now comes from that message row.
- **Turn-in** (`0x5dc400`), in order: "<title> completed." only when the quest has no follow-up in its chain; "Experience gained: N." when the XP is non-zero; "Received …" with the paid coins from the COPPER/SILVER/GOLD globals; then one "Received item: [link]." per fixed reward, and one for the chosen reward, which the client remembers from `GetQuestReward` (`0x50161a`) because the packet does not carry it (vmangos `Player.cpp:14500`).
- Every line comes from the install's strings. A line whose quest or item record is still in flight waits for it; an unknown record is dropped.
- The money line joins only the paid coins ("1 Gold, 5 Copper"). The reference's separator test prints "1 Gold, , 5 Copper" when the middle coin is zero, a quirk not copied.

Tests: six new tests across the quest log, the turn-in handler and the line queue; `scripts/check.sh` is green.

To see it: accept a quest from any giver and read "Quest accepted: <title>"; turn it in and read the completed, experience, money and item lines.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 07:42:53 +07:00
Sam SungandClaude Opus 5.5 3e4792f886 Quests print their chat lines: accepted, completed, experience, money and items (#390)
Quests printed no chat lines: no "Quest accepted: …", "… completed.", "Experience gained: …" or "Received …". Nothing raised the reference's quest messages.

Fixes #69.

- **Accept** (`0x5ddd80`): a quest-log slot watcher raises "Quest accepted: <title>" when a slot gains a quest, or keeps its quest and loses the fail bit (`0x5dde17`-`0x5dde34`); a slot that swaps quests says nothing. An uncached quest prints when its record arrives. The QUESTADDED sound now comes from that message row.
- **Turn-in** (`0x5dc400`), in order: "<title> completed." only when the quest has no follow-up in its chain; "Experience gained: N." when the XP is non-zero; "Received …" with the paid coins from the COPPER/SILVER/GOLD globals; then one "Received item: [link]." per fixed reward, and one for the chosen reward, which the client remembers from `GetQuestReward` (`0x50161a`) because the packet does not carry it (vmangos `Player.cpp:14500`).
- Every line comes from the install's strings. A line whose quest or item record is still in flight waits for it; an unknown record is dropped.
- The money line joins only the paid coins ("1 Gold, 5 Copper"). The reference's separator test prints "1 Gold, , 5 Copper" when the middle coin is zero, a quirk not copied.

Tests: six new tests across the quest log, the turn-in handler and the line queue; `scripts/check.sh` is green.

To see it: accept a quest from any giver and read "Quest accepted: <title>"; turn it in and read the completed, experience, money and item lines.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 07:42:53 +07:00
Sam SungandClaude Opus 5.5 622f8ce525 A ghost is dead to the attack check, the action bar, the cast ladder and the cursor (#389)
A ghost could swing, got a lit action bar, a sword cursor over enemies, and an Attack button that did not refuse. benilla tested death as health 0 only, and a released ghost has health 1.

Fixes #246. Fixes #248. Fixes #250. Fixes #251.

- **One predicate** (`0x605f30`): dead or ghost is health 0 or below, or a player with the `PLAYER_FLAGS` ghost bit `0x10`. It lives on the object fields and every site uses it: the attack check (`0x612e10`), the usable walk's first check (`0x6e3dad`), summon, trade and the death screen.
- **#248:** the cast ladder refuses a dead or ghost caster with `SPELL_FAILED_CASTER_DEAD` and sends nothing, unless the spell's `Attributes` has `0x800000` (`0x6e4c49`-`0x6e4c68`); the Attack action button takes it first ("You are dead").
- **#251:** the sword cursor also needs a live, unmounted, unpacified player in control (`0x482648`-`0x4826cb`). A right-click now decides attack from the reference's CanInteract/CanAttack fork (`0x60c18c`-`0x60c247`), not from the cursor kind, so a ghost right-clicking a hostile NPC with a service flag selects it and does nothing else, instead of opening its window.

Tests: seven tests, each with a ghost at health 1; `scripts/check.sh` is green.

To see it: release spirit. The action bar stays grey; Attack Target reads "Can't attack while dead."; hovering a hostile mob shows the pointer; right-clicking a hostile vendor selects it and opens nothing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 07:23:28 +07:00
Sam SungandClaude Opus 5.5 b8a32a06e7 A ghost is dead to the attack check, the action bar, the cast ladder and the cursor (#389)
A ghost could swing, got a lit action bar, a sword cursor over enemies, and an Attack button that did not refuse. benilla tested death as health 0 only, and a released ghost has health 1.

Fixes #246. Fixes #248. Fixes #250. Fixes #251.

- **One predicate** (`0x605f30`): dead or ghost is health 0 or below, or a player with the `PLAYER_FLAGS` ghost bit `0x10`. It lives on the object fields and every site uses it: the attack check (`0x612e10`), the usable walk's first check (`0x6e3dad`), summon, trade and the death screen.
- **#248:** the cast ladder refuses a dead or ghost caster with `SPELL_FAILED_CASTER_DEAD` and sends nothing, unless the spell's `Attributes` has `0x800000` (`0x6e4c49`-`0x6e4c68`); the Attack action button takes it first ("You are dead").
- **#251:** the sword cursor also needs a live, unmounted, unpacified player in control (`0x482648`-`0x4826cb`). A right-click now decides attack from the reference's CanInteract/CanAttack fork (`0x60c18c`-`0x60c247`), not from the cursor kind, so a ghost right-clicking a hostile NPC with a service flag selects it and does nothing else, instead of opening its window.

Tests: seven tests, each with a ghost at health 1; `scripts/check.sh` is green.

To see it: release spirit. The action bar stays grey; Attack Target reads "Can't attack while dead."; hovering a hostile mob shows the pointer; right-clicking a hostile vendor selects it and opens nothing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 07:23:28 +07:00
Sam SungandClaude Opus 5.5 632ab88572 Party and raid roster lines and the join chime follow the reference's two stores (#388)
Party and raid join and leave lines, and the join chime, follow the reference: it composes them from two stores, the party slots and the raid roster, where benilla ran one ungated diff over the whole member list.

Fixes #264. Fixes #268. Fixes #269. Fixes #270.

- **Party lines** (`0x5e6a40`): join lines print only onto a group already held (an occupied slot, `0x5e6afb`, or a raid roster, `0x5e6b29`); forming a group as leader prints one line, for the member the list names last (`0x5e6c94`-`0x5e6cc1`); a raid list prints no party member lines (`0x5e6c01`, `0x5e6cd1`).
- **Raid lines** (`0x4ba5f0`, `0x4ba550`): arrivals print only onto a held roster (`0x4ba725`), departures from `0x4ba7a0`; "You have joined a raid group" when none was held (`0x4ba83a`), and "You have left the raid group" when a non-raid list ends a held raid (`0x4ba55f`).
- **Ending the group**: the leave acknowledgement, `SMSG_GROUP_UNINVITE` and `SMSG_GROUP_DESTROYED` empty the party slots first (`0x4e84a0`), so the empty list that follows names nobody.
- **The chime** (`igPlayerInviteAccept`): queued when a member is seated into no held group (`0x5e6dc6`) or joins a held party (`0x5e6c24`); a raid arrival plays nothing.

Tests: eight new tests fail on the old composition and pass now; `scripts/check.sh` is green.

To see it (two or more characters): accept a party invite and hear the chime, with no "joins the party." lines for members already there; `/leave` prints only "You leave the group."; convert a party of four to a raid and party members see only "You have joined a raid group".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 06:56:26 +07:00
Sam SungandClaude Opus 5.5 459a9a5697 Party and raid roster lines and the join chime follow the reference's two stores (#388)
Party and raid join and leave lines, and the join chime, follow the reference: it composes them from two stores, the party slots and the raid roster, where benilla ran one ungated diff over the whole member list.

Fixes #264. Fixes #268. Fixes #269. Fixes #270.

- **Party lines** (`0x5e6a40`): join lines print only onto a group already held (an occupied slot, `0x5e6afb`, or a raid roster, `0x5e6b29`); forming a group as leader prints one line, for the member the list names last (`0x5e6c94`-`0x5e6cc1`); a raid list prints no party member lines (`0x5e6c01`, `0x5e6cd1`).
- **Raid lines** (`0x4ba5f0`, `0x4ba550`): arrivals print only onto a held roster (`0x4ba725`), departures from `0x4ba7a0`; "You have joined a raid group" when none was held (`0x4ba83a`), and "You have left the raid group" when a non-raid list ends a held raid (`0x4ba55f`).
- **Ending the group**: the leave acknowledgement, `SMSG_GROUP_UNINVITE` and `SMSG_GROUP_DESTROYED` empty the party slots first (`0x4e84a0`), so the empty list that follows names nobody.
- **The chime** (`igPlayerInviteAccept`): queued when a member is seated into no held group (`0x5e6dc6`) or joins a held party (`0x5e6c24`); a raid arrival plays nothing.

Tests: eight new tests fail on the old composition and pass now; `scripts/check.sh` is green.

To see it (two or more characters): accept a party invite and hear the chime, with no "joins the party." lines for members already there; `/leave` prints only "You leave the group."; convert a party of four to a raid and party members see only "You have joined a raid group".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 06:56:26 +07:00
Sam SungandClaude Opus 5.5 1f77007977 Floating combat text words each outcome as the reference's emitter does (#387)
Floating combat text picks the wrong outcome word for mitigated hits, partly mitigated spell hits, damage-over-time ticks and one spell-miss code. Each now follows the reference's own emitter.

Fixes #42. Fixes #43. Fixes #89. Fixes #349.

- **Melee partials (#42):** tested resist (`0x629efd`), then block (`0x629f15`), then absorb (`0x629f30`); benilla tested absorb first.
- **Direct spell hits (#43):** a landed hit words its first partial as `0x62cd80` does: `SPELL_RESISTED`, else `SPELL_BLOCKED` (carrying the blocked amount), else `SPELL_ABSORBED`, else `SPELL_DAMAGE`; a zero-damage hit tests absorbed, blocked, resisted. The wider cause: benilla applied the direct words to every `SMSG_SPELLNONMELEEDAMAGELOG`. The reference's handler (`0x5e85e0`) sends split damage to `SPLIT_DAMAGE` (`0x62de60`) and a periodic log, gated on `CombatLogPeriodicSpells` (`0x62d9ae`), to the periodic emitter; the text now routes the same three ways.
- **Damage ticks (#89):** a landed tick words `RESIST`, else `ABSORB`, else `DAMAGE` (`0x628100`: `0x628354`, `0x62836c`, `0x62837f`); a zero-damage tick words `SPELL_ABSORBED`, else `SPELL_RESISTED`.
- **Spell-miss codes (#349):** the jump table at `0x62be10` sends code 10, 1 and 12 and up to `SPELL_MISSED` (`0x62bdc3`), and code 0 fires nothing.

Tests: six tests in `combat_log/text.rs`; the two over existing functions fail on the old code, and the new routing is covered by three more. `scripts/check.sh` is green.

To see it (Floating Combat Text on, "Show Damage Reduction" on): a damage-over-time tick now scrolls as damage, "-N", and a partly resisted tick as "N (M resisted)"; a partly resisted spell hit reads "300 (100 resisted)" instead of "-300".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 06:45:22 +07:00
Sam SungandClaude Opus 5.5 7a795659d9 Floating combat text words each outcome as the reference's emitter does (#387)
Floating combat text picks the wrong outcome word for mitigated hits, partly mitigated spell hits, damage-over-time ticks and one spell-miss code. Each now follows the reference's own emitter.

Fixes #42. Fixes #43. Fixes #89. Fixes #349.

- **Melee partials (#42):** tested resist (`0x629efd`), then block (`0x629f15`), then absorb (`0x629f30`); benilla tested absorb first.
- **Direct spell hits (#43):** a landed hit words its first partial as `0x62cd80` does: `SPELL_RESISTED`, else `SPELL_BLOCKED` (carrying the blocked amount), else `SPELL_ABSORBED`, else `SPELL_DAMAGE`; a zero-damage hit tests absorbed, blocked, resisted. The wider cause: benilla applied the direct words to every `SMSG_SPELLNONMELEEDAMAGELOG`. The reference's handler (`0x5e85e0`) sends split damage to `SPLIT_DAMAGE` (`0x62de60`) and a periodic log, gated on `CombatLogPeriodicSpells` (`0x62d9ae`), to the periodic emitter; the text now routes the same three ways.
- **Damage ticks (#89):** a landed tick words `RESIST`, else `ABSORB`, else `DAMAGE` (`0x628100`: `0x628354`, `0x62836c`, `0x62837f`); a zero-damage tick words `SPELL_ABSORBED`, else `SPELL_RESISTED`.
- **Spell-miss codes (#349):** the jump table at `0x62be10` sends code 10, 1 and 12 and up to `SPELL_MISSED` (`0x62bdc3`), and code 0 fires nothing.

Tests: six tests in `combat_log/text.rs`; the two over existing functions fail on the old code, and the new routing is covered by three more. `scripts/check.sh` is green.

To see it (Floating Combat Text on, "Show Damage Reduction" on): a damage-over-time tick now scrolls as damage, "-N", and a partly resisted tick as "N (M resisted)"; a partly resisted spell hit reads "300 (100 resisted)" instead of "-300".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 06:45:22 +07:00
pkuzicandClaude Opus 5.5 ddc001c849 MONKEY (reviewfix-a): cloud-review fixes — cvars, capture fixture, wind pin, post perf
- farclip High seed 777 declared in SEEDED_DEVIATIONS (owner: High is the
  default); test walks the seeded column against every reference row (#6)
- WOW_CAPTURE_CVARS=<file> replaces BENILLA_HOME as the capture cvar fixture (#13)
- label derivation skips session-owned rows, so an env lever no longer
  persists graphicsQuality/lightingQuality = Custom (#14)
- /console help strings: restored line continuations + a test (#15)
- WOW_FOLIAGE_WIND read only in a dev build under WOW_CAPTURE (#16)
- fog node skipped at volumetricFog 0 with no lamp; fog and SSAO uniforms
  persistent per view, written in prepare (#17)
- tests: every governed graphics row through its observer; OptionsFrame
  farclip slider tied to view::FARCLIP_RANGE

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 00:42:27 +01:00
pkuzicandClaude Opus 5.5 b2b5ef7539 MONKEY (reviewfix-a): cloud-review fixes — cvars, capture fixture, wind pin, post perf
- farclip High seed 777 declared in SEEDED_DEVIATIONS (owner: High is the
  default); test walks the seeded column against every reference row (#6)
- WOW_CAPTURE_CVARS=<file> replaces BENILLA_HOME as the capture cvar fixture (#13)
- label derivation skips session-owned rows, so an env lever no longer
  persists graphicsQuality/lightingQuality = Custom (#14)
- /console help strings: restored line continuations + a test (#15)
- WOW_FOLIAGE_WIND read only in a dev build under WOW_CAPTURE (#16)
- fog node skipped at volumetricFog 0 with no lamp; fog and SSAO uniforms
  persistent per view, written in prepare (#17)
- tests: every governed graphics row through its observer; OptionsFrame
  farclip slider tied to view::FARCLIP_RANGE

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 00:42:27 +01:00
Sam SungandClaude Opus 5.5 3df3303d0e Every loot close deselects a dead unit, and a selection change closes the loot on the old target (#379)
Closing a loot window left the looted corpse targeted, and changing target left the old corpse's loot window open.

Fixes #238. Fixes #71.

- **One close routine** (`0x48f200`): every close (CloseLoot, the last row or the coins taken, the server's release response, stepping away) runs the same routine, then deselects the source when it is a unit or player with health 0 or below (`0x48f34f`-`0x48f369`). Before, only the movement close asked, and it keyed on the loot type rather than health. A skinned corpse now loses the selection; a live pick-pocket target keeps it.
- **A selection change closes the old target's loot** (`0x4936cc` → `0x493910` → `0x493974`): Tab, Esc, a click-off or the target's death sends the release before the new selection. A chest window survives a Tab.
- Declaring the loot drain's order against the target update also clears about ninety older undeclared schedule pairs, so the ceiling follows down.

Tests: four new or extended tests fail with the behaviours stubbed out and pass now; `scripts/check.sh` is green.

To see it: kill a mob, loot it and close the window: the target frame clears. Loot a corpse and press Tab with the window open: the window closes and the next mob is targeted.

One wire difference stays and is documented at the seam: when Tab closes a window on a dead target, the reference also sends a `CMSG_SET_SELECTION` of 0 before the new selection (`0x493a2a`). The server ends in the same state.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 06:15:14 +07:00
Sam SungandClaude Opus 5.5 43a2acda1d Every loot close deselects a dead unit, and a selection change closes the loot on the old target (#379)
Closing a loot window left the looted corpse targeted, and changing target left the old corpse's loot window open.

Fixes #238. Fixes #71.

- **One close routine** (`0x48f200`): every close (CloseLoot, the last row or the coins taken, the server's release response, stepping away) runs the same routine, then deselects the source when it is a unit or player with health 0 or below (`0x48f34f`-`0x48f369`). Before, only the movement close asked, and it keyed on the loot type rather than health. A skinned corpse now loses the selection; a live pick-pocket target keeps it.
- **A selection change closes the old target's loot** (`0x4936cc` → `0x493910` → `0x493974`): Tab, Esc, a click-off or the target's death sends the release before the new selection. A chest window survives a Tab.
- Declaring the loot drain's order against the target update also clears about ninety older undeclared schedule pairs, so the ceiling follows down.

Tests: four new or extended tests fail with the behaviours stubbed out and pass now; `scripts/check.sh` is green.

To see it: kill a mob, loot it and close the window: the target frame clears. Loot a corpse and press Tab with the window open: the window closes and the next mob is targeted.

One wire difference stays and is documented at the seam: when Tab closes a window on a dead target, the reference also sends a `CMSG_SET_SELECTION` of 0 before the new selection (`0x493a2a`). The server ends in the same state.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 06:15:14 +07:00
pkuzicandGPT-5.6 Sol (Codex) 62f1476e4f MONKEY (reviewfix): pin shared shader buffer literals
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:43:56 +01:00
pkuzicandGPT-5.6 Sol (Codex) 8c894bf9f7 MONKEY (reviewfix): pin shared shader buffer literals
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:43:56 +01:00
pkuzicandGPT-5.6 Sol (Codex) 554d3a5eb9 MONKEY (reviewfix): shade water in its source wave domain
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:37:11 +01:00
pkuzicandGPT-5.6 Sol (Codex) 405e9b534f MONKEY (reviewfix): shade water in its source wave domain
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:37:11 +01:00
pkuzicandGPT-5.6 Sol (Codex) c59d42e708 MONKEY (reviewfix): stitch displaced water LOD edges
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:36:16 +01:00
pkuzicandGPT-5.6 Sol (Codex) cc42b2f9fb MONKEY (reviewfix): stitch displaced water LOD edges
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:36:16 +01:00
pkuzicandGPT-5.6 Sol (Codex) 32b3880cc1 MONKEY (reviewfix): separate skybox sort bands
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:32:00 +01:00
pkuzicandGPT-5.6 Sol (Codex) 6107bdc7a4 MONKEY (reviewfix): separate skybox sort bands
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:32:00 +01:00
pkuzicandGPT-5.6 Sol (Codex) 82240e8e76 MONKEY (reviewfix): isolate animated sky materials
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:28:28 +01:00
pkuzicandGPT-5.6 Sol (Codex) 9a88ea2de5 MONKEY (reviewfix): isolate animated sky materials
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:28:28 +01:00
pkuzicandClaude Opus 5.5 4db69f6b53 MONKEY (reviewfix-a): SSAO normal cannot go NaN on isolated pixels against the sky
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:27:18 +01:00
pkuzicandClaude Opus 5.5 40238ad3e8 MONKEY (reviewfix-a): SSAO normal cannot go NaN on isolated pixels against the sky
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:27:18 +01:00
pkuzicandClaude Opus 5.5 b50a66fefb MONKEY (reviewfix-a): WarcraftXL credits — standard header on grading, sky_fx row, layer.rs module credit
The grading port carries the same attribution header as the other WarcraftXL
ports (used with the author's permission, attribution required).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:27:02 +01:00
pkuzicandClaude Opus 5.5 c5711fce22 MONKEY (reviewfix-a): WarcraftXL credits — standard header on grading, sky_fx row, layer.rs module credit
The grading port carries the same attribution header as the other WarcraftXL
ports (used with the author's permission, attribution required).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:27:02 +01:00
pkuzicandGPT-5.6 Sol (Codex) 488d451500 MONKEY (reviewfix): make skybox path lookup deterministic
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:26:09 +01:00
pkuzicandGPT-5.6 Sol (Codex) 4b692177ae MONKEY (reviewfix): make skybox path lookup deterministic
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:26:09 +01:00
pkuzicandClaude Opus 5.5 b234b51dc9 MONKEY (reviewfix-a): merge graphics-programme-polish
Conflicts: sun_shafts prepare keeps the integration warm loop on the polish
format-only blur key (mask pipelines are queued at init); sky_fx keeps the
clock ordered before LightingConsumeSet plus the polish clock buffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:25:28 +01:00
pkuzicandClaude Opus 5.5 0d8a92ff49 MONKEY (reviewfix-a): merge graphics-programme-polish
Conflicts: sun_shafts prepare keeps the integration warm loop on the polish
format-only blur key (mask pipelines are queued at init); sky_fx keeps the
clock ordered before LightingConsumeSet plus the polish clock buffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 23:25:28 +01:00
pkuzicandGPT-5.6 Sol (Codex) df78c4758e MONKEY (reviewfix): preserve missing stage-one UV transforms
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:23:43 +01:00
pkuzicandGPT-5.6 Sol (Codex) 0eb9e1c022 MONKEY (reviewfix): preserve missing stage-one UV transforms
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:23:43 +01:00
pkuzicandGPT-5.6 Sol (Codex) 132b1d07c4 MONKEY (reviewfix): document Classic skybox fidelity
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:22:02 +01:00
pkuzicandGPT-5.6 Sol (Codex) 51d7de6a4e MONKEY (reviewfix): document Classic skybox fidelity
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:22:02 +01:00
pkuzicandGPT-5.6 Sol (Codex) 33061bd94b MONKEY (reviewfix): keep skybox clocks precise
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:21:11 +01:00
pkuzicandGPT-5.6 Sol (Codex) e754af5db8 MONKEY (reviewfix): keep skybox clocks precise
Co-Authored-By: GPT-5.6 Sol (Codex)
2026-09-25 23:21:11 +01:00
pkuzicandClaude Opus 5.5 f7715c80af MONKEY (followups): reduce SSAO grain on alpha-tested foliage
STAGE_AO flags a two-sided depth spike (the smaller one-sided step two pixels out, capped by the
second difference: ~0 on planes, grazing planes, silhouettes and contact creases) and stores the
smoothness in alpha. STAGE_BLUR turns the spike density of its 4x4 window into a foliage mask,
widens the depth tolerance there (up to 11x) and scales the occlusion by 1 - 0.4 * mask. Smooth
windows are unchanged. WOW_AO_DEBUG=5 shows the mask. LIGHTING.md documents this and the two
earlier followups fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 22:02:01 +01:00
pkuzicandClaude Opus 5.5 8a5af68554 MONKEY (followups): reduce SSAO grain on alpha-tested foliage
STAGE_AO flags a two-sided depth spike (the smaller one-sided step two pixels out, capped by the
second difference: ~0 on planes, grazing planes, silhouettes and contact creases) and stores the
smoothness in alpha. STAGE_BLUR turns the spike density of its 4x4 window into a foliage mask,
widens the depth tolerance there (up to 11x) and scales the occlusion by 1 - 0.4 * mask. Smooth
windows are unchanged. WOW_AO_DEBUG=5 shows the mask. LIGHTING.md documents this and the two
earlier followups fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 22:02:01 +01:00
pkuzicandClaude Opus 5.5 14578ea26b MONKEY (followups): re-apply the saved presets to rows missing from config
On load, Cvars::reapply_saved_presets writes the saved graphicsQuality rung (and the saved
lightingQuality rung, else the Graphics rung's) over every governed row the file does not carry,
so a row registered after the save follows the preset instead of its registered default. Rows the
file carries and session-owned rows stay; Custom writes nothing. Tests for both ladders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:53:25 +01:00
pkuzicandClaude Opus 5.5 40ebaec012 MONKEY (followups): re-apply the saved presets to rows missing from config
On load, Cvars::reapply_saved_presets writes the saved graphicsQuality rung (and the saved
lightingQuality rung, else the Graphics rung's) over every governed row the file does not carry,
so a row registered after the save follows the preset instead of its registered default. Rows the
file carries and session-owned rows stay; Custom writes nothing. Tests for both ladders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:53:25 +01:00
pkuzicandClaude Opus 5.5 e970cedcf2 MONKEY (followups): refresh the streamed shadow cache without volumetric fog
The static world caster rebuilds only on 16 yd of camera drift. The refresh that invalidates it
when streamed geometry arrives lived in the volumetric-fog plugin and was gated on that cvar, so
with volumetricFog 0 a standing camera never picked up trees and doodads that streamed in late.
The refresh now lives in world_shadow.rs and is gated on worldShadows only (Classic unaffected).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:53:25 +01:00
pkuzicandClaude Opus 5.5 8fde660924 MONKEY (followups): refresh the streamed shadow cache without volumetric fog
The static world caster rebuilds only on 16 yd of camera drift. The refresh that invalidates it
when streamed geometry arrives lived in the volumetric-fog plugin and was gated on that cvar, so
with volumetricFog 0 a standing camera never picked up trees and doodads that streamed in late.
The refresh now lives in world_shadow.rs and is gated on worldShadows only (Classic unaffected).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 21:53:25 +01:00
Sam SungandClaude Opus 5.5 73ec78c480 SendChatMessage sends a numbered channel's name, not its number (#377)
Typing into a numbered channel (`/1 hello`, or a line under a "[2. Trade]" header) sent nothing: the channel number went to the wire as the channel's name, so the server found no channel called "2".

Fixes #222.

- `SendChatMessage` reads a CHANNEL target the way 1.12.1 does (`0x49f4d9`-`0x49f4ea`): `SStrToInt` on the text, then the by-number slot getter (`0x49be50`), and the packet carries that slot's name (`0x49f70b`). A number that names no joined slot sends nothing, before the AFK clear and the tutorial acknowledge. There is no by-name leg, so an addon that passes a channel name sends nothing, as in 1.12.1.
- The binding keeps the target as Lua's `tostring` gives it, so 2.7 reads 2 instead of rounding to 3. `LeaveChannelByName` shares the parse and the getter.
- The send drains run before the zone-channel walk, so a `/N` resolves against the roster the script read the same frame.

Test: `a_channel_send_carries_the_numbered_slots_name` runs the real drain over a slot roster. It failed before (the wire target was "2") and passes now; holes, suspended slots, names and missing targets send nothing.

To see it: two characters of one faction in the same zone, both in General. On the first, `/1 hello`: the second now sees it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 02:46:13 +07:00
Sam SungandClaude Opus 5.5 381c018cc8 SendChatMessage sends a numbered channel's name, not its number (#377)
Typing into a numbered channel (`/1 hello`, or a line under a "[2. Trade]" header) sent nothing: the channel number went to the wire as the channel's name, so the server found no channel called "2".

Fixes #222.

- `SendChatMessage` reads a CHANNEL target the way 1.12.1 does (`0x49f4d9`-`0x49f4ea`): `SStrToInt` on the text, then the by-number slot getter (`0x49be50`), and the packet carries that slot's name (`0x49f70b`). A number that names no joined slot sends nothing, before the AFK clear and the tutorial acknowledge. There is no by-name leg, so an addon that passes a channel name sends nothing, as in 1.12.1.
- The binding keeps the target as Lua's `tostring` gives it, so 2.7 reads 2 instead of rounding to 3. `LeaveChannelByName` shares the parse and the getter.
- The send drains run before the zone-channel walk, so a `/N` resolves against the roster the script read the same frame.

Test: `a_channel_send_carries_the_numbered_slots_name` runs the real drain over a slot roster. It failed before (the wire target was "2") and passes now; holes, suspended slots, names and missing targets send nothing.

To see it: two characters of one faction in the same zone, both in General. On the first, `/1 hello`: the second now sees it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 02:46:13 +07:00
Sam SungandClaude Opus 5.5 de0fa568d7 A stale useUiScale comment, and a usage line for doc-links.py (#376)
Two small fixes.

- `OptionsFrame.xml`: the comment on the missing Use UI Scale checkbox said benilla has no `useUiScale`. It is registered at "0" and never read, which is why the UI scale always applies.
- `scripts/doc-links.py`: `--help` and `-h` print the usage in the module doc instead of running the full `cargo doc` pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 02:38:27 +07:00
Sam SungandClaude Opus 5.5 bbdc23b8fc A stale useUiScale comment, and a usage line for doc-links.py (#376)
Two small fixes.

- `OptionsFrame.xml`: the comment on the missing Use UI Scale checkbox said benilla has no `useUiScale`. It is registered at "0" and never read, which is why the UI scale always applies.
- `scripts/doc-links.py`: `--help` and `-h` print the usage in the module doc instead of running the full `cargo doc` pass.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 02:38:27 +07:00
pkuzicandClaude Opus 5.5 b36848bc68 MONKEY (integration): order tick_shelter before the lighting resolve set
It reads MonkeyFrame.wetness while update_fog_model writes MonkeyFrame; the
undeclared pair put the ambiguity count one over the 5,582 ceiling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 20:31:25 +01:00