Add level-aware builder controls
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
# Weapon and gear stat level scaling
|
||||
|
||||
This document records the empirically observed rules for adjusting weapon and
|
||||
gear stat ranges by item level. The rules apply independently to both endpoints
|
||||
of a configured range.
|
||||
|
||||
These formulas are based on in-game observations rather than published game
|
||||
mechanics. Preserve source observations when adding new samples and revise the
|
||||
constants if a larger data set disproves them.
|
||||
|
||||
## Numeric representation and display
|
||||
|
||||
Stat ranges must retain their unrounded decimal values. The integer shown by the
|
||||
game is consistent with truncation:
|
||||
|
||||
```text
|
||||
displayedValue = floor(rawValue)
|
||||
```
|
||||
|
||||
Do not use `ceil`, and do not repeatedly level an already displayed integer.
|
||||
Both approaches accumulate errors. A level-1 value displayed as `0` can still
|
||||
have a positive fractional raw value that becomes visible 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
|
||||
```
|
||||
|
||||
When only displayed integers are available, a prediction can be off by one.
|
||||
That is expected information loss, not evidence for rounding upward.
|
||||
|
||||
## Shared progression model
|
||||
|
||||
The stable portion of both progressions is linear, not compounded:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Never calculate a new level as `previousDisplayedValue × 1.05`; that describes
|
||||
compound growth and does not match the observations.
|
||||
|
||||
For a range `[minimum, maximum]`, calculate each endpoint separately:
|
||||
|
||||
```text
|
||||
scaledMinimum = hiddenMinimum × multiplier(level)
|
||||
scaledMaximum = hiddenMaximum × multiplier(level)
|
||||
```
|
||||
|
||||
Only truncate when producing a game-matching display value.
|
||||
|
||||
## Gear
|
||||
|
||||
The observed stable gear multiplier is:
|
||||
|
||||
```text
|
||||
gearMultiplier(level) = 0.91 + 0.05 × level
|
||||
```
|
||||
|
||||
This rule is validated for levels 10 through 50 across Standard, Specialized,
|
||||
and High-end samples. Quality changes the hidden stat ranges; the observed
|
||||
late-level multiplier does not change with quality.
|
||||
|
||||
Given hidden level-independent endpoints:
|
||||
|
||||
```text
|
||||
rawMinimum(level) = hiddenMinimum × gearMultiplier(level)
|
||||
rawMaximum(level) = hiddenMaximum × gearMultiplier(level)
|
||||
```
|
||||
|
||||
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 and do not follow the
|
||||
stable multiplier directly. Do not extrapolate that transition from a single
|
||||
level-1-to-level-2 change. Until the early curves are sampled more completely,
|
||||
store authoritative ranges for those levels or mark 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)
|
||||
```
|
||||
|
||||
The `1.14` offset is provisional and is currently validated only for the
|
||||
level-40-to-level-50 interval. Preserve 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 displayed-source calculation misses by one because `753` is already
|
||||
truncated. Applying the ratio to the unrounded source value produces the
|
||||
observed `873`. This is why calculations must use 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 to level 1. An Exotic
|
||||
sample's displayed level-1 values and level-50 values fit a `2.91` endpoint
|
||||
ratio for most stats, which is incompatible with simply extending the
|
||||
level-40-to-level-50 offset backward. Weapons therefore also appear to have an
|
||||
early transition or another 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`.
|
||||
|
||||
Reference in New Issue
Block a user