Correct builder item level scaling

This commit is contained in:
JB
2026-07-25 22:18:50 -04:00
parent 478a37c17a
commit 1c32b1dfdc
4 changed files with 70 additions and 10 deletions
+17 -5
View File
@@ -776,11 +776,23 @@ calculates the ordinary level-40 curve value; never rebase level 40 as T2 level
1. Slider bounds, direct-input validation, displayed bounds, and clamping must
all enforce the same availability minimum.
ISAC weapon-tier damage and core ranges are observations recorded at their
explicit reference level. The progression curve still has a level-1 origin,
but builder scaling must calculate the ratio between the target level and the
stored observation's `reference_level`. Do not treat every stored endpoint as a
level-1 value merely because the curve begins there.
ISAC ranges that represent observed values retain their explicit reference
level. The progression curve still has a level-1 origin, but builder scaling
must calculate the ratio between the target level and the stored observation's
`reference_level`. Do not treat every observed endpoint as a level-1 value
merely because the curve begins there.
Weapon damage is the exception to reference-observation scaling: each
weapon-tier damage range is stored as a hidden base and must be multiplied
directly by `weaponMultiplier(selectedLevel)`. Changing weapon level remaps the
selected damage value into the newly calculated range. Shared core attributes
remain level-50 reference profiles and use ratio scaling independently.
Gear base Health and Armor follow the same hidden-base principle. Multiply
their stored per-item endpoints directly by `gearMultiplier(selectedLevel)`,
truncate only for display, and remap the user's selected value proportionally
when gear level changes. Do not apply this rule to rolled Attributes or the
shared core-allocation profile, which retain independent reference semantics.
### Shared core allocation
+16
View File
@@ -79,6 +79,12 @@ rawMinimum(level) = hiddenMinimum × gearMultiplier(level)
rawMaximum(level) = hiddenMaximum × gearMultiplier(level)
```
ISAC gear `base_health` and `base_armor` endpoints are these hidden,
level-independent bases. Builder base survivability therefore uses the direct
multiplier form above rather than treating those endpoints as observations at
the row's legacy reference level. Rolled Attributes and shared core profiles
retain their separately defined reference semantics.
Given an unrounded range recorded at a known reference level:
```text
@@ -150,6 +156,16 @@ targetRaw =
/ weaponMultiplier(referenceLevel)
```
Per-weapon damage endpoints in ISAC are hidden base ranges, not observations at
the shared core profile's reference level. Calculate weapon damage directly:
```text
damageRaw(level) = storedDamageBase × weaponMultiplier(level)
```
Firepower, Toughness, and Engineering remain shared reference-level
observations and continue to use the ratio form.
SHD.build stores the reference level associated with each weapon-tier range.
Builder calculations use that recorded observation level in the ratio above.
The curve's level-1 origin does not imply that every stored range was observed