245 lines
7.7 KiB
Markdown
245 lines
7.7 KiB
Markdown
# Weapon and gear stat level scaling
|
||
|
||
Use these observed rules to adjust weapon and gear stat ranges by item level.
|
||
Apply each rule to both endpoints of a configured range.
|
||
|
||
In-game observations, rather than published game mechanics, support these
|
||
formulas. Preserve source observations with new samples and revise constants
|
||
when a larger data set disproves them.
|
||
|
||
## Numeric representation and display
|
||
|
||
Store stat ranges as unrounded decimals. The game display truncates them:
|
||
|
||
```text
|
||
displayedValue = floor(rawValue)
|
||
```
|
||
|
||
Avoid `ceil` and repeated leveling of displayed integers. Both accumulate
|
||
errors. A level-1 display of `0` can hide a positive fractional raw value that
|
||
appears at a higher level.
|
||
|
||
For example, a standard gear item displayed `0 ENG` at level 1 and `2 ENG` at
|
||
level 42. With a level-42 multiplier of `3.01`, a raw base near `0.7` explains
|
||
both values:
|
||
|
||
```text
|
||
floor(0.7) = 0
|
||
floor(0.7 × 3.01) = 2
|
||
```
|
||
|
||
Predictions from displayed integers can miss by one because truncation loses
|
||
information. That error does not indicate rounding upward.
|
||
|
||
## Shared progression model
|
||
|
||
The stable portion of both progressions is linear:
|
||
|
||
```text
|
||
rawStat(level) = hiddenBase × multiplier(level)
|
||
```
|
||
|
||
The multiplier increases by `0.05` per level. Equivalently, each level adds a
|
||
fixed `5%` of the hidden base:
|
||
|
||
```text
|
||
rawStat(level + 1) - rawStat(level) = hiddenBase × 0.05
|
||
```
|
||
|
||
Do not calculate a new level as `previousDisplayedValue × 1.05`. That compound
|
||
growth model conflicts with the observations.
|
||
|
||
For a range `[minimum, maximum]`, calculate each endpoint separately:
|
||
|
||
```text
|
||
scaledMinimum = hiddenMinimum × multiplier(level)
|
||
scaledMaximum = hiddenMaximum × multiplier(level)
|
||
```
|
||
|
||
Truncate at the game-display boundary.
|
||
|
||
## Gear
|
||
|
||
The observed stable gear multiplier is:
|
||
|
||
```text
|
||
gearMultiplier(level) = 0.91 + 0.05 × level
|
||
```
|
||
|
||
Samples across Standard, Specialized, and High-end qualities validate this rule
|
||
for levels 10 through 50. Quality changes hidden stat ranges; the observed
|
||
late-level multiplier remains the same.
|
||
|
||
Given hidden level-independent endpoints:
|
||
|
||
```text
|
||
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
|
||
targetRaw =
|
||
referenceRaw
|
||
× gearMultiplier(targetLevel)
|
||
/ gearMultiplier(referenceLevel)
|
||
```
|
||
|
||
### Gear example
|
||
|
||
At level 42:
|
||
|
||
```text
|
||
gearMultiplier(42) = 0.91 + 0.05 × 42 = 3.01
|
||
```
|
||
|
||
A Standard item with approximate hidden bases of `615.0 HP`, `107.4 AR`,
|
||
`10.0 FP`, `11.4 TGH`, and `0.7 ENG` produces:
|
||
|
||
```text
|
||
HP = floor(615.0 × 3.01) = 1851
|
||
AR = floor(107.4 × 3.01) = 323
|
||
FP = floor(10.0 × 3.01) = 30
|
||
TGH = floor(11.4 × 3.01) = 34
|
||
ENG = floor(0.7 × 3.01) = 2
|
||
```
|
||
|
||
### Early gear levels
|
||
|
||
Levels 1 through 9 show a quality-dependent transition outside the stable
|
||
multiplier. Do not extrapolate it from one level-1-to-level-2 change. Until
|
||
more samples define the early curves, store authoritative ranges or label
|
||
calculated results as estimates.
|
||
|
||
## Weapons
|
||
|
||
Weapon observations from levels 40 through 50 show the same fixed `0.05`
|
||
multiplier increase per level, but a different offset:
|
||
|
||
```text
|
||
weaponMultiplier(level) ≈ 1.14 + 0.05 × level
|
||
```
|
||
|
||
This gives approximately:
|
||
|
||
```text
|
||
weaponMultiplier(40) = 3.14
|
||
weaponMultiplier(50) = 3.64
|
||
```
|
||
|
||
and predicts a level-40-to-level-50 ratio of:
|
||
|
||
```text
|
||
3.64 / 3.14 ≈ 1.15924
|
||
```
|
||
|
||
Two observed weapons produced ratios of approximately `1.15960` and `1.15936`.
|
||
The small difference is consistent with hidden fractional bases and truncated
|
||
display values.
|
||
|
||
Given an unrounded weapon range at a known reference level:
|
||
|
||
```text
|
||
targetRaw =
|
||
referenceRaw
|
||
× weaponMultiplier(targetLevel)
|
||
/ 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
|
||
at level 1. T2 availability limits likewise do not change a range's recorded
|
||
reference level.
|
||
|
||
Firepower, Toughness, and Engineering nominal tier ranges are stored once in
|
||
the shared core-allocation configuration at reference level 50. Scale those
|
||
nominal endpoints to the target level using the appropriate equipment-family
|
||
multiplier, then derive the combined pool bounds by multiplying each endpoint
|
||
by three. Redistribution changes the split between the three cores without
|
||
changing the selected item's total allocation.
|
||
|
||
The `1.14` offset remains provisional; observations only validate it from level
|
||
40 to 50. Retain enough decimal precision to revise it without migrating
|
||
rounded data.
|
||
|
||
### Weapon example
|
||
|
||
A weapon changed from `753 DMG` at level 40 to `873 DMG` at level 50:
|
||
|
||
```text
|
||
753 × (3.64 / 3.14) ≈ 872.95
|
||
floor(872.95) = 872
|
||
```
|
||
|
||
The calculation misses by one because `753` is truncated. The ratio applied to
|
||
the unrounded source value produces `873`, so calculations require stored
|
||
decimal endpoints.
|
||
|
||
The observed changes over those ten levels were linear:
|
||
|
||
```text
|
||
DMG: 753 → 873 (12.0 raw points per level)
|
||
FP: 44 → 51 (about 0.7 per level)
|
||
TGH: 15 → 18 (about 0.3 per level)
|
||
ENG: 45 → 52 (about 0.7 per level)
|
||
```
|
||
|
||
### Early weapon levels
|
||
|
||
Do not apply the provisional late-level weapon offset at level 1. An Exotic
|
||
sample's level-1 and level-50 displays fit a `2.91` endpoint ratio for most
|
||
stats, which conflicts with extending the level-40-to-level-50 offset
|
||
backward. Weapons appear to have an early transition or quality-dependent input.
|
||
|
||
Until more intermediate samples are available:
|
||
|
||
- use the weapon formula only within the validated level 40–50 interval;
|
||
- do not derive a hidden base directly from a displayed level-1 value;
|
||
- prefer authoritative low-level ranges where exact results are required.
|
||
|
||
## Implementation requirements
|
||
|
||
1. Store range endpoints as decimals and retain their reference level.
|
||
2. Scale minimum and maximum independently using raw values.
|
||
3. Calculate directly from the reference value; never chain per-level rounded
|
||
results.
|
||
4. Truncate only at the presentation boundary when matching the game display.
|
||
5. Clamp supported levels to `1–50`.
|
||
6. Treat gear levels below 10 and weapon levels below 40 as provisional until
|
||
their curves are verified.
|
||
7. Add observed intermediate values as regression fixtures before changing a
|
||
multiplier or rounding rule.
|
||
|
||
## Current regression observations
|
||
|
||
Useful known outputs include:
|
||
|
||
- Specialized gear at level 27: `1610 HP`, `280 AR`, `29 FP`, `23 TGH`,
|
||
`10 ENG`.
|
||
- Standard gear at level 42: `1851 HP`, `323 AR`, `30 FP`, `34 TGH`, `2 ENG`.
|
||
- High-end gear: level 40 `2682 HP`, `464 AR`, `47 FP`, `16 TGH`, `36 ENG`;
|
||
level 41 `2728 HP`, `472 AR`, `48 FP`, `16 TGH`, `37 ENG`; level 50
|
||
`3143 HP`, `544 AR`, `55 FP`, `19 TGH`, `43 ENG`.
|
||
- Weapon sample: level 40 `1886 DMG`, `120 FP`, `123 TGH`, `31 ENG`; level 50
|
||
`2187 DMG`, `139 FP`, `142 TGH`, `36 ENG`.
|
||
- Weapon sample: level 40 `753 DMG`, `44 FP`, `15 TGH`, `45 ENG`; level 50
|
||
`873 DMG`, `51 FP`, `18 TGH`, `52 ENG`.
|