8.5 KiB
Ascend: Ailments
Forge 1.20.1 library mod providing Soul Rot, Bleed, Fracture, Fear, Charm, Taunt, Overcharm, and Winded.
The mod ID is ascend_ailments; Ascend is optional.
Release builds are tested and published through GitHub Actions. The required one-time CurseForge setup and release process are documented in docs/RELEASING.md.
Public API
Normal callers should use net.fretux.ailments.api.AilmentApi, for example:
AilmentApi.applyBleed(target, source);
AilmentApi.applySoulRot(target, source, true);
AilmentApi.applyFear(target, source, 100);
AilmentApi.applyCharm(target, source, 100);
AilmentApi.applyTaunt(target, source, 100, 0);
AilmentApi.applyOvercharm(target, source, 200);
AilmentApi.applyWinded(target, source, 60);
AilmentApi.applyFracture(target, source, 160);
Skill nodes, modded weapons, and other data-driven callers can use the uniform application API:
boolean applied = AilmentApi.applyEffect(target, source, AilmentType.FEAR, 100, 0);
int appliedCount = AilmentApi.applyEffects(target, source,
AilmentApplication.stack(AilmentType.BLEED),
AilmentApplication.timed(AilmentType.WINDED, 60));
applyEffects attempts every descriptor in order and returns how many were accepted. Use stack for configured
Bleed/Soul Rot stacking and timed for an explicit duration and amplifier. AilmentApi.getEffect(type) exposes the
registered MobEffect when an integration needs to inspect an active effect without depending on registry internals.
Other mods can use the same source-safe machinery for their own registered effects:
MobEffect frost = MyEffects.FROST.get();
// Raw duration, authoritative merging, real Forge source, and persistent latest-source tracking.
AilmentApi.applyEffect(target, source, frost, 100, 0);
// Add one stack per call, cap at 4 stacks, and refresh to 100 ticks.
AilmentApi.applyStackingEffect(target, source, frost, 100, 4);
// Add one stack, extend remaining duration, and Arcane-scale each added duration chunk once.
AilmentApi.applyStackingEffect(target, source, frost, 100, 4, true, true);
LivingEntity loadedSource = AilmentApi.getEffectSource(target, frost);
UUID sourceId = AilmentApi.getEffectSourceUuid(target, frost);
applyScaledEffect provides the non-stacking Arcane-scaled variant. Source-aware applications reject infinite or
higher-amplifier active effects instead of creating vanilla hidden fallbacks, ensuring that the visible effect and its
single tracked owner cannot diverge. Generic applications are server-only, reject invalid or cross-dimension sources,
and honor team/friendly-fire rules for harmful player-on-player effects. Source
metadata is keyed by the external effect's registry ID and is cleared lazily when queried after the effect expires;
clearEffectSource can clear it explicitly without removing the effect.
Ordinary API applications are not rate-limited. Automatic combat integrations that need the configured PvP proc
cooldown should use applyProcEffect with either an AilmentApplication descriptor or explicit type/duration values.
Fracture stacks up to three times. Each stack removes 2 armor and 1 armor toughness; reapplication adds a stack and refreshes its duration. Arcane scales that refreshed duration but never changes the fixed attribute penalties.
These methods reject invalid targets, enforce PvP and immunity rules, scale duration once at application,
and persist source/potency data. Query methods expose stacks, loaded sources, Bleed immunity, and mental-control
resistance/immunity. Source queries return null when the UUID cannot currently be resolved.
Soul Rot's optional stack-duration mode follows the explicit balance table: amplifier 0 through 4 receives 160/180/200/220/240 base ticks (or the configured base plus 20 ticks per amplifier). This resolves the prose formula/table mismatch in favor of the listed gameplay results.
At two or more Bleed stacks, every successful Bleed damage tick builds the victim's Hemorrhage meter. Fill uses the
Bleed source's application-time Arcane potency snapshot. At the configured threshold, the meter resets to zero and
deals Bleed damage equal to 20% of the victim's maximum health by default. Integrations and HUD implementations can
read AilmentApi.getHemorrhageProgress(target) or the normalized getHemorrhageFraction(target). Minimum stacks,
threshold, fill per tick, burst health fraction, and the synchronized player-victim HUD meter are configurable in the
bleed section.
Damage ordering
The single LivingHurtEvent pipeline applies modifiers in this order:
- Soul Rot victim vulnerability
- Charm victim/attacker rules
- Taunt victim/attacker rules
- Overcharm's pre-hit Charm snapshot and direct-player-melee bonus
Each applicable multiplier is applied once. The Overcharm snapshot happens before Charm is refreshed, so its first hit has no pre-existing-Charm bonus. For simultaneous control effects, active Fear takes precedence over Taunt, and Taunt takes precedence over Charm's prohibition against attacking its owner.
Optional Ascend integration
compat.AscendCompat checks for mod ID ascend and reflection-isolates its player-stats capability. Missing classes,
missing capabilities, non-player sources, and absent/unloaded source data all fall back to 1.0x. An incompatible API
is logged and cached instead of retrying reflection during every application. DOT potency is snapshotted on
application so source unloading does not alter an active effect.
Datapack extension
Entity type tags:
ascend_ailments:bleed_immuneascend_ailments:soulless(immune to Soul Rot)ascend_ailments:sturdy(immune to Fracture)ascend_ailments:mental_control_resistantascend_ailments:mental_control_immune
Vanilla undead are included in soulless, and any vanilla or modded entity classified with MobType.UNDEAD is
also rejected independently of the tag. sturdy includes iron golems by default. Non-player undead remain naturally
Bleed-immune; bleed_immune takes precedence even for players and also prevents and clears Hemorrhage buildup.
Integrations can query AilmentApi.canSoulRot, canFracture, and canBleed before presenting or applying abilities.
Item tags:
ascend_ailments:bleed_on_hitascend_ailments:soul_rot_on_hitascend_ailments:fracture_on_hitascend_ailments:fear_on_hitascend_ailments:charm_on_hitascend_ailments:taunt_on_hitascend_ailments:overcharm_on_hitascend_ailments:winded_on_hit
Direct melee hits with items in these tags apply their corresponding ailment. Soul Rot, Bleed, and Fracture use
their configured stack/duration behavior; the other tags use taggedWeaponEffectDurationTicks. Bleed also applies to non-vanilla item
registry paths containing a configured katana-family keyword. Automatic application, proc chance, matching keywords,
and the PvP proc cooldown are configurable under integration in ascend-ailments-server.toml. PvP cooldowns are
tracked per attacking player and ailment; their configured minimum is 60 ticks (3 seconds).
Admin commands
/ascendailments apply ... supports all eight effects and /ascendailments clear <target> removes the library's
effects and metadata. Permission level 2 is required. Durations are ticks; amplifier arguments use vanilla's
zero-based convention.
Creative test items
The Tools & Utilities creative tab contains one glowing debug stick for each of the eight ailments. A successful
direct hit applies the named effect through the normal source-aware API. Soul Rot, Bleed, and Fracture add their
configured stacks; the other effects use taggedWeaponEffectDurationTicks. The sticks have no recipes and only apply
effects when wielded by a player in Creative Mode, including on multiplayer and dedicated servers.
Potions
Each ailment has a drinkable potion brewed from an Awkward Potion. Add Gunpowder for its splash variant (and Dragon's Breath afterward for the standard lingering variant).
| Ailment | Awkward Potion ingredient |
|---|---|
| Soul Rot | Soul Sand |
| Bleed | Rotten Flesh |
| Fracture | Bone |
| Fear | Fermented Spider Eye |
| Charm | Honey Bottle |
| Taunt | Fire Charge |
| Overcharm | Golden Apple |
| Winded | Feather |
Fear, Charm, and Taunt retain a source. A drinkable bottle targets its drinker with the player who took the finished bottle from the brewing stand as its brewer; drinking your own control potion has no effect. Splash potions use the thrower as their source and likewise do not control the thrower. Drinkable control potions created without a recorded brewer do nothing safely.