EntityScaling ignores meta.rounding_unit config, hardcodes rounding from modifier value.
Summary
EntityScaling.apply() computes its own rounding unit from modifier.value * 0.25F instead of reading meta.rounding_unit from the config. This causes entity attribute modifiers to be rounded to arbitrary increments that don't match the user-configured rounding unit. ItemScaling correctly reads the config value via getRoundingUnit(), so loot scaling rounds properly while entity scaling does not.
Affected code
EntityScaling.java, lines 81-83:
var modifierValue = modifier.randomizedValue(level);
var roundingUnit = modifier.value * 0.25F; // BUG: hardcoded, ignores config
modifierValue = (float) MathHelper.round(modifierValue, roundingUnit);
Reproduction
Config:
{
"meta": {
"rounding_unit": 0.5
},
"difficulty_types": [
{
"name": "wilds",
"entities": [
{
"entity_matches": { "attitude": "ANY", "type": "" },
"attributes": [
{
"attribute": "minecraft:generic.max_health",
"operation": "MULTIPLY_BASE",
"randomness": 0.0,
"value": 0.15,
"offset": 2.0
}
]
}
]
}
]
}
Expected: Zombie (20 base HP) gets modifier value 2.0 + (0.15 * 1) = 2.15, rounded to nearest 0.5 = 2.0 or 2.5, resulting in 20 * 3.0 = 60.0 or 20 * 3.5 = 70.0 HP.
Actual: Rounding unit is computed as 0.15 * 0.25 = 0.0375. Modifier value 2.15 rounds to 57 * 0.0375 = 2.1375. Zombie gets 20 * 3.1375 = 62.75 HP.
The bug is more visible with non-zero offset, but also affects any modifier where value * 0.25 doesn't align with the configured rounding_unit. For example, with value: 0.3 and randomness: 0.05 at level 1, the rounding unit becomes 0.075 instead of the configured 0.5, producing values like 18.39 HP on mobs that should show clean half-point increments.
Additionally, when modifier.value is 0.0 (e.g., a flat offset-only modifier), the rounding unit becomes 0.0. In MathHelper.round(), this computes 1.0 / 0.0 = Infinity, then Math.round(value * Infinity) = Long.MAX_VALUE, then Long.MAX_VALUE / Infinity = 0.0. The modifier is silently zeroed out instead of being applied.
Suggested fix
Option A: Extract a shared RoundingHelper class that reads meta.rounding_unit from config. Both EntityScaling and ItemScaling use it instead of each having their own implementation.
// RoundingHelper.java (new file in net.dungeon_difficulty.logic)
package net.dungeon_difficulty.logic;
import net.dungeon_difficulty.DungeonDifficulty;
import org.jetbrains.annotations.Nullable;
public class RoundingHelper {
@Nullable
public static Double getRoundingUnit() {
var config = DungeonDifficulty.config.value;
if (config.meta != null && config.meta.rounding_unit != null) {
return config.meta.rounding_unit;
}
return null;
}
}
// EntityScaling.java, replace lines 81-83:
var modifierValue = modifier.randomizedValue(level);
var roundingUnit = RoundingHelper.getRoundingUnit();
if (roundingUnit != null) {
modifierValue = (float) MathHelper.round(modifierValue, roundingUnit);
}
// ItemScaling.java, replace private getRoundingUnit() and its call sites:
var roundingUnit = RoundingHelper.getRoundingUnit();
if (roundingUnit != null) {
value = MathHelper.round(value, roundingUnit);
}
Option B (more flexible, preferable): Introduce a separate config parameter for entity scaling rounding (e.g., meta.entity_rounding_unit), then wire it in EntityScaling the same way ItemScaling currently reads meta.rounding_unit. This would allow independent control over rounding precision for entity stats vs. item stats. RoundingHelper could expose two methods (getEntityRoundingUnit() and getItemRoundingUnit()) in this case.
Thank you!
EntityScaling ignores
meta.rounding_unitconfig, hardcodes rounding from modifier value.Summary
EntityScaling.apply()computes its own rounding unit frommodifier.value * 0.25Finstead of readingmeta.rounding_unitfrom the config. This causes entity attribute modifiers to be rounded to arbitrary increments that don't match the user-configured rounding unit.ItemScalingcorrectly reads the config value viagetRoundingUnit(), so loot scaling rounds properly while entity scaling does not.Affected code
EntityScaling.java, lines 81-83:Reproduction
Config:
{ "meta": { "rounding_unit": 0.5 }, "difficulty_types": [ { "name": "wilds", "entities": [ { "entity_matches": { "attitude": "ANY", "type": "" }, "attributes": [ { "attribute": "minecraft:generic.max_health", "operation": "MULTIPLY_BASE", "randomness": 0.0, "value": 0.15, "offset": 2.0 } ] } ] } ] }Expected: Zombie (20 base HP) gets modifier value
2.0 + (0.15 * 1) = 2.15, rounded to nearest0.5=2.0or2.5, resulting in20 * 3.0 = 60.0or20 * 3.5 = 70.0HP.Actual: Rounding unit is computed as
0.15 * 0.25 = 0.0375. Modifier value2.15rounds to57 * 0.0375 = 2.1375. Zombie gets20 * 3.1375 = 62.75HP.The bug is more visible with non-zero
offset, but also affects any modifier wherevalue * 0.25doesn't align with the configuredrounding_unit. For example, withvalue: 0.3andrandomness: 0.05at level 1, the rounding unit becomes0.075instead of the configured0.5, producing values like18.39HP on mobs that should show clean half-point increments.Additionally, when
modifier.valueis0.0(e.g., a flat offset-only modifier), the rounding unit becomes0.0. InMathHelper.round(), this computes1.0 / 0.0 = Infinity, thenMath.round(value * Infinity) = Long.MAX_VALUE, thenLong.MAX_VALUE / Infinity = 0.0. The modifier is silently zeroed out instead of being applied.Suggested fix
Option A: Extract a shared
RoundingHelperclass that readsmeta.rounding_unitfrom config. BothEntityScalingandItemScalinguse it instead of each having their own implementation.Option B (more flexible, preferable): Introduce a separate config parameter for entity scaling rounding (e.g.,
meta.entity_rounding_unit), then wire it inEntityScalingthe same wayItemScalingcurrently readsmeta.rounding_unit. This would allow independent control over rounding precision for entity stats vs. item stats.RoundingHelpercould expose two methods (getEntityRoundingUnit()andgetItemRoundingUnit()) in this case.Thank you!