From 16077633c5bcd406bfababd27974a4b1f3fea063 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 15 Jul 2026 07:43:26 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20correct=20OD=20spec/plan=20=E2=80=94=20?= =?UTF-8?q?variance=20orientation=20per=20UB=20source,=20SpellInfo=20chang?= =?UTF-8?q?e/bonus=20semantics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../plans/2026-07-15-weapon-od-rating.md | 9 +++---- .../2026-07-15-weapon-od-rating-design.md | 24 +++++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/superpowers/plans/2026-07-15-weapon-od-rating.md b/docs/superpowers/plans/2026-07-15-weapon-od-rating.md index dfd03249..7d47f8f0 100644 --- a/docs/superpowers/plans/2026-07-15-weapon-od-rating.md +++ b/docs/superpowers/plans/2026-07-15-weapon-od-rating.md @@ -106,8 +106,9 @@ func TestOD_MeleeRetailMaxIsZero(t *testing.T) { } } -// Melee with tighter variance (0.376 = one granite tink below 0.47): -// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = round(1.00,2)=1 → OD = 71-1-71 = -1. +// Melee with tighter variance (0.376, one granite tink BETTER than the 0.47 baseline): +// varianceTinks = round(log(0.47/0.376)/log(0.8), 2) = -1.00 → OD = 71-(-1)-71 = +1. +// (Table MaxVar is the type's baseline variance; lower variance = higher OD.) func TestOD_MeleeOneTinkVariance(t *testing.T) { raw := map[string]any{ "ObjectClass": 1.0, @@ -116,8 +117,8 @@ func TestOD_MeleeOneTinkVariance(t *testing.T) { "Spells": []any{}, "ActiveSpells": []any{}, } od, ok := computeOD(raw) - if !ok || !approx(od, -1.0) { - t.Fatalf("melee OD = %v ok=%v, want -1", od, ok) + if !ok || !approx(od, 1.0) { + t.Fatalf("melee OD = %v ok=%v, want +1", od, ok) } } diff --git a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md index d9d0e14b..9d26a8fa 100644 --- a/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md +++ b/docs/superpowers/specs/2026-07-15-weapon-od-rating-design.md @@ -32,13 +32,23 @@ Raw item keys (verified present in our `item_raw_data`): - `original_json->Spells` / `ActiveSpells`: innate and active spell id arrays. **Buffed values** (GetBuffedIntValueKey / GetBuffedDoubleValueKey semantics): -value + Σ bonus(innate Spells) − Σ change(ActiveSpells), using the spell-effect -subset from UB `Dictionaries.cs`: MaxDamage — Blood Drinker VI 1616:+20, -Infected Caress 2096:+22, Incant. BD 5183/4395:+24, Minor/Major/Epic/Legendary -Blood Thirst 2598:+2/2586:+4/4661:+7/6089:+10, Prodigal BD 3688:+300 (bonus = -change for all these); ElemVsMonsters (double) — Spirit Drinker VI 3258:+.06, -Infected Spirit Caress 3259:+.07, Incant. SD 5182/4414:+.08, Minor/Major/Epic/ -Legendary Spirit Thirst 3251:+.01/3250:+.03/4670:+.05/6098:+.07. +value + Σ **bonus**(innate Spells) − Σ **change**(ActiveSpells). Each spell +entry is a {change, bonus} pair (`SpellInfo(key, change, bonus=0)`, +Dictionaries.cs:356). Old-style item spells were converted to player auras in +2012, so their innate **bonus is 0** — only their active-enchant change is +subtracted; the Blood/Spirit Thirst cantrips have bonus == change: +- MaxDamage — 1616 BD VI {20,0}, 2096 Infected Caress {22,0}, 5183/4395 + Incant. BD {24,0}, 2598 Minor BT {2,2}, 2586 Major BT {4,4}, 4661 Epic BT + {7,7}, 6089 Legendary BT {10,10}, 3688 Prodigal BD {300,0}. +- ElemVsMonsters — 3258 SD VI {.06,0}, 3259 Infected Spirit Caress {.07,0}, + 5182/4414 Incant. SD {.08,0}, 3251 Minor ST {.01,.01}, 3250 Major ST + {.03,.03}, 4670 Epic ST {.05,.05}, 6098 Legendary ST {.07,.07}. + +**Melee variance orientation**: the table's MaxVar is the type's *baseline* +variance; a weapon with LOWER variance than baseline yields a NEGATIVE +varianceTinks (log ratio < 1 over log 0.8) and therefore a HIGHER OD — +`varianceTinks = round(log(MaxVar_t / variance)/log(0.8), 2)` exactly as +ItemInfo.cs:1096. **MultiStrike** weapons: WeaponType (key 47 in UB code = our int key 47? no — UB reads LongValueKey 47 = WeaponType master id; the multistrike check is: