/
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Improved Dice Algorithm:
x) is now computed from the mob's vanilla attribute value and rangeFactor, then the bonus (b) absorbs the rounding error so the rolled average is always exactly equal to the vanilla value — no more systematic buff/nerf from rounding driftxdn + b where b = target − x · dieAvgAuto Dice Type Selection:
autoDice config option (default true) per attribute section — picks the most "natural-feeling" die for each mob automatically based on its vanilla attribute valueautoDice = false to revert to the global diceType fallbackPer-mob Datapack Overrides:
data/<namespace>/mob_overrides/# prefix (e.g. #minecraft:raiders)/reload with no restart requireddata/mobdiceattribs/mob_overrides/example.jsonDimension Filter:
data/<namespace>/dimension_rules/enable field (optional, default true) — set to false to suppress all rolling in that dimensionmultiplier field (optional, default 1.0) — scales every attribute target before dice are rolleddata/mobdiceattribs/dimension_rules/example.json/reloadDifficulty Scaling:
data/<namespace>/difficulty_rules/"peaceful", "easy", "normal", "hard" (lowercase)data/mobdiceattribs/difficulty_rules/example.json/reloadDistance-from-Spawn Health Scaling:
[distanceScaling] config section — disabled by defaultenable (default false), blocksPerTier (default 1000), multiplierPerTier (default 0.1), cap (default 3.0)Additional Attributes:
armor — only rolls for mobs with base armor > 0 (zombie=2, warden=30)armorToughness — only rolls for mobs with base armor toughness > 0 (warden=3)attackSpeed — only rolls if base > 0; note: limited visible effect on most hostile mobsfollowRange — detection/pursuit range (zombie=35, skeleton=16, blaze=48)mob_overrides/example_all_attributes.json shipped in jar showing all eight attributesElite Mobs:
Elite Zombie) that is always visible[eliteMobs] — enable, healthThreshold (default 1.2), namePrefix (default "Elite"), showName (default true)rangeFactor=2.0 the practical rolled maximum is ~1.35×; values above that will never fire. Recommended range: 1.15–1.35namePrefix (see Spawn Profiles) takes priority over the elite name when setLoot Scaling:
mda_hp_ratio stored in entity NBT for any mob that rolls above its vanilla HP target[lootScaling] — enable, threshold (default 1.0), xpMultiplier (default 2.0), lootBonusRolls (default 1)threshold equal to eliteMobs.healthThreshold to restrict bonuses to elite mobs onlyxpMultiplier / lootBonusRolls fields (see Spawn Profiles) override config for that mobSpawn Profiles:
data/<namespace>/spawn_profiles/namePrefix, nameColor, xpMultiplier, lootBonusRolls, and all eight AttribOverride sections (all optional)common, uncommon, rare (blue, 2× XP, 1 bonus roll), legendary (purple, 5× XP, 3 bonus rolls, all attributes boosted)data/mobdiceattribs/spawn_profiles/example_legendary.json/reloadRarity Tiers:
data/<namespace>/rarity_tiers/ — { "tiers": [ { "profile": "...", "weight": N }, ... ] }[rarityTiers] — enable toggle onlydata/mobdiceattribs/rarity_tiers/example.json (60/25/10/5 weights for common/uncommon/rare/legendary)/reloadSpawn Hooks:
data/<namespace>/spawn_hooks/ — JSON object with context name keys and profile ResourceLocation values; omit a key or set to null to fall through to rarity tiersnatural, spawner, chunk_generation, structure, breeding, mob_summoned, jockey, event, conversion, reinforcement, triggered, bucket, spawn_egg, command, patrol[spawnHooks] — enable toggle onlydata/mobdiceattribs/spawn_hooks/example.json/reloadCommands:
/mda reroll <targets> — force-rerolls matched entities; resets HP to stored vanilla value (mda_base_hp) before rolling so results don't compound. Requires op level 2. Accepts standard entity selectors./mda inspect <target> — prints current attribute values plus mda_hp_ratio, mda_base_hp, and assigned profile. Single-entity selector only.Jade Mod Integration:
jade added as a runtime dependency (implementation) in build.gradleroll*() methods now accept a SpawnProfile parameter; attribute overrides merge as profile.attrib().merge(mobOverride) so per-mob overrides beat profileapplyRolls() gate order: mob whitelist/blacklist → dimension gate → difficulty gate → profile resolution → per-attribute rollsSimpleJsonResourceReloadListener implementations now filter by MDA.MOD_ID namespace — only data/mobdiceattribs/ files are loaded, preventing collisions with other modsshowName config (default false) now gates name tag visibility for both profile names and elite names; names are still set on the mob for Jade/TOP hover[speed] enable defaults to true with standard dice mechanics; speed profile overrides removed from legendary/rare after confirming compounding was the root cause/mda inspect now outputs Profile and Spawn type NBT fields for debuggingrarity_tiers/example.json renamed to rarity_tiers/default.jsonFinalizeSpawnEvent updated to top-level class (NeoForge 1.21.1 API change)net.neoforged.moddev (Gradle plugin)@Mod class now uses constructor injection of IEventBus and ModContainerMod.EventBusSubscriber replaced with @EventBusSubscriber(bus = Bus.GAME)ForgeConfigSpec replaced with ModConfigSpec throughoutResourceLocation.fromNamespaceAndPath() API adoptedAttributes.X returns Holder<Attribute>; .value() used to reach RangedAttributemod.gottsch.forge.gottschcore.* → mod.gottsch.neo.gottschcore.*gottschcore → gottschcore-neoforgeneoforge.mods.toml moved to src/main/templates/META-INF/ with generateModMetadata task for property substitutionmodContainer.registerConfig() — removed premature ModConfigEvent validation listener that caused "Cannot get config value before config is loaded" crashisValidEntity() simplified to entity instanceof Monster (Enemy interface removed in 1.21)side = "SERVER" — mod is server-only and clients can connect without it installed