Ars 'n SpellsСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачатьСкачать
ВЕРСИИ (12)
release
Ars 'n Spells 3.3.5
3.3.52 окт. 2026 г.4,6 тыс.Minecraft: 1.21.1neoforge
Что нового
## [3.3.5] - 2026-09-27
### Fixed
- Iron's spells no longer stop with "Cast stopped. Check your resources; details are in the server log." when another mod checks mana inside Iron's own mana payment. 3.3.4 took the price as soon as Iron's final cost event ended, before Iron's own mana check and write. A mod that checks affordability at that point, such as Animus on NeoForge 1.21.1, saw the pool already debited and cancelled the cast; ANS refunded it and logged `Effect boundary not reached`. Any spell costing more than half the remaining pool failed. ANS now takes the price where Iron's writes its own mana debit and replaces that write, so such a check sees the pool as Iron's would, and a top-up made there pays for the cast. The cost event then states what ANS will take from the pool Iron's reads: the converted amount in `ars_primary`, the Iron's share of a dual-cost split, and 0 for bound Ars spells and LP-paid casts. No Forge 1.20.1 mod is known to act at that point; the change keeps both builds' payment code the same.
- A cast that another mod cancels before its effect now costs nothing and is not reported as a payment failure: no warning and no "Cast stopped" message. Iron's own follow-through runs as it would without ANS, and debug mode logs `stage=vetoed_before_effect`.
- The startup self-check now names each handler it needs and also covers the payment and cast-ticker mixins. Before, any ANS method on `AbstractSpell` passed, so a failed payment mixin would not have been reported.
- Channelled Iron's spells no longer stop with a payment failure when mana runs low. 3.3.4 turned off Iron's own end-of-channel check, so a channel such as BielGG's Crystal Barrage (250 mana per pulse) ran into a pulse the caster could not pay and stopped with "Cast stopped. Check your resources; details are in the server log." ANS now checks after every paid pulse, at that pulse's final price and in the pool that paid it. When the balance cannot cover another pulse, the channel finishes as Iron's native final pulse, with cooldown, scroll consumption and completion. Final-price modifiers such as BielGG's Thorn Ring are honoured; Iron's own check only ever saw the base cost.
- `ars_primary`: Iron's mana regeneration can no longer lower the Ars pool. Iron's regeneration reads and writes the Ars balance in this mode but clamped it to Iron's mirrored `max_mana`, which is rounded down to a whole number and can briefly lag the real Ars maximum. That clamp removed mana without any cast. It is the only such path found and the most likely cause of the reported dip while scrolling the hotbar, although the report itself has not been reproduced. Regeneration may now only raise the balance.
- The shared-pool ceiling is no longer computed before an equipment change has taken effect. Forge fires the change event before vanilla swaps the item's attribute modifiers, so ANS now reconciles at the end of the player's tick instead. Delayed ceiling updates are merged per player, so an older maximum can no longer be applied after a newer one.
- Ars spells cast from Iron's spell wheel counted as successful even when Ars refused them, for example for lack of mana, because Ars's caster reports success either way. Success now comes from Ars's own resolver. A refused cast no longer grants the first cross-cast advancement.
- A Cursed Ring LP shortage on an Iron's cast is now reported as LP, not as Iron's mana.
- A resource shortage now says what was needed and what was available, for example "Not enough Iron's mana for Crystal Barrage: 250 needed, 180 available.", instead of the generic message. Shortages are ordinary gameplay and are no longer logged as warnings; debug mode records one line per failed cast with the price and resource. Other payment faults still warn, now including the price. These diagnostic lines identify the player by a pseudonymous token instead of their UUID.
- Config migration: only a config file without a schema stamp is checked for being newly generated, so a stamped 3.3.0–3.3.2 file can no longer be mistaken for a new one. Files from 3.3.3 and 3.3.4 receive only the new 3.3.5 step.
### Added
- `inscribed_ars_default_cooldown_ticks` (Cross-Cast Inscription, 0–12000 ticks, 20 ticks = 1 s): Iron's cooldown after an Ars spell bound into an Iron's spellbook casts successfully from Iron's spell wheel. It uses Iron's own cooldown system, so Iron's cooldown reduction, the wheel's cooldown display and saving across relogs all apply. A failed, refused or unpaid cast starts no cooldown. Newly generated configs use 40 ticks (2 s); configs from earlier versions migrate to 0, which keeps the previous behaviour. Changes take effect on the next cast after the config reloads. The setting is also on the in-game settings screen. Books that reuse the same proxy slot share its cooldown. Ordinary Ars casts, ordinary Iron's spells and Iron's spells inscribed into Ars items are unaffected, and the optional category cooldowns remain a separate check.
- Debug mode logs both mana pools, the Iron's ceiling, the selected slot and the held item whenever equipment reconciliation changes something (at most ten lines per second per player). It also logs each regeneration write that was refused because it would have lowered the Ars pool.
- New GameTests cover: channels that run out of mana in all five modes; a SWORD channel with a halved final cost; a delayed SWORD cast charged once at its final price; `ars_primary` hotbar cycling with Iron's regeneration; removal of a real maximum-mana bonus; and the inscribed cooldown after success, failure, zero, cooldown reduction, shared slots and category cooldowns.
- New GameTests reproduce the NeoForge Scorch report with a GameTest-only mixin at the call Animus uses: an affordability check in all five modes at conversion rates 0.5, 1 and 3, a top-up of an underfunded cast, a cancel before the effect, and a channel under the check. Only `runGameTestServer` sets `-Dans.gametest.castProbe=true`, which applies that mixin.
- `-PwithIrons316RuntimeGameTests` runs the Iron's-loaded GameTests against Iron's Spellbooks 1.20.1-3.16.3 (with irons_lib 1.20.1-2.1.0) instead of the 3.15.0 build pin.
- `tools/pack_presets.py` accepts config schema 3 as well as 2; before this change it would have refused every 3.3.5 config. `docs/3.3.5/config-reference.md` lists every key of this release.
### Compatibility
- Tested: Minecraft 1.20.1, Forge 47.4.10, Ars Nouveau 4.12.7, Iron's Spellbooks 1.20.1-3.15.0 and 1.20.1-3.16.3. BielGG's Spells Addon 1.5-patchwork was inspected from its jar but not run, because it also requires L_Ender's Cataclysm and Lionfish API. Details and the remaining limits are in `docs/3.3.5/`.
- Animus 1.20.1-3.0.35 was inspected from its jar: it works through Iron's cast check and cost events and does not act inside Iron's mana payment. It was not run. The Iron's GameTests also passed with Covenant of the Seven 2.2.6-hotfix loaded.
- Ars Affinity has no Forge 1.20.1 release and is not supported on this build. It is covered by the NeoForge 1.21.1 build.
### Forge / NeoForge parity
The Forge 1.20.1 and NeoForge 1.21.1 builds now have the same features, configuration, commands, datapack tags and translations, except for integrations whose mod has no build for the other Minecraft version (Covenant of the Seven and Too Many Glyphs exist only for 1.20.1; Ars Affinity and Ars Elemancy only for 1.21.1). `docs/3.3.5/parity-review.md` lists every remaining difference and why. This build gains:
- **Cross-mod combat stats in both directions.** Iron's spell power already scaled Ars spell damage. The Ars Spell Damage Bonus perk now also adds to Iron's spell damage as a flat bonus, which `spell_power_cap` does not limit. **This changes damage for players with that perk**; set `enable_ars_damage_for_irons_damage = false` to keep the 3.3.4 behaviour. New Spell Scaling keys: `enable_cross_mod_combat_stats`, `enable_irons_power_for_ars_damage`, `enable_ars_damage_for_irons_damage` (all on by default and independent of the mana mode) and `multi_school_power_policy` (`primary` by default, as before; `max` or `average` let a multi-school spell scale with another of its schools; affinity and progression still credit the first school). `/ans debug combat` shows the settings, both mods' spell-damage attributes and the last scaled hit in each direction.
- **Tagged-curio discount.** Each worn curio in `#ars_n_spells:curio_spell_discount` reduces Ars and Iron's cast costs by `virtue_ring_discount` (0.20), and all of them together by at most `max_total_curio_discount` (0.50). A cast that cost mana never becomes free. With Covenant installed, the Blasphemy discount still applies after it. The shipped tag lists Iron's school focus items, which are not normally wearable; packs add their own curios. `enable_curio_discounts` covers both discounts.
- **`#ars_n_spells:cross_cast_blacklist`.** Ars Zero's five multi-phase glyphs only work inside a Spell Staff. A spell using them is now refused by the Spell Loom, `/ans export_to_irons_scroll`, Spell Transcription and every cross-cast, with a message naming the glyphs.
- `/ans info` also lists the player's affinity levels and the number of registered Iron's schools. Its raw Iron's mana line is translatable, and the ring-bypass flag appears only with Covenant installed.
- Server stop now also clears staged scroll costs, cast-validation scopes, in-flight cross-casts, combat diagnostics and log throttles.
- The "Cross spell selected" message is translatable, and cross-cast refusals are shown in red.
- Config comments match the NeoForge build. The `mana_unification_mode` comment no longer claims a restart is needed, because mode changes apply live.
- The debug-only startup lock check looks at `ars_n_spells-server.toml`, not the pre-2.0.1 `-common.toml`.
- New GameTests: combat bridge (11), `ParityBehaviourGameTests` (Source Jar synergy, gear bonus per mode, potion mirroring, tagged curios), uninscription teardown, the Curios attribute toggle, Ars Zero profile, resolver-hook and blacklist checks, proxy pool reuse and the carrier reconciler. `tools/verify_loader_parity.py` now ships here too and checks both directions, including GameTest coverage.
release
Ars 'n Spells 3.3.5
3.3.52 окт. 2026 г.1,9 тыс.Minecraft: 1.20.1forge
Что нового
## [3.3.5] - 2026-09-27
### Fixed
- Iron's spells no longer stop with "Cast stopped. Check your resources; details are in the server log." when another mod checks mana inside Iron's own mana payment. 3.3.4 took the price as soon as Iron's final cost event ended, before Iron's own mana check and write. A mod that checks affordability at that point, such as Animus on NeoForge 1.21.1, saw the pool already debited and cancelled the cast; ANS refunded it and logged `Effect boundary not reached`. Any spell costing more than half the remaining pool failed. ANS now takes the price where Iron's writes its own mana debit and replaces that write, so such a check sees the pool as Iron's would, and a top-up made there pays for the cast. The cost event then states what ANS will take from the pool Iron's reads: the converted amount in `ars_primary`, the Iron's share of a dual-cost split, and 0 for bound Ars spells and LP-paid casts. No Forge 1.20.1 mod is known to act at that point; the change keeps both builds' payment code the same.
- A cast that another mod cancels before its effect now costs nothing and is not reported as a payment failure: no warning and no "Cast stopped" message. Iron's own follow-through runs as it would without ANS, and debug mode logs `stage=vetoed_before_effect`.
- The startup self-check now names each handler it needs and also covers the payment and cast-ticker mixins. Before, any ANS method on `AbstractSpell` passed, so a failed payment mixin would not have been reported.
- Channelled Iron's spells no longer stop with a payment failure when mana runs low. 3.3.4 turned off Iron's own end-of-channel check, so a channel such as BielGG's Crystal Barrage (250 mana per pulse) ran into a pulse the caster could not pay and stopped with "Cast stopped. Check your resources; details are in the server log." ANS now checks after every paid pulse, at that pulse's final price and in the pool that paid it. When the balance cannot cover another pulse, the channel finishes as Iron's native final pulse, with cooldown, scroll consumption and completion. Final-price modifiers such as BielGG's Thorn Ring are honoured; Iron's own check only ever saw the base cost.
- `ars_primary`: Iron's mana regeneration can no longer lower the Ars pool. Iron's regeneration reads and writes the Ars balance in this mode but clamped it to Iron's mirrored `max_mana`, which is rounded down to a whole number and can briefly lag the real Ars maximum. That clamp removed mana without any cast. It is the only such path found and the most likely cause of the reported dip while scrolling the hotbar, although the report itself has not been reproduced. Regeneration may now only raise the balance.
- The shared-pool ceiling is no longer computed before an equipment change has taken effect. Forge fires the change event before vanilla swaps the item's attribute modifiers, so ANS now reconciles at the end of the player's tick instead. Delayed ceiling updates are merged per player, so an older maximum can no longer be applied after a newer one.
- Ars spells cast from Iron's spell wheel counted as successful even when Ars refused them, for example for lack of mana, because Ars's caster reports success either way. Success now comes from Ars's own resolver. A refused cast no longer grants the first cross-cast advancement.
- A Cursed Ring LP shortage on an Iron's cast is now reported as LP, not as Iron's mana.
- A resource shortage now says what was needed and what was available, for example "Not enough Iron's mana for Crystal Barrage: 250 needed, 180 available.", instead of the generic message. Shortages are ordinary gameplay and are no longer logged as warnings; debug mode records one line per failed cast with the price and resource. Other payment faults still warn, now including the price. These diagnostic lines identify the player by a pseudonymous token instead of their UUID.
- Config migration: only a config file without a schema stamp is checked for being newly generated, so a stamped 3.3.0–3.3.2 file can no longer be mistaken for a new one. Files from 3.3.3 and 3.3.4 receive only the new 3.3.5 step.
### Added
- `inscribed_ars_default_cooldown_ticks` (Cross-Cast Inscription, 0–12000 ticks, 20 ticks = 1 s): Iron's cooldown after an Ars spell bound into an Iron's spellbook casts successfully from Iron's spell wheel. It uses Iron's own cooldown system, so Iron's cooldown reduction, the wheel's cooldown display and saving across relogs all apply. A failed, refused or unpaid cast starts no cooldown. Newly generated configs use 40 ticks (2 s); configs from earlier versions migrate to 0, which keeps the previous behaviour. Changes take effect on the next cast after the config reloads. The setting is also on the in-game settings screen. Books that reuse the same proxy slot share its cooldown. Ordinary Ars casts, ordinary Iron's spells and Iron's spells inscribed into Ars items are unaffected, and the optional category cooldowns remain a separate check.
- Debug mode logs both mana pools, the Iron's ceiling, the selected slot and the held item whenever equipment reconciliation changes something (at most ten lines per second per player). It also logs each regeneration write that was refused because it would have lowered the Ars pool.
- New GameTests cover: channels that run out of mana in all five modes; a SWORD channel with a halved final cost; a delayed SWORD cast charged once at its final price; `ars_primary` hotbar cycling with Iron's regeneration; removal of a real maximum-mana bonus; and the inscribed cooldown after success, failure, zero, cooldown reduction, shared slots and category cooldowns.
- New GameTests reproduce the NeoForge Scorch report with a GameTest-only mixin at the call Animus uses: an affordability check in all five modes at conversion rates 0.5, 1 and 3, a top-up of an underfunded cast, a cancel before the effect, and a channel under the check. Only `runGameTestServer` sets `-Dans.gametest.castProbe=true`, which applies that mixin.
- `-PwithIrons316RuntimeGameTests` runs the Iron's-loaded GameTests against Iron's Spellbooks 1.20.1-3.16.3 (with irons_lib 1.20.1-2.1.0) instead of the 3.15.0 build pin.
- `tools/pack_presets.py` accepts config schema 3 as well as 2; before this change it would have refused every 3.3.5 config. `docs/3.3.5/config-reference.md` lists every key of this release.
### Compatibility
- Tested: Minecraft 1.20.1, Forge 47.4.10, Ars Nouveau 4.12.7, Iron's Spellbooks 1.20.1-3.15.0 and 1.20.1-3.16.3. BielGG's Spells Addon 1.5-patchwork was inspected from its jar but not run, because it also requires L_Ender's Cataclysm and Lionfish API. Details and the remaining limits are in `docs/3.3.5/`.
- Animus 1.20.1-3.0.35 was inspected from its jar: it works through Iron's cast check and cost events and does not act inside Iron's mana payment. It was not run. The Iron's GameTests also passed with Covenant of the Seven 2.2.6-hotfix loaded.
- Ars Affinity has no Forge 1.20.1 release and is not supported on this build. It is covered by the NeoForge 1.21.1 build.
### Forge / NeoForge parity
The Forge 1.20.1 and NeoForge 1.21.1 builds now have the same features, configuration, commands, datapack tags and translations, except for integrations whose mod has no build for the other Minecraft version (Covenant of the Seven and Too Many Glyphs exist only for 1.20.1; Ars Affinity and Ars Elemancy only for 1.21.1). `docs/3.3.5/parity-review.md` lists every remaining difference and why. This build gains:
- **Cross-mod combat stats in both directions.** Iron's spell power already scaled Ars spell damage. The Ars Spell Damage Bonus perk now also adds to Iron's spell damage as a flat bonus, which `spell_power_cap` does not limit. **This changes damage for players with that perk**; set `enable_ars_damage_for_irons_damage = false` to keep the 3.3.4 behaviour. New Spell Scaling keys: `enable_cross_mod_combat_stats`, `enable_irons_power_for_ars_damage`, `enable_ars_damage_for_irons_damage` (all on by default and independent of the mana mode) and `multi_school_power_policy` (`primary` by default, as before; `max` or `average` let a multi-school spell scale with another of its schools; affinity and progression still credit the first school). `/ans debug combat` shows the settings, both mods' spell-damage attributes and the last scaled hit in each direction.
- **Tagged-curio discount.** Each worn curio in `#ars_n_spells:curio_spell_discount` reduces Ars and Iron's cast costs by `virtue_ring_discount` (0.20), and all of them together by at most `max_total_curio_discount` (0.50). A cast that cost mana never becomes free. With Covenant installed, the Blasphemy discount still applies after it. The shipped tag lists Iron's school focus items, which are not normally wearable; packs add their own curios. `enable_curio_discounts` covers both discounts.
- **`#ars_n_spells:cross_cast_blacklist`.** Ars Zero's five multi-phase glyphs only work inside a Spell Staff. A spell using them is now refused by the Spell Loom, `/ans export_to_irons_scroll`, Spell Transcription and every cross-cast, with a message naming the glyphs.
- `/ans info` also lists the player's affinity levels and the number of registered Iron's schools. Its raw Iron's mana line is translatable, and the ring-bypass flag appears only with Covenant installed.
- Server stop now also clears staged scroll costs, cast-validation scopes, in-flight cross-casts, combat diagnostics and log throttles.
- The "Cross spell selected" message is translatable, and cross-cast refusals are shown in red.
- Config comments match the NeoForge build. The `mana_unification_mode` comment no longer claims a restart is needed, because mode changes apply live.
- The debug-only startup lock check looks at `ars_n_spells-server.toml`, not the pre-2.0.1 `-common.toml`.
- New GameTests: combat bridge (11), `ParityBehaviourGameTests` (Source Jar synergy, gear bonus per mode, potion mirroring, tagged curios), uninscription teardown, the Curios attribute toggle, Ars Zero profile, resolver-hook and blacklist checks, proxy pool reuse and the carrier reconciler. `tools/verify_loader_parity.py` now ships here too and checks both directions, including GameTest coverage.
release
Ars 'n Spells 3.2.4
3.2.44 сент. 2026 г.4 тыс.Minecraft: 1.21.1neoforge
Что нового
## [3.2.4] - 2026-09-02 — Performance Improvements
### Improved
* **Mana Well** rituals now use a much lighter player check instead of repeatedly scanning nearby entities.
* Reduced unnecessary per-tick mod compatibility checks.
* Shared mana limits now only sync when the value actually changes, reducing unnecessary network traffic.
* **Resonance** now syncs only when its value changes instead of every few seconds.
No gameplay, config, network protocol, or save-data changes.
release
Ars 'n Spells 3.2.4
3.2.44 сент. 2026 г.1,5 тыс.Minecraft: 1.20.1forge
Что нового
## [3.2.4] - 2026-09-02 — Performance Improvements
### Improved
* **Mana Well** rituals now use a much lighter player check instead of repeatedly scanning nearby entities.
* Reduced unnecessary per-tick mod compatibility checks.
* Shared mana limits now only sync when the value actually changes, reducing unnecessary network traffic.
* **Resonance** now syncs only when its value changes instead of every few seconds.
No gameplay, config, network protocol, or save-data changes.
release
Ars 'n Spells 3.2.2
3.2.229 авг. 2026 г.1,1 тыс.Minecraft: 1.21.1neoforge
Что нового
## [3.2.2] - 2026-08-28
A major stability, compatibility, and polish update focused on **rituals, mana integration, scroll reliability, spellbook compatibility, and cleaner Ars Nouveau ↔ Iron's Spells integration**.
### New Ars 'n' Spells Creative Tab
Ars 'n' Spells now has its own dedicated Creative Mode tab containing:
* Spell Loom
* Spell Transcription Tablet
* Spellbook Binding Tablet
* Spell Uninscription Tablet
* Mana Infusion Tablet
* Mana Well Tablet
These items no longer clutter the vanilla Functional Blocks or Ars Nouveau tabs, while remaining available through Creative Search and JEI/EMI.
Items requiring Iron's Spells 'n Spellbooks only appear when Iron's is installed.
### Mana Infusion & Mana Well Rituals
Two previously inaccessible rituals can now actually be crafted and used.
* **Mana Infusion** grants mana to the nearest player when completed.
* **Mana Well** regenerates mana for players inside its area.
Both now have:
* Craftable ritual tablets.
* Proper item models and textures.
* Enchanting Apparatus recipes.
* Full localization.
Both require **Iron's Spells 'n Spellbooks**.
### Fixed Fake Ars 'n' Spells Loot Scrolls
Iron's loot systems could previously generate useless scrolls containing Ars 'n' Spells' internal `ars_cross_*` proxy spells.
These could appear in:
* Exploration chests.
* Mystery Scroll Pouches.
* Mob drops.
* Wandering Trader offers.
* Other Iron's random-spell rewards.
They now correctly opt out of random loot generation.
Existing dud proxy scrolls are repaired into **blank Iron's scrolls** when used instead of consuming resources or doing nothing.
Missing proxy descriptions have also been added so any remaining visible proxy displays readable text instead of a raw translation key.
### Fixed One Mana Bar Compatibility
Fixed a mixin conflict with **One Mana Bar** that could prevent entire modpacks from starting.
* Mana integration now uses safer compatibility hooks.
* `ARS_PRIMARY` behavior continues to work when other mods replace Iron's casting logic.
* Optional integration failures now disable the affected feature instead of bringing down the entire modpack.
* Startup diagnostics now correctly report which integrations actually loaded.
### Fixed Iron's Scroll Costs
Iron's scrolls had unintentionally been casting **completely free** in previous releases.
They now correctly follow:
`scroll_cost_mode`
Available behavior includes:
* `full` — normal spell cost. **Default**
* `lp_only` — pay LP instead.
* `free` — intentionally retain free casting.
### Fixed Hybrid Mana Wipes
Fixed a serious issue where casting an Ars Nouveau spell in **HYBRID mana mode** could unexpectedly delete a large portion of the player's mana.
* Ars and Iron's now agree on the correct maximum mana.
* Equipment bonuses are handled properly.
* Dimension changes no longer break the shared mana ceiling.
* Mana validation and actual costs now use the same calculation.
* Very cheap spells no longer accidentally round down to free casts.
### Fixed Iron's Inscription Table Crashes
ANS-exported scrolls could previously crash clients or dedicated servers when used with Iron's **Inscription Table**.
* Newly exported scrolls now contain valid Iron's scroll data.
* Older affected scrolls are repaired when encountered.
* Incompatible ANS carriers are safely rejected.
* Empty spells can no longer accidentally be written into spellbooks.
### Fixed Spell Loom Scroll Crashes
* Fixed malformed or outdated Spell Loom scrolls potentially crashing the client when hovered.
* Invalid scroll data now fails safely.
* Improved validation and repair of legacy exported scrolls.
* Empty carriers no longer incorrectly enter Iron's normal casting path.
### Fixed Unbinding Ars Spells
Removing an Ars spell from an Iron's spellbook now properly removes its entry from the spell wheel.
Previously, unbinding could leave behind selectable but unusable spell entries.
### Fixed Virtue Ring Free Casting
Fixed the **Virtue Ring** allowing completely free Ars spellcasting when its Aura system was disabled.
Mana and Aura behavior now consistently follows the intended configuration.
### Cleaner JEI, EMI & Creative Menus
Internal `ars_cross_*` proxy spells are now hidden from normal player-facing lists and recipes.
They no longer clutter:
* JEI
* EMI
* Iron's Scrolls tab
* Scroll Forge recipes
* Arcane Anvil recipes
* Random Iron's loot
The proxies remain internally available so existing bound spellbooks continue working.
### Improved Spell School Detection
Ars spells are now assigned to magical schools more accurately.
This improves:
* Elemental affinity.
* Iron's spell-power scaling.
* Multi-school glyph handling.
* Ars Elemental compatibility.
Filter glyphs no longer incorrectly determine an entire spell's school.
Addon glyph-school mappings can also be supplied through datapacks.
### Missing Addon Glyph Protection
Stored spells are now checked to make sure **all required glyphs still exist**.
Previously, uninstalling a glyph addon could silently remove missing glyphs and leave behind a different but still castable spell.
ANS now refuses to bind or cast incomplete spells and reports which glyphs are missing.
### Improved Spellbook Detection
Iron's spellbooks are now detected through Iron's supported interfaces and tags rather than relying on item-name matching.
This improves compatibility with custom and addon spellbooks.
### Fixed Ritual & Spell Textures
* Ritual tablets now use proper Ars 'n' Spells artwork instead of missing textures.
* Added fallback icons for Ars spells shown through Iron's spell wheel.
* Added automated checks to prevent items from shipping without required models or textures.
### Additional Reliability Improvements
* Spell-related transactions now use Minecraft game time, avoiding problems caused by lag or paused worlds.
* ANS-owned item data now includes a schema version for safer future migrations.
* Improved warning rate limits to prevent malformed scrolls from flooding server logs.
* Added stronger automated checks for mixins, item assets, rituals, scrolls, and addon compatibility.
* Expanded compatibility testing with **Ars Elemental** and **Too Many Glyphs**.
### Compatibility
* Existing worlds remain compatible.
* Existing bound spellbooks continue to work.
* Existing malformed ANS scrolls are repaired when encountered where possible.
* Datapack support remains compatible.
* Optional integrations now fail more safely instead of preventing the entire game from loading.
release
Ars 'n Spells 3.2.2
3.2.229 авг. 2026 г.428Minecraft: 1.20.1forge
Что нового
## [3.2.2] - 2026-08-28
A major stability, compatibility, and polish update focused on **rituals, mana integration, scroll reliability, spellbook compatibility, and cleaner Ars Nouveau ↔ Iron's Spells integration**.
### New Ars 'n' Spells Creative Tab
Ars 'n' Spells now has its own dedicated Creative Mode tab containing:
* Spell Loom
* Spell Transcription Tablet
* Spellbook Binding Tablet
* Spell Uninscription Tablet
* Mana Infusion Tablet
* Mana Well Tablet
These items no longer clutter the vanilla Functional Blocks or Ars Nouveau tabs, while remaining available through Creative Search and JEI/EMI.
Items requiring Iron's Spells 'n Spellbooks only appear when Iron's is installed.
### Mana Infusion & Mana Well Rituals
Two previously inaccessible rituals can now actually be crafted and used.
* **Mana Infusion** grants mana to the nearest player when completed.
* **Mana Well** regenerates mana for players inside its area.
Both now have:
* Craftable ritual tablets.
* Proper item models and textures.
* Enchanting Apparatus recipes.
* Full localization.
Both require **Iron's Spells 'n Spellbooks**.
### Fixed Fake Ars 'n' Spells Loot Scrolls
Iron's loot systems could previously generate useless scrolls containing Ars 'n' Spells' internal `ars_cross_*` proxy spells.
These could appear in:
* Exploration chests.
* Mystery Scroll Pouches.
* Mob drops.
* Wandering Trader offers.
* Other Iron's random-spell rewards.
They now correctly opt out of random loot generation.
Existing dud proxy scrolls are repaired into **blank Iron's scrolls** when used instead of consuming resources or doing nothing.
Missing proxy descriptions have also been added so any remaining visible proxy displays readable text instead of a raw translation key.
### Fixed One Mana Bar Compatibility
Fixed a mixin conflict with **One Mana Bar** that could prevent entire modpacks from starting.
* Mana integration now uses safer compatibility hooks.
* `ARS_PRIMARY` behavior continues to work when other mods replace Iron's casting logic.
* Optional integration failures now disable the affected feature instead of bringing down the entire modpack.
* Startup diagnostics now correctly report which integrations actually loaded.
### Fixed Iron's Scroll Costs
Iron's scrolls had unintentionally been casting **completely free** in previous releases.
They now correctly follow:
`scroll_cost_mode`
Available behavior includes:
* `full` — normal spell cost. **Default**
* `lp_only` — pay LP instead.
* `free` — intentionally retain free casting.
### Fixed Hybrid Mana Wipes
Fixed a serious issue where casting an Ars Nouveau spell in **HYBRID mana mode** could unexpectedly delete a large portion of the player's mana.
* Ars and Iron's now agree on the correct maximum mana.
* Equipment bonuses are handled properly.
* Dimension changes no longer break the shared mana ceiling.
* Mana validation and actual costs now use the same calculation.
* Very cheap spells no longer accidentally round down to free casts.
### Fixed Iron's Inscription Table Crashes
ANS-exported scrolls could previously crash clients or dedicated servers when used with Iron's **Inscription Table**.
* Newly exported scrolls now contain valid Iron's scroll data.
* Older affected scrolls are repaired when encountered.
* Incompatible ANS carriers are safely rejected.
* Empty spells can no longer accidentally be written into spellbooks.
### Fixed Spell Loom Scroll Crashes
* Fixed malformed or outdated Spell Loom scrolls potentially crashing the client when hovered.
* Invalid scroll data now fails safely.
* Improved validation and repair of legacy exported scrolls.
* Empty carriers no longer incorrectly enter Iron's normal casting path.
### Fixed Unbinding Ars Spells
Removing an Ars spell from an Iron's spellbook now properly removes its entry from the spell wheel.
Previously, unbinding could leave behind selectable but unusable spell entries.
### Fixed Virtue Ring Free Casting
Fixed the **Virtue Ring** allowing completely free Ars spellcasting when its Aura system was disabled.
Mana and Aura behavior now consistently follows the intended configuration.
### Cleaner JEI, EMI & Creative Menus
Internal `ars_cross_*` proxy spells are now hidden from normal player-facing lists and recipes.
They no longer clutter:
* JEI
* EMI
* Iron's Scrolls tab
* Scroll Forge recipes
* Arcane Anvil recipes
* Random Iron's loot
The proxies remain internally available so existing bound spellbooks continue working.
### Improved Spell School Detection
Ars spells are now assigned to magical schools more accurately.
This improves:
* Elemental affinity.
* Iron's spell-power scaling.
* Multi-school glyph handling.
* Ars Elemental compatibility.
Filter glyphs no longer incorrectly determine an entire spell's school.
Addon glyph-school mappings can also be supplied through datapacks.
### Missing Addon Glyph Protection
Stored spells are now checked to make sure **all required glyphs still exist**.
Previously, uninstalling a glyph addon could silently remove missing glyphs and leave behind a different but still castable spell.
ANS now refuses to bind or cast incomplete spells and reports which glyphs are missing.
### Improved Spellbook Detection
Iron's spellbooks are now detected through Iron's supported interfaces and tags rather than relying on item-name matching.
This improves compatibility with custom and addon spellbooks.
### Fixed Ritual & Spell Textures
* Ritual tablets now use proper Ars 'n' Spells artwork instead of missing textures.
* Added fallback icons for Ars spells shown through Iron's spell wheel.
* Added automated checks to prevent items from shipping without required models or textures.
### Additional Reliability Improvements
* Spell-related transactions now use Minecraft game time, avoiding problems caused by lag or paused worlds.
* ANS-owned item data now includes a schema version for safer future migrations.
* Improved warning rate limits to prevent malformed scrolls from flooding server logs.
* Added stronger automated checks for mixins, item assets, rituals, scrolls, and addon compatibility.
* Expanded compatibility testing with **Ars Elemental** and **Too Many Glyphs**.
### Compatibility
* Existing worlds remain compatible.
* Existing bound spellbooks continue to work.
* Existing malformed ANS scrolls are repaired when encountered where possible.
* Datapack support remains compatible.
* Optional integrations now fail more safely instead of preventing the entire game from loading.
release
Ars 'n Spells 3.0.1
3.0.16 июл. 2026 г.4,4 тыс.Minecraft: 1.21.1neoforge
Что нового
## [3.0.1] — full 3.0.x parity with 1.20.1: native spell wheel + Spell Loom (2026-07-05)
Ports the entire Forge 1.20.1 3.0.0/3.0.1 line (including its audit remediation) onto NeoForge
1.21.1, aligning version numbers so 3.0.1 means the same feature set on both game versions.
Compile targets: **Ars Nouveau 5.11.1 / Iron's Spellbooks 1.21.1-3.16.0** (the Iron's pin was
bumped from 3.15.6 to match the play instance; every API this release touches was re-verified
against the 3.16.0 jar). Build- and test-verified (60 JUnit tests, 0 failures); in-game runtime
validation per TESTING_GUIDE.
### Added — Ars spells in Iron's native spell wheel (3.0.0 feature A+B)
- **Export → bind workflow.** An Ars Nouveau spell is exported onto a real `irons_spellbooks:scroll`
carrier (`ArsSpellExportUtil`), then bound onto a real Iron's spellbook
(`IronsBookBindingUtil.appendArsSpellToBook`), where it appears as **its own entry in Iron's
native spell wheel** and casts through Iron's native right-click flow.
- **Proxy-spell pool.** Eight real registered Iron's spells (`ars_n_spells:ars_cross_1..8`,
`ArsCrossProxyRegistry` on `SpellRegistry.SPELL_REGISTRY_KEY`) drive the wheel entries. Each
proxy has mana cost 0 (the delegated Ars cast pays the real cost exactly once), ENDER school
(never blocked by "not learned"), instant cast, no cooldown. `IronsProxySlotWriter` grows the
book's native container capacity so the player's real Iron's spells are never evicted.
- **Data model.** `CrossModSpell` gains additive `proxy_pool_id` / `custom_name` / `nature` /
`icon_symbol` fields with backward-compatible codecs — components written by 2.6.1 decode
unchanged, and entries without proxy metadata encode byte-identically to the 2.6.1 shape.
- **Wheel cosmetics.** New client mixin `MixinAbstractSpellArsIcon` (gated on Iron's presence,
`require = 0`) substitutes the player-chosen name and a whitelisted nature/icon texture in the
wheel. 17 icon textures ship under `textures/gui/icons/spell/`, plus
`textures/gui/spell_icons/ars_cross_1..8.png` as Iron's un-mixed fallback path so a skipped
mixin degrades gracefully instead of showing a missing texture.
- **Spellbook Binding ritual** (`spellbook_binding` tablet, apparatus recipe, brazier ritual):
drop one carrier scroll + one Iron's spellbook; validates fully before mutating, consumes ONE
scroll (stacks preserved), reports DUPLICATE/BOOK_FULL precisely. Config:
`allow_ars_spells_in_irons_spellbooks` (default true) and
`max_ars_cross_spells_per_irons_spellbook` (default -1 = pool-size bound).
- **Commands** `/ans export_to_irons_scroll` and `/ans bind_scroll_to_irons_book` (permission 2).
- **Tooltips.** `CrossSpellTooltipHandler` (client) shows inscribed-spell entries and cast/cycle
hints on any inscribed item.
- Right-clicking an Iron's **spellbook** now always defers to Iron's native flow — the ANS
sidecar right-click cast no longer hijacks spellbook clicks.
### Added — Spell Loom workstation (3.0.0 feature C)
- **First block in the mod**: craftable Spell Loom (gold + lapis + book + obsidian). Right-click
opens a 3-slot menu (Ars source + blank Iron's scroll → carrier output) with a name field and
nature/icon cyclers. The inscribe action is a server-authoritative payload
(`SpellLoomExportPayload`): the server re-reads the block entity slots, validates the scroll,
clamps the name to 40 chars, and whitelists nature/icon keys. Hoppers can interact via the
item-handler block capability. Ships blockstate/models/textures, loot table, shaped recipe,
and recipe-unlock advancement (all at singular 1.21 datapack paths).
### Fixed — audit ports from the 1.20.1 3.0.x line
- **ANS-CRIT-005 (world-load deadlock risk):** `RegenSynergyHandler`'s Source-Jar scan now verifies
all covered chunks are loaded (non-loading `hasChunk` via new pure `ChunkScanUtil`) before
reading block states, clamps Y to build height, and skips-and-retries near unloaded chunks.
New config: `enable_source_jar_synergy` (kill switch, default true),
`source_jar_scan_interval_ticks` (20, 1–200), `source_jar_scan_radius` (4, 1–8).
- **ANS-CRIT-002 / ANS-HIGH-030 (SEPARATE-mode mana integrity):** the Iron's share of a dual-cost
cast is now pre-paid atomically with the sufficiency check during Ars cost-calc (previously the
post-cast TAIL consume silently swallowed failures — a one-way Ars drain), and a failed Ars leg
**refunds** the pre-paid Iron's share via the secondary bridge.
- **F1 (apparatus recipes uncraftable with Iron's loaded):** pedestal ingredient
`irons_spellbooks:spell_book` is not a registered item (Iron's ships 16 tiered books). Recipes
now use the new `#ars_n_spells:irons_spell_books` tag (entries `required: false`, so the tag
loads Iron's-less).
- **3.0.1 config screen:** full legibility pass (owned near-opaque background so blur mods can't
frost it, bounded panel, row stripes with hover, real button chrome with shared render/click
geometry, description truncation + hover tooltip, scrollbar) and full read-only gating in
multiplayer. Fixed "Reset Toggles" wrongly setting `enable_cooldown_system` to true (TOML
default is false). Moved to `client/screen/` (audit F3).
- **Payload registration hardening:** all payloads register unconditionally (an Iron's-gated
registration could fail channel negotiation when server/client disagree on Iron's presence);
network protocol bumped to "2" so 2.6.1 ↔ 3.0.1 cross-connects are cleanly rejected.
- **F5:** the remaining direct `enable_mana_unification` read in `RegenSynergyHandler` now routes
through `BridgeManager.isUnificationEnabled()`. **F6:** `/reload`-safety of the ritual-tablet
splice documented on `RitualRegistryHandler`.
### Removed — dead configuration (ANS-MED-044 / F4 + subsystem-gone keys)
- Removed 59 config keys no code ever read: the Ars Glyph Bonuses and Iron's School Bonuses
sections, 4 resonance caps, category-cooldown keys, `allow_discount_stacking`, the Performance
keys (`mana_sync_interval`, `enable_caching`, `cache_duration`), `hybrid_sync_rate`,
`allow_mana_overflow`, and — 1.21.1-only, because Blood Magic / Covenant of the Seven have no
1.21.1 builds — the entire Cursed Ring LP, Aura, and Blasphemy sections plus
`hide_mana_bar_with_ring` and `scroll_cost_mode` (its reader mixin was never ported; re-add
key + mixin together if the feature returns). Kept: `virtue_ring_discount` and
`max_total_curio_discount` (repurposed by the live curio discount system) and the resonance
master keys (parity with 1.20.1).
release
Ars 'n Spells 3.0.1
3.0.16 июл. 2026 г.3,1 тыс.Minecraft: 1.20.1forge
Что нового
## [3.0.1] - 2026-07-05
### Fixed config screen readability/blur issue
- The in-game config screen now paints its own near-opaque background and a bordered content panel instead of relying on the vanilla translucent dim — client blur mods/shaders (the "frosted glass" look) can no longer make it unreadable. Rows have background stripes with hover highlight, high-contrast shadowed text, and the ON/OFF and Mana Mode controls are drawn as real bordered buttons whose hitboxes exactly match the drawn rect (previously a 20px hitbox floated over a 35px row). Long descriptions truncate with a hover tooltip instead of overflowing. ([ConfigScreenFactory.java](src/main/java/com/otectus/arsnspells/config/ConfigScreenFactory.java))
- **Fixed: boolean toggles were clickable in multiplayer read-only mode** — the click silently mutated only the client's SERVER-config mirror (cycle rows were already gated). All row controls are now gated on `canMutate`, render disabled on dedicated-server clients, and the screen shows "Read-only: server-managed config. Edit the server TOML or use /ans commands."
- "Reset Toggles" now resets `enable_cooldown_system` to its actual TOML default (`false`); it previously set it to `true`.
### Source Jar synergy: kill switch + tuning (follow-up to the ANS-CRIT-005 chunk-load deadlock fix)
- Fixed in 2.6.2/3.0.0 and hardened here: the Source Jar synergy scan could touch (and synchronously load) chunks during player tick in ≤2.6.1, which could contribute to chunk-load deadlocks. The scan now remains guarded by a non-loading `hasChunk` check, and this release adds server-owner controls around it.
- New keys under `Source Jar Synergy`: `enable_source_jar_synergy` (default `true` — the supported off switch; when `false` the periodic scan is skipped entirely), `source_jar_scan_interval_ticks` (default 20, range 1–200), and `source_jar_scan_radius` (default 4, hard cap 8 — at most a 2×2 chunk area). Existing TOMLs are auto-upgraded with defaults; no keys renamed. The multiplier keeps its 0.1 minimum — use the kill switch to disable, not a zero multiplier. The kill switch is also exposed as a toggle in the config screen.
- The chunk-coverage math behind the scan guard moved to [ChunkScanUtil.java](src/main/java/com/otectus/arsnspells/util/ChunkScanUtil.java) with direct unit coverage; skipped scans are still retried and never cached.
- With `debug_mode = true`, a rate-limited counter summary (scans run / skipped due to unloaded chunks / jar hits, plus a slow-scan warning) is logged at most once per minute — counters only, never per-block.
### Fixed: crash at boot on installs without Iron's Spellbooks
- `MixinArsPotionEffects` targets an Ars Nouveau class but its bytecode references Iron's `AttributeRegistry`; on an Iron's-less install the mixin processor failed with `ClassMetadataNotFoundException` while transforming `ManaCapEvents`, which made Ars Nouveau itself fail to load and killed the server during startup. The mixin is now gated on Iron's presence in [ArsNSpellsMixinPlugin.java](src/main/java/com/otectus/arsnspells/mixin/ArsNSpellsMixinPlugin.java) — it only has an effect when Iron's is the primary mana system, so nothing is lost. (Found because the Iron-less GameTest profile could not boot.)
### Full-codebase audit remediation
Remediation from the 3.0.1 full-codebase audit (see [AUDIT_FINDINGS.md](AUDIT_FINDINGS.md), [AUDIT_ARCHITECTURE.md](AUDIT_ARCHITECTURE.md)).
#### Fixed: transcription/binding ritual tablets were uncraftable when Iron's is loaded
- Both apparatus recipes used pedestal ingredient `irons_spellbooks:spell_book`, which is **not a registered item** — Iron's registers only tiered books (`copper_spell_book`, …, `legendary_spell_book`). With Iron's installed, both recipes failed to parse (`JsonSyntaxException: Unknown item`) and the Spell Transcription / Spellbook Binding tablets could not be crafted. The recipes now accept any tiered Iron's spell book via a new shipped item tag [`ars_n_spells:irons_spell_books`](src/main/resources/data/ars_n_spells/tags/items/irons_spell_books.json) (all entries optional, so the tag also loads cleanly on Iron's-less installs). Pack makers can override the tag to restrict tiers.
- `pack.mcmeta` now declares the correct 1.20.1 data-pack format (15; was 12).
#### Fixed: LP cost participants gated on inconsistent config toggles
- `MixinSanctifiedAbstractSpell` bypassed Covenant of the Seven's native LP/death check based on `enable_mana_unification` instead of the LP system's own `enable_lp_system` master toggle: with unification off + LP on, both ANS and Covenant processed the cost (the double-penalty/instant-death interaction the bypass exists to prevent); with unification on + LP off, Covenant was bypassed with nobody charging LP. The scroll LP path in `MixinScrollItem` had no LP-system gate at all, so scrolls kept charging LP with the system disabled. Both now key off `enable_lp_system` (default unchanged: `true`).
#### Changed
- Mode-dependent features (equipment mana bridging, Source Jar synergy, mana-bar hiding) now consistently respect `mana_unification_mode = "disabled"` even when the `enable_mana_unification` master toggle is still `true` — previously each site re-implemented the precedence check and this state behaved inconsistently. `BridgeManager.isUnificationEnabled()` is the documented single source of truth.
- The three scroll LP action-bar messages are now translatable (`message.ars_n_spells.lp.*`); English text unchanged.
- `ConfigScreenFactory` moved from the common `config` package to `client/screen` (it is a client `Screen`; the old location risked dedicated-server classloading if ever referenced from common code).
- Removed the redundant `MixinIronsManaBarOverlay` — `ManaBarController` already cancels Iron's mana-bar overlay via `RenderGuiOverlayEvent.Pre` before the mixin's injection point could ever run. Visual behavior unchanged.
- Removed the dead `IronsLPHandler.storePendingScrollLP` (no callers; scroll costs stage through `ScrollLPTracker`). If any pack invoked it reflectively, that call will now fail to resolve.
## [3.0.0] - 2026-07-02
### Export Ars spells onto Iron's scrolls and bind them into spellbooks
The Ars → scroll → spellbook workflow is the headline 3.0.0 feature. An Ars Nouveau spell can now be exported onto a real `irons_spellbooks:scroll` and then bound into a real Iron's spellbook, where it casts through Ars 'n' Spells' existing server-authoritative cross-cast pipeline. The Ars spell is preserved as an opaque ANS sidecar payload (`arsnspells:cross_spells`) on the real Iron item, coexisting untouched with Iron's own `ISB_Spells` container — no lossy translation into Iron's registry slot model.
- **New binding ritual + tablet.** [SpellbookBindingRitual.java](src/main/java/com/otectus/arsnspells/rituals/SpellbookBindingRitual.java) consumes a carrier scroll and appends its Ars entry onto a spellbook in range, with full pre-mutation validation and translated feedback. The tablet is registered in [ModItemsRegistry.java](src/main/java/com/otectus/arsnspells/registry/ModItemsRegistry.java) only when Iron's is loaded; the [recipe](src/main/resources/data/ars_n_spells/recipes/apparatus/spellbook_binding.json) is wrapped in `forge:conditional`.
- **New export/bind utilities.** [ArsSpellExportUtil.java](src/main/java/com/otectus/arsnspells/spell/ArsSpellExportUtil.java) and [IronsBookBindingUtil.java](src/main/java/com/otectus/arsnspells/spell/IronsBookBindingUtil.java) recognize Iron items by registry id (no top-level Iron's imports) and dedup bound spells by their serialized `ars_spell` payload, not the shared placeholder id.
- **New commands.** `/ans export_to_irons_scroll` and `/ans bind_scroll_to_irons_book` (permission level 2) provide a developer/admin path. [ArsNSpellsCommands.java](src/main/java/com/otectus/arsnspells/commands/ArsNSpellsCommands.java).
- **Cross-spell tooltips.** [CrossSpellTooltipHandler.java](src/main/java/com/otectus/arsnspells/events/CrossSpellTooltipHandler.java) surfaces embedded Ars spells, the active index, and cast/cycle hints on Iron scrolls and spellbooks (still used for generic non-spellbook carriers).
### Ars spells in Iron's native spell wheel + the Spell Loom workstation
Bound Ars spells now appear as their own entries in **Iron's native spell-selection wheel** and cast through Iron's native right-click flow (instead of the ANS sidecar right-click), and are authored at a new **Spell Loom** block.
- **Registered proxy-spell pool.** [ArsCrossProxySpell](src/main/java/com/otectus/arsnspells/spell/irons/ArsCrossProxySpell.java) + [ArsCrossProxyRegistry](src/main/java/com/otectus/arsnspells/spell/irons/ArsCrossProxyRegistry.java) register a finite pool (`ars_cross_1..8`) of real Iron's `AbstractSpell`s into `SpellRegistry`. Each occupies one wheel slot; its `onCast` reads the casting book's sidecar entry (matched by pool id) and delegates to `CrossCastingHandler.castArsSpell`, so cost flows once through `onArsSpellCost`/`BridgeManager` (proxy `getManaCost` is 0; no double-charge). Iron's-gated; never classloads without Iron's. These are **real registered spells, not forged ids** — avoiding the lookup/UI-crash risks of fake Iron's spell ids.
- **Native container write.** [IronsProxySlotWriter](src/main/java/com/otectus/arsnspells/spell/irons/IronsProxySlotWriter.java) adds each proxy into *grown* container capacity, so a player's existing Iron's spells are never evicted. [IronsBookBindingUtil.appendArsSpellToBook](src/main/java/com/otectus/arsnspells/spell/IronsBookBindingUtil.java) allocates a distinct pool id (the wheel de-dupes by spell id) and enforces the per-book cap; it returns a typed `AppendResult` (`ADDED`/`DUPLICATE`/`BOOK_FULL`/`FAILED`).
- **Custom name + icon in the wheel.** Client-only [MixinAbstractSpellArsIcon](src/main/java/com/otectus/arsnspells/mixin/irons/MixinAbstractSpellArsIcon.java) substitutes the per-spell name and icon for proxy entries (`require = 0`, so a future Iron's change degrades to a static fallback rather than crashing). The loom's chosen **icon symbol** (spark/flame/leaf/bolt/star/eye/drop/moon — 8 shipped 16×16 icons) takes priority; the nature icon is the fallback. The icon **color** control was dropped pre-release: Iron's `getSpellIconResource` returns a plain texture path with no tint hook, so a color could never render. Both the nature and icon keys are whitelisted server-side in [SpellLoomExportPacket](src/main/java/com/otectus/arsnspells/network/SpellLoomExportPacket.java) so crafted packets can't stamp NBT that resolves to a missing texture.
- **Native right-click preserved.** [CrossCastingHandler.onRightClickItem](src/main/java/com/otectus/arsnspells/spell/CrossCastingHandler.java) now defers to Iron's native flow for Iron's spellbooks (no more hijack); the ANS right-click/sneak-cycle path remains for generic inscribed items.
- **Spell Loom workstation.** New block + block entity + menu + screen ([block/](src/main/java/com/otectus/arsnspells/block/), [SpellLoomMenu.java](src/main/java/com/otectus/arsnspells/menu/SpellLoomMenu.java), [SpellLoomScreen.java](src/main/java/com/otectus/arsnspells/client/screen/SpellLoomScreen.java)): drop an Ars source + a blank Iron's scroll, set a name/nature/icon, and inscribe a carrier scroll via the server-authoritative [SpellLoomExportPacket](src/main/java/com/otectus/arsnspells/network/SpellLoomExportPacket.java). Craftable; appears in the Functional Blocks creative tab.
- **New config.** `allow_ars_spells_in_irons_spellbooks` (default `true`) and `max_ars_cross_spells_per_irons_spellbook` (default `-1` = no cap, bounded by the pool size 8) under Cross-Cast Inscription.
- **Localised diagnostics.** The previously-raw `arsnspells.crosscast.invalid.*` validator messages are now translated.
- **Limitation / compat.** At most 8 Ars spells per book show in the native wheel (Iron's `SpellData` stores only id/level/locked and the wheel merges by id). Network protocol version bumped `2 → 3`.
### Pending-cost race fix (free-cast / mischarge on rapid casts)
The Virtue Ring (aura), Cursed Ring (LP), and Iron's-LP handlers staged a pending resource cost at cost-calc and consumed it at the deferred resolve. They each used a **single-entry** `Map<UUID, PendingX>`, so back-to-back casts of delayed-resolution spells (e.g. Ars projectiles whose `SpellResolveEvent.Post` fires on impact) overwrote each other's staged cost — the first cast paid the second's price and the second cast went free.
- **Per-player FIFO queue.** [VirtueRingHandler.java](src/main/java/com/otectus/arsnspells/events/VirtueRingHandler.java), [CursedRingHandler.java](src/main/java/com/otectus/arsnspells/events/CursedRingHandler.java), and [IronsLPHandler.java](src/main/java/com/otectus/arsnspells/events/IronsLPHandler.java) now store a `Deque<PendingX>` per player: enqueue at cost-calc, poll FIFO (skipping expired heads) at resolve. No cast goes free and no staged cost is dropped. Empty deques are evicted by the periodic sweep and on logout, not in the hot consume path (which would race a concurrent cost-calc reusing the same deque).
### Critical fix: world-load deadlock (also shipped standalone as 2.6.2)
- **Fixed a server-thread deadlock while loading chunks.** The Source-Jar regen-synergy scan ([RegenSynergyHandler.java](src/main/java/com/otectus/arsnspells/events/RegenSynergyHandler.java)) called `getBlockState` across a 9×4×9 volume around each player with no loaded-chunk check; near an unloaded chunk border (login, teleport, dimension change, chunk streaming) this forced a synchronous chunk load on the server thread, freezing the game inside `ServerChunkCache.getChunkBlocking`. The scan now verifies the (at most 4) covered chunks are loaded first and retries next cycle otherwise, never caching a result from a skipped scan; its Y range is clamped to world build height. (ANS-CRIT-005)
### High-severity fixes
- **Closed a post-cast invulnerability window.** In safe mode (`death_on_insufficient_lp = false`), [LPDeathPrevention](src/main/java/com/otectus/arsnspells/events/LPDeathPrevention.java)'s death-event safety net cancelled ANY lethal magic/sacrifice damage while the LP-immune flag was set — and the flag lingers up to ~3s after every successful Cursed-Ring cast, silently negating unrelated killing blows (PvP spells, hostile casters, Blood Magic effects). The death handler now enforces the same same-tick scope as the hurt handler. (ANS-HIGH-028)
- **Server config values are now applied at world load.** The mana-bridge mode was cached at common setup, before the SERVER-type config file is read, so a non-default `mana_unification_mode` / `enable_mana_unification` in `ars_n_spells-server.toml` was silently ignored until someone ran `/ans mode set`. [BridgeManager](src/main/java/com/otectus/arsnspells/bridge/BridgeManager.java) now re-selects on every config load/reload and initializes defensively (DISABLED until real values exist). The init banner/self-check now logs once per session instead of on every world load. (ANS-HIGH-029)
- **Failed SEPARATE-mode cross-casts no longer drain Iron's mana.** The Iron's share of a dual-cost cross-cast is pre-consumed during the Ars cost-calc (ANS-CRIT-002); if the Ars leg then failed (insufficient Ars mana, downstream cancel), that payment was silently kept. [CrossCastingHandler](src/main/java/com/otectus/arsnspells/spell/CrossCastingHandler.java) now records the pre-payment on the cast context and refunds it via the secondary bridge on every failed-cast path. (ANS-HIGH-030)
### Medium fixes
- **Scroll `full` cost mode now actually charges mana.** [MixinScrollItem](src/main/java/com/otectus/arsnspells/mixin/irons/MixinScrollItem.java) validated the mana cost and then charged nothing (Iron's scrolls never deduct mana natively). The cost is now staged at HEAD and consumed at RETURN only when Iron's accepts the use, via the new `CastingAuthority.consumeIronsSpellMana` (mirrors the validation conversion exactly). (ANS-MED-043)
- **Scroll LP staging migrated to per-player FIFO.** [ScrollLPTracker](src/main/java/com/otectus/arsnspells/compat/ScrollLPTracker.java) used a single overwriting slot, so a second scroll use before the first's RETURN clobbered the first's staged cost (the same race the ring handlers' deque migration fixed); entries leaked until logout if another mod suppressed the RETURN. Now a per-player deque with a 5s TTL and opportunistic eviction. (ANS-MED-042)
- **Removed ~20 config options that were never read** (silent modpack-tuning traps): the entire *Ars Glyph Bonuses* section (`amplify_damage_bonus`, `extend_time_duration_bonus`, `split_projectile_count`, `pierce_armor_penetration`, `sensitive_crit_bonus`), the entire *Iron's School Bonuses* section (`enable_school_bonuses`, `school_bonus_multiplier`, ten `*_school_*` per-level values), four of the five resonance caps (`max_duration_multiplier`, `max_projectile_split`, `max_chain_chance`, `max_area_multiplier` — only `max_damage_multiplier` is enforced), `enable_category_cooldowns`, `cooldown_reduction_cap`, `allow_discount_stacking`, `mana_sync_interval`, `enable_caching`, `cache_duration`. Setting any of these had no effect; they can return alongside real implementations. (ANS-MED-044)
- **Rituals consume one item, not the whole stack.** [SpellTranscriptionRitual](src/main/java/com/otectus/arsnspells/rituals/SpellTranscriptionRitual.java) and [SpellbookBindingRitual](src/main/java/com/otectus/arsnspells/rituals/SpellbookBindingRitual.java) discarded the entire source/scroll `ItemEntity`; a stacked input (Iron's scrolls stack to 16) lost the extras.
### Hardening / consistency
- **Fixed packet ids.** [PacketHandler](src/main/java/com/otectus/arsnspells/network/PacketHandler.java) registered `ResonanceSyncPacket` only when Iron's was loaded, shifting every later message id with Iron's presence. All packets now register unconditionally with fixed ids (the packet touches no Iron's classes).
- [CooldownSyncPacket](src/main/java/com/otectus/arsnspells/network/CooldownSyncPacket.java) wraps its client-mirror write in the same `DistExecutor` client guard as its sibling S2C packets.
- [MixinArsPotionEffects](src/main/java/com/otectus/arsnspells/mixin/ars/MixinArsPotionEffects.java) resolves its two target `MobEffect`s once instead of reverse-registry-scanning every active effect twice per player tick. (OPT-019)
- [MixinResourceBarOverlay](src/main/java/com/otectus/arsnspells/mixin/covenant/MixinResourceBarOverlay.java)'s label `@Redirect` is pinned to `ordinal = 0` so a future Covenant build can't get stray " / peak" suffixes on other bars.
- Deleted dead `util/SafeCasterContext.java` (zero callers; superseded by reading `event.context` directly).
- The in-game config screen's save toast now says the save is scheduled (the write is async; the log is the source of truth) instead of unconditionally claiming success.
- The Spell Loom recipe ships an unlock advancement (recipe toast on picking up a book); the loom's icon button label is now translatable (`ars_n_spells.spell_loom.icon` + `ars_n_spells.icon.*`).
### Tests
- **Iron-loaded GameTests.** [CrossCastGameTests.java](src/main/java/com/otectus/arsnspells/gametest/CrossCastGameTests.java) replaces the previous unconditional `helper.succeed()` placeholders with a real CYCLE test driven through `CrossCastingHandler.serverHandleCast` and an Iron-loaded export→bind→coexist round-trip on real `irons_spellbooks` items. The round-trip self-skips when Iron's is absent and runs under the new opt-in `-PwithIronsRuntimeGameTests` profile ([build.gradle](build.gradle)).
- New unit tests: chunk-guard source assertions for the deadlock fix, death-handler tick scope, SEPARATE-mode refund bookkeeping, ScrollLPTracker FIFO/mana-cost carriage.
### Dev environment (build-time only, no player impact)
- **Compile classpath corrected to Ars Nouveau 4.12.7.** `ars_nouveau_file` pointed at CurseMaven file 4781441, which is Ars **4.5.0** — the mod compiled against a different Ars API than the `[4.12.7,4.13)` range mods.toml requires. Now pinned to file 6688854 (4.12.7).
- **Forge build target 47.2.0 → 47.4.0**, the minimum Iron's 3.15+ accepts (players have been on 47.4.x all along; `loaderVersion` stays `[47,)`).
- **Runnable dev environment.** GeckoLib + Curios (Ars' runtime graph) are now `runtimeOnly`, and PlayerAnimator rides the `-PwithIronsRuntimeGameTests` profile, so `runClient`/`runGameTestServer` boot without hand-copied jars. GameTest structure templates are staged from `src/test/resources/gameteststructures/` into the run dir by the new `stageGameTestStructures` task (vanilla/Forge ship none — the suite previously crashed at batch setup with "Could not find structure file gameteststructures/platform.snbt").
release
Ars 'n Spells 2.6.0
2.6.015 июн. 2026 г.927Minecraft: 1.20.1forge
Что нового
## [2.6.0] - 2026-06-14
### Apotheosis / Apothic Curios mana bridge
Affixed and socketed **curios** (rings, amulets, belts) now contribute their mana stats to the unified Ars ↔ Iron's pool. The equipment scanner already read attribute modifiers off armor and weapons — so Apotheosis affixes there always worked — but the curio path read only `IManaEquipment` and Ars enchantments, so an affixed/socketed ring's max-mana or mana-regen never reached the cross-mod bridge. A Mana Battery Ring took effect in its own system's pool but was invisible to the other.
- **Curios attribute modifiers are now read and mirrored.** [EquipmentIntegration.java](src/main/java/com/otectus/arsnspells/equipment/EquipmentIntegration.java) enumerates worn curios via the Curios API (`CuriosApi.getCuriosInventory(...).findCurios(...)`) and reads each slot's aggregated attribute modifiers (`CuriosApi.getAttributeModifiers(slotContext, uuid, stack)`), summing Ars `max_mana`/`mana_regen` and Iron's `max_mana`/`mana_regen` through the **same `sumModifiers` helper and ADDITION-only rule the armor path uses**. This routes Apotheosis (with Apothic Curios) affixes & sockets — and any other curio mana gear such as Magical Jewelry or Jewelcraft — through the existing bridge. No double-counting: the curio's own pool already gets the modifier natively; the bridge only mirrors it to the other system, exactly as armor does.
- **No hard Apotheosis dependency.** The read is generic (any mod's curio mana attributes), gated behind the new `read_curio_attribute_modifiers` config (default on) and wrapped so any API surprise degrades to "no bonus" rather than a crash.
- **Spell power needed no change** — it is read from the player's *total* attribute, so affix spell power on armor/weapons/curios already counted. Apothic Attributes' own attributes (crit, armor pierce, fire/cold damage) are combat-only and out of scope for the mana/spell bridge.
- **Build:** [build.gradle](build.gradle) adds a `compileOnly` Curios API dependency (`5.9.1+1.20.1`, the version Ars Nouveau bundles at runtime). Curios is always present at runtime via Ars, so this only puts the slot-aware API on the compile classpath.
### Ring / aura-HUD correctness and hardening
- **Aura-bar peak tracker is now lock-free.** [ClientAuraPeakTracker.java](src/main/java/com/otectus/arsnspells/client/ClientAuraPeakTracker.java) stores the personal peak in an `AtomicInteger` with a monotonic `getAndUpdate` ratchet, so the render-thread read in the HUD mixin composes cleanly with client-tick writes (and stays correct if a sync writer is ever added).
- **Covenant version-drift probe.** [ArsNSpellsClient.java](src/main/java/com/otectus/arsnspells/client/ArsNSpellsClient.java) logs at startup whether Covenant of the Seven is at the version the aura-bar HUD mixin (`MixinResourceBarOverlay`) was bytecode-verified against (2.2.6). The mixin uses `require = 0`, so a mismatch can't crash the client; this makes the silent fallback diagnosable instead.
- **Virtue aura system honors its toggle.** [VirtueRingHandler.java](src/main/java/com/otectus/arsnspells/events/VirtueRingHandler.java) now short-circuits its handlers when `ENABLE_VIRTUE_AURA_SYSTEM` is off.
- **Dead alternate-resource stubs removed.** [CastingAuthority.java](src/main/java/com/otectus/arsnspells/casting/CastingAuthority.java) dropped the never-implemented `detectAlternateResourceCost`/`validateAlternateResource` path (it always returned null/true); Cursed/Virtue ring costs are owned by their dedicated event handlers.
### Performance (render + tick hot paths)
- **OPT-008:** [MixinArsPotionEffects.java](src/main/java/com/otectus/arsnspells/mixin/ars/MixinArsPotionEffects.java) only churns the mana attribute modifiers when the value actually changed, instead of a remove/add every server tick (which forced an attribute recompute).
- **OPT-009:** [ManaBarController.java](src/main/java/com/otectus/arsnspells/client/ManaBarController.java) matches mana overlays on the `ResourceLocation` namespace/path directly (allocation-free `equals`) instead of `toString()` + substring scan every overlay every frame. The matchers are extracted as pure, package-private, unit-testable methods.
- **OPT-010 / MED-019:** [OverlayDiagnostics.java](src/main/java/com/otectus/arsnspells/client/OverlayDiagnostics.java) registers its per-frame render subscriber on the Forge bus only while diagnostics are enabled (zero dispatch cost when off, the default), and uses a `TreeSet` for already-sorted iteration.
- **IronsLP debug trace gated.** [IronsLPHandler.java](src/main/java/com/otectus/arsnspells/events/IronsLPHandler.java) builds its per-cast entry-trace strings only when `LOGGER.isDebugEnabled()`.
### Tests
- New unit coverage for the above: [ClientAuraPeakTrackerTest](src/test/java/com/otectus/arsnspells/client/ClientAuraPeakTrackerTest.java) (monotonic ratchet), [ManaBarControllerOverlayMatchTest](src/test/java/com/otectus/arsnspells/client/ManaBarControllerOverlayMatchTest.java) (overlay matchers), and [VirtueRingAuraToggleTest](src/test/java/com/otectus/arsnspells/config/VirtueRingAuraToggleTest.java) (toggle gating).
release
Ars 'n Spells 2.5.0
2.5.015 июн. 2026 г.1,8 тыс.Minecraft: 1.21.1neoforge
Что нового
## [2.5.0] — 1.21.1 compatibility & correctness (2026-06-06)
A correctness-focused compatibility release on top of the build-verified 2.0.1 core.
The bridge / cross-casting / progression / resonance / rituals stack is unchanged; this
release fixes the largest parity gaps, restores two silently-broken datapack features,
and hardens optional-mod handling. Compile targets stay pinned to the build-verified
**Ars Nouveau 5.11.1 / Iron's Spellbooks 3.15.6**; the target pack runs **AN 5.11.7 /
ISS 3.16.0** at runtime (event- and registry-based code tolerates the delta — see
*Known limitations*). **Build- and test-verified; in-game runtime validation remains
pending** (the build environment runs no Minecraft).
### Fixed — datapack paths (were build-green but runtime-broken)
- **Ritual recipes are obtainable again.** The Spell Transcription / Uninscription
apparatus recipes shipped under the 1.20.1 plural path `data/ars_n_spells/recipes/…`,
which Minecraft 1.21 no longer reads (it loads `recipe/`, singular — verified against
the Ars Nouveau and Iron's jars). They never loaded, so the ritual tablets were
uncraftable in survival. Moved to `data/ars_n_spells/recipe/apparatus/`.
- **Ritual recipes now parse.** Once relocated, the same apparatus recipes surfaced a
second carryover — the 1.20.1 recipe schema (`output`/`item`, `reagent` as an array),
which fails AN's current `enchanting_apparatus` codec with `No key result`. Migrated to
the 1.21 form (`result` with `id`+`count`, `reagent` as a single object); verified
against the live pack (AN 5.11.7) so the Transcription/Uninscription tablets craft at
the Enchanting Apparatus. A `ResourcePresenceTest` schema check now guards the format.
- **Curio spell discount works again.** The `#ars_n_spells:curio_spell_discount` item tag
shipped at the plural `tags/items/` path (1.20.1) instead of 1.21's `tags/item/`, so it
never loaded and the discount was permanently inert. Moved to `tags/item/`, and the tag
now ships a sensible default (`#irons_spellbooks:school_focus`, optional).
### Added / changed — affinity now covers every Iron's addon school
- **Dynamic, addon-aware affinity.** Affinity was keyed by a hardcoded 16-value
`AffinityType` enum, so the ~19 addon schools in the target pack
(`cataclysm_spellbooks:abyssal`, `iss_magicfromtheeast:spirit`, `somakespells:aqua`, …)
earned no affinity at all — the Iron's handler dropped every school not in the enum.
Affinity is now stored as a `Map<String,Integer>` keyed by the full school id (mirroring
progression), so **every registered Iron's school tracks automatically**, with no
per-mod code. New `SchoolKeys` (the single canonical-key source shared by both handlers
and the damage-scaling site) and an Iron's-gated `SchoolIndex` registry snapshot for
`/ans` diagnostics.
- **Fixed the mirrored Ars-side drop bug.** `aqua`/`geo`/`wind` (words the Ars glyph
heuristic emits but the enum lacked) threw in `AffinityType.valueOf` and were silently
lost; they now track under `ars_n_spells:*` keys.
- **Safe save migration.** `AffinityData` uses a versioned codec; a 2.0.x save (bare map
of enum-name keys) migrates losslessly — the nine elemental tracks are renamed
(`FIRE` → `irons_spellbooks:fire`) with counts intact and re-stamped on first save
(idempotent). **Owner decision (default):** the seven legacy category/source buckets
(OFFENSIVE/DEFENSIVE/UTILITY/MOVEMENT/ARCANE/PRIMAL/HYBRID) are dropped on migration —
they were never real schools and current code never wrote them. Back up saves if you
want to be cautious; flip to quarantine on request.
- `/ans info <player>` now lists the player's non-zero affinity tracks and (with Iron's)
the registered school count.
### Added — Curios discount, both sides
- The tagged-curio mana discount now applies to **Iron's** casts too
(`SpellOnCastEvent.setManaCost`), not just Ars casts. The slot scan is shared via a new
`compat/curios/CuriosAccess`. New `max_total_curio_discount` config (default 0.50) caps
the combined discount so stacked curios can't trivialise mana cost.
### Hardened — optional-mod & version resilience
- All mana/resolver mixin injects now carry `require = 0`, so an Ars/Iron's point-release
method-signature change fails soft (skips the inject) instead of crashing mod load. The
mixin plugin additionally probes the Ars target classes (`ManaCap`/`ManaData`/
`SpellResolver`) so a class rename also fails soft. (Shadow *field* drift remains fatal —
the eventual event-first migration is the real fix; see *Known limitations*.)
- New `compat.ModPresence` (cached multi-mod presence) + `compat.CompatIds`; `IronsCompat`
delegates to them. Lightweight foundation; the full module framework is deferred.
- New `#ars_n_spells:magical_companions` entity-type tag (aggregates `#ars_nouveau:familiar`
+ `#irons_spellbooks:summons`, optional) as datapack scaffolding for future summon synergy.
### Tests
- `ResourcePresenceTest` asserts every shipped data/asset file exists, parses, and sits at
the correct singular 1.21 path (regression guard for the directory-flattening bug above).
- `SchoolKeysTest` pins the Ars↔Iron's key agreement and the aqua/geo/wind fix.
- `AffinityDataMigrationTest` covers the versioned codec round-trip and the 2.0.x → 2.5.0
legacy migration (rename, bucket drop, re-stamp, clamp).
### Known limitations
- **Compile vs runtime version delta.** Pinned to AN 5.11.1 / ISS 3.15.6; pack runs
5.11.7 / 3.16.0. A post-2.5.0 task is to validate in-game and optionally move the compile
classpath up. Mixin **shadow-field** drift (e.g. an AN field rename) would still crash on
load — `require = 0` covers method drift only; migrating the mana bridge to AN/ISS events
is the durable fix and is deferred.
- **In-game validation pending** (build env has no Minecraft): cast one spell per addon
school → affinity increments under the correct id; load a 2.0.x save → elemental tracks
migrate with counts intact, buckets dropped; tagged-curio cast drops cost on both Ars and
Iron's within the clamp; client + dedicated-server boot with/without Iron's and Curios;
ritual tablets craftable at the apparatus.
- Covenant LP / aura / virtue / blasphemy remain **N/A** (Branch B). The dead Covenant
config keys are intentionally retained to match the canonical 2.0.1 config.
release
Ars 'n Spells 2.0.0
2.0.029 мая 2026 г.2,7 тыс.Minecraft: 1.20.1forge
Что нового
## [2.0.0] - 2026-05-14
### Audit-driven major release
2.0.0 addresses the comprehensive technical audit at [ars-n-spells-2.0.0.md](ars-n-spells-2.0.0.md). Every High and Medium-High hypothesis in the audit's "Ranked Root-Cause Hypotheses" maps to a closed fix below. The major-version bump reflects two breaking changes (new C2S packet ID; clients older than 2.0.0 cannot cross-cast against a 2.0.0 server) plus the architectural reorganization of the cross-cast pipeline.
### Phase 1 — Hotfix (cross-cast actually works again)
- **Client-side cancellation no longer swallows the cast.** [CrossCastingHandler.java](src/main/java/com/otectus/arsnspells/spell/CrossCastingHandler.java) used to call `handleCrossCast` on both sides, return `true` on the logical client, and then `event.setCanceled(true)` — so on a dedicated server the client claimed success and cancelled the use, while the server never received any cast trigger. Silent "input detected, nothing happens" failure. The client now short-circuits before any cast logic and sends a new `CrossCastRequestPacket` instead; the server is the sole authority over cast execution.
- **Cross-cast decoupled from mana unification.** The previous `BridgeManager.isUnificationEnabled()` guard in [`CrossCastingHandler.onRightClickItem`](src/main/java/com/otectus/arsnspells/spell/CrossCastingHandler.java), [`CrossCastingHandler.onArsSpellCost`](src/main/java/com/otectus/arsnspells/spell/CrossCastingHandler.java), and [`CrossCastIronsHandler.onIronsSpellCast`](src/main/java/com/otectus/arsnspells/spell/CrossCastIronsHandler.java) made inscribed items inert whenever `mana_mode=disabled` or `enable_mana_unification=false`. The README documents `disabled` as a *mana sharing* mode, not as a master switch for cross-cast. Settled policy: cross-cast remains available in every mode; the multiplier still applies; in `disabled` mode, native upstream pools pay native costs (no SEPARATE split, no ARS_PRIMARY conversion). The unification check survives as an internal mode-branch flag inside each cost site.
### Phase 2 — Stabilization (multiplayer authoritative + traceable)
- **New C2S [`CrossCastRequestPacket`](src/main/java/com/otectus/arsnspells/network/CrossCastRequestPacket.java).** Carries hand, action (`CAST`/`CYCLE`), client-observed index, and a client-generated attempt UUID. The server handler re-reads the held stack (no client trust), generates its own attempt UUID for trace correlation, and dispatches to the new `CrossCastingHandler.serverHandleCast` entry point.
- **New [`PacketHandler.sendToServer`](src/main/java/com/otectus/arsnspells/network/PacketHandler.java).** Helper for the new C2S direction. `CrossCastRequestPacket` is registered at the *tail* of the packet ID list so pre-existing IDs (Resonance, Affinity, Cooldown, Aura) do not shift.
- **New [`CrossCastValidator`](src/main/java/com/otectus/arsnspells/spell/CrossCastValidator.java).** Single authority for cross-cast payload validity. Checks index range, payload non-emptiness, spell-type resolution (with namespace fallback), Ars `ars_spell` non-empty, Iron's `spell_id` parseability + level ≥ 1 + registry resolution. Rejections produce a translation key the player sees via `displayClientMessage` and a structured `descriptor_rejected` trace event. The four-arg public API is the production path; a package-private overload accepts a synthetic Iron's predicate so unit tests do not need Forge bootstrap. 16-case [`CrossCastValidatorTest`](src/test/java/com/otectus/arsnspells/spell/CrossCastValidatorTest.java) covers every branch.
- **`attemptId` UUID on [`CrossCastContext.Entry`](src/main/java/com/otectus/arsnspells/spell/CrossCastContext.java).** Threaded from the packet handler through `serverHandleCast`, into `CrossCastContext.begin(...)`, and read back at every Ars/Iron mixin and event-handler trace point. Parallel cross-casts no longer alias their logs.
- **New [`util/CrossCastTrace`](src/main/java/com/otectus/arsnspells/util/CrossCastTrace.java).** Structured logger emitting `[CrossCastTrace] attempt=<uuid> player=<name> side=<C|S> stage=<symbolic> k=v …` exactly as specified in the audit's "Debug Instrumentation Plan". Gated on `debug_mode`. Stages: `INPUT_DETECTED`, `REQUEST_SENT`, `REQUEST_RECEIVED`, `DESCRIPTOR_VALIDATED`, `DESCRIPTOR_REJECTED`, `RESOURCE_CHECK`, `RESOURCE_SPEND`, `ARS_COST_APPLIED`, `IRON_COST_APPLIED`, `UPSTREAM_CAST_ENTER`, `UPSTREAM_CAST_EXIT`, `EFFECT_APPLIED`, `CYCLE_APPLIED`. Used from [`CrossCastingHandler`](src/main/java/com/otectus/arsnspells/spell/CrossCastingHandler.java), [`CrossCastIronsHandler`](src/main/java/com/otectus/arsnspells/spell/CrossCastIronsHandler.java), [`MixinSpellResolverPreCast`](src/main/java/com/otectus/arsnspells/mixin/ars/MixinSpellResolverPreCast.java), and [`MixinSpellResolverMana`](src/main/java/com/otectus/arsnspells/mixin/ars/MixinSpellResolverMana.java).
- **New [`CrossCastCostResolver`](src/main/java/com/otectus/arsnspells/spell/CrossCastCostResolver.java).** Single source of truth for the cross-cast cost algorithm — captures the mode × multiplier × ring state matrix in one place. Returns a `CostBreakdown(primary, secondary, primaryMode, secondaryMode, mode, unified, ringActive, multiplier)` record. Three stages: `ARS_PRECALC`, `IRON_PRECALC`, `IRON_POSTEVENT`. For 2.0.0 this is an authoritative *calculator* — existing cost-mutation sites still own choreography (event mutation, mixin cancels, ring pending-cost stamping); full delegation onto the resolver is tracked for 2.0.1.
- **New [`CapabilityResyncHandler`](src/main/java/com/otectus/arsnspells/events/CapabilityResyncHandler.java).** Single owner of bridge-capability resync across `PlayerLoggedInEvent`, `PlayerRespawnEvent`, and `PlayerChangedDimensionEvent`. Replays Affinity (one packet per non-zero school), Cooldown (one packet per active category), and Resonance (when Iron's is loaded). Aura is *not* duplicated here — [`AuraCapabilityProvider`](src/main/java/com/otectus/arsnspells/aura/AuraCapabilityProvider.java) already covers all three events from 1.10.0. The previous `AffinitySyncOnLoginHandler` is retired; its login coverage is subsumed.
### Phase 3 — Hardening
- **Sealed [`SpellDescriptor`](src/main/java/com/otectus/arsnspells/spell/SpellDescriptor.java) model** with [`ArsSerializedSpellDescriptor`](src/main/java/com/otectus/arsnspells/spell/ArsSerializedSpellDescriptor.java) and [`IronsRegistrySpellDescriptor`](src/main/java/com/otectus/arsnspells/spell/IronsRegistrySpellDescriptor.java). Typed adapter between the two upstream spell models with uniform `validate/serialize/displayName/resolve/systemType/spellId`. On-disk NBT shape is unchanged so pre-2.0.0 inscribed items round-trip cleanly via `SpellDescriptor.parse(CompoundTag)`. Full migration of call sites off raw `CompoundTag` maps onto descriptors is tracked for 2.1.0.
- **New [`CastContext`](src/main/java/com/otectus/arsnspells/spell/CastContext.java) value record.** Threads attempt UUID + player + hand + source stack + descriptor + mode + cost breakdown through the pipeline. Existing sites still pass individual parameters; full migration is tracked for 2.1.0.
- **GameTest scaffold.** [`build.gradle`](build.gradle) gains a `gameTestServer` run target gated on the `ars_n_spells` namespace. [`CrossCastGameTests`](src/main/java/com/otectus/arsnspells/gametest/CrossCastGameTests.java) ships one sanity scenario confirming the scaffold is wired; the full seven-scenario suite from the audit's "Testing and Validation Strategy" lands in 2.0.1 alongside the structure NBT templates each scenario requires.
- **CI workflow.** [`.github/workflows/ci.yml`](.github/workflows/ci.yml) — JDK 17 on Ubuntu, gradle and ForgeGradle caches, `./gradlew compileJava test` as the required-status job, `./gradlew runGameTestServer` as an advisory job (continue-on-error true while the GameTest suite is still landing).
### Breaking changes
- **Packet ID list grew.** `CrossCastRequestPacket` is appended at the tail of `PacketHandler.register()`, so existing packet IDs (Resonance, Affinity, Cooldown, Aura) are unchanged. Clients older than 2.0.0 cannot cross-cast against a 2.0.0 server — they cannot send the new packet. Servers older than 2.0.0 cannot serve 2.0.0 clients — they will reject the new packet ID. Use matching client/server versions.
- **`AffinitySyncOnLoginHandler` removed.** Its login-sync responsibility is fully subsumed by `CapabilityResyncHandler` (which adds respawn + dimension sync). No user-facing behavior change for affinity on login.
- **`mana_mode=disabled` now permits cross-cast.** Previously, setting the mode to disabled (or `enable_mana_unification=false`) made inscribed items inert. They now cast normally with native upstream pool costs; only mana *sharing* is suppressed in disabled mode. Modpacks that intentionally wanted cross-cast disabled by setting `mana_mode=disabled` will see cross-cast become available again — there is no separate `enable_cross_casting` toggle; the feature is now always-on whenever an inscribed item is held.
### Known follow-ups (deferred to 2.0.1 / 2.1.0)
- **2.0.1**: full site delegation onto `CrossCastCostResolver` (current 2.0.0 has the resolver but call sites still own choreography); `CrossCastCostResolverTest` with the mode × ring × stage matrix (needs a `BridgeManager.testSetMode` test-only seam).
- **2.0.1**: the seven cross-cast GameTest scenarios (clean Ars cast, clean Iron cast, malformed NBT rejection, insufficient resources, dimension transition, separate-mode dual cost, ring + cross-cast) — each needs its own structure NBT template.
- **2.1.0**: full migration of `CrossCastingHandler` / `CrossCastValidator` call sites off raw `CompoundTag` maps onto `SpellDescriptor`; `CastContext` threaded through the pipeline.
- **2.1.0**: server/client config split, datapack registries for spell schools / cooldown categories / progression rules / cross-cast rules.
### Backward compatibility
- **Save format unchanged.** AffinityData, ProgressionData, CooldownData, AuraCapability, and `arsnspells:cross_spells` NBT shapes all preserved. Inscribed items from 1.8.9+ load and cast unchanged at 2.0.0.
- **Mod config unchanged.** No keys added, removed, or renamed. The `mana_mode=disabled` semantics change is documented above.
- **Mixin injection points unchanged.** All Ars `SpellResolver` injects keep their `@At` targets and method signatures. Mixin-compatible with Ars 4.12.7+; no Iron's-side mixin changes.
### Ring of Virtues and Ring of Curses — correctness pass
Investigation found five correctness bugs in the Sanctified Legacy / Covenant of the Seven ring integration. Symptoms ranged from "the rings silently do nothing on a C7-only modpack" to "the player pays both mana and aura on the same spell after unequipping the ring mid-cast." All are fixed in 1.10.0.
- **`hasBothRings` AND-gate fix.** [SanctifiedLegacyCompat.java:222](src/main/java/com/otectus/arsnspells/compat/SanctifiedLegacyCompat.java) returned `false` whenever **either** Covenant of the Seven **or** Enigmatic Legacy was missing. But C7 ships both rings — meaning a C7-only modpack with both rings equipped silently dropped through every ring path: `isWearingCursedRing` cancelled out, `isWearingVirtueRing` cancelled out, ring-conflict notification never fired, and the player paid mana while believing aura was being consumed. The guard is now `&&` instead of `||`. `hasMatchingBlasphemy` was also tightened to use `isAvailable()` for consistency.
- **Stale pending-cost can't leak across spells anymore.** [VirtueRingHandler](src/main/java/com/otectus/arsnspells/events/VirtueRingHandler.java) and [CursedRingHandler](src/main/java/com/otectus/arsnspells/events/CursedRingHandler.java) used to consume the pending aura/LP cost purely on UUID lookup at `SpellResolveEvent.Pre`. If another HIGHEST-priority handler cancelled a spell between `SpellCostCalcEvent` and `SpellResolveEvent.Pre`, the pending cost lingered for up to 5 seconds; the next spell — even with the ring unequipped — was charged aura/LP **and** mana ([MixinSpellResolverMana](src/main/java/com/otectus/arsnspells/mixin/ars/MixinSpellResolverMana.java) only cancels mana if you're currently wearing the ring). Both handlers now re-verify `isWearingVirtueRing` / `isWearingCursedRing` at every consumption site and drop the stale entry if state changed.
- **Resolve consumption moved from Pre to Post.** Consuming on `SpellResolveEvent.Pre` meant that if another mod cancelled the cast at Pre after our HIGHEST handler ran, the resource was charged but the spell never executed ("paid but didn't cast"). Aura/LP is now charged on `SpellResolveEvent.Post`, which only fires for resolved (non-cancelled) spells. Validation continues to happen at `canCast` ([MixinSpellResolverPreCast](src/main/java/com/otectus/arsnspells/mixin/ars/MixinSpellResolverPreCast.java)) so impossible casts still get blocked cleanly. Pre is kept as a state-drift gate that drops the pending entry if the ring came off between cost-calc and resolve.
- **Iron's Spellbooks + Virtue Ring path now exists.** Previously, casting any Iron's spell while wearing the Virtue Ring drained Iron's mana — only the Cursed Ring had an Iron's handler. Symmetric coverage with the new [IronsAuraHandler](src/main/java/com/otectus/arsnspells/events/IronsAuraHandler.java): pre-cast validation against the aura pool, mana zeroed at `SpellOnCastEvent`, aura consumed instead. Insufficient aura cancels the cast with an action-bar message (no death penalty — Virtue Ring failure is intentionally non-punitive). Iron's scrolls get the same treatment via a new aura branch in [MixinScrollItem](src/main/java/com/otectus/arsnspells/mixin/irons/MixinScrollItem.java) plus [ScrollAuraTracker](src/main/java/com/otectus/arsnspells/compat/ScrollAuraTracker.java) for the HEAD→RETURN commit pattern that ScrollLPTracker already uses.
- **`AuraCapability` no longer corrupts new players.** [AuraCapability.java](src/main/java/com/otectus/arsnspells/aura/AuraCapability.java) used to read `AURA_MAX_DEFAULT` in its constructor and fall back to **100** on `IllegalStateException`. `AttachCapabilitiesEvent` can fire before `ModConfigEvent.Loading`, so any player created before config load was permanently capped at 100 aura (10% of the configured default of 1000). The capability now defers initialization until first server-side access (so config is guaranteed loaded), and `loadNBTData` runs a one-shot migration: if a saved `maxAura == 100` and the configured default is higher, the player is reset to the configured default and an `ans_v110_migrated` marker is stamped onto the NBT so the heuristic only runs once. Users who legitimately wanted a 100-aura cap should re-apply their config preference after upgrading.
### Aura HUD and sync
The mana bar is hidden while the Virtue Ring is worn (since spells cost aura, not mana), but until now nothing replaced it — the player flew blind. 1.10.0 ships the missing pieces:
- **New** [AuraSyncPacket](src/main/java/com/otectus/arsnspells/network/AuraSyncPacket.java) — server→client sync of `(aura, maxAura)`. Sent on login, dimension change, respawn (post-clone), and whenever the server-side capability marks itself dirty and the `mana_sync_interval` tick window elapses.
- **New** [ClientAuraState](src/main/java/com/otectus/arsnspells/client/ClientAuraState.java) — client-side mirror, reset on disconnect.
- **New** [AuraBarController](src/main/java/com/otectus/arsnspells/client/AuraBarController.java) — `RenderGuiOverlayEvent.Post` overlay drawn just above the hotbar in aqua tint when the local player wears the Virtue Ring. Hidden when `mc.options.hideGui`, when the ring isn't equipped, or when the aura system is disabled.
### Ring swap mid-cast no longer leaks
The previous handler had no signal for Curios slot changes (`LivingEquipmentChangeEvent` does not fire for Curios), so the per-player curio cache could stay stale for up to a second and a stamped pending cost could be consumed against the wrong wearer state. The cleanup now happens at the consumption site instead: both `SpellResolveEvent.Pre` and `SpellResolveEvent.Post` in the ring handlers re-check `isWearingVirtueRing` / `isWearingCursedRing` (with the freshness provided by the 20-tick `SanctifiedLegacyCompat` curio cache) and drop the pending entry when state has changed. A dedicated `CurioChangeEvent` listener that would cut the "ring just equipped → not active yet" latency from ~1 s to instant is deferred — the event class is not on this mod's transitive compile classpath without an extra `compileOnly` dependency declaration.
### Configuration
- **New: `enable_aura_system`** (default `true`) — master toggle mirroring `enable_lp_system`. When false, the Virtue Ring is ignored and spells use normal mana. Useful for modpacks that want LP but not aura.
- **Removed: `virtue_ring_discount`** — the Ring of Virtue stopped being a mana discount in 1.2.0 (it converts mana to aura). The config key has been dead since then; setting it had no effect. Removed entirely in 1.10.0. Existing configs will get an "unknown key" warning on first load and can safely delete the line.
- **Changed default: `aura_minimum_cost`** is now `10` (was `5`) — matches `ars_lp_minimum_cost`. Existing configs preserve whatever value the user set.
### Commands
- **New: `/ans aura`** — non-permissioned subcommand that prints the caller's own aura value. The existing `/ans info <player>` is unchanged (still op-only).
release
Ars 'n Spells 1.6.3
1.6.326 мар. 2026 г.1,4 тыс.Minecraft: 1.20.1forge
Что нового
1. # Ars 'n' Spells v1.6.3
## Bug Fixes
- Fixed startup crash caused by `MixinSanctifiedAbstractSpell` using the wrong parameter type (`LivingEntity` instead of `Player`), preventing the game from loading when Iron's Spellbooks was present
- Fixed crash in `IronsBridge.setMana()` due to missing null check on `MagicData`
- Fixed potential crash from null `SpellRarity` when calculating LP costs for Iron's spells and scrolls
- Fixed `MixinSanctifiedAbstractSpell` not being registered in mixin config. Sanctified Legacy LP validation was completely non-functional
- Fixed `MixinSpellStatsPotency` being wrongly gated on Iron's Spellbooks. Resonance potency now works even without Iron's installed
- Fixed potential double LP charge when using spell scrolls with Cursed Ring equipped
- Fixed `BridgeManager` creating unnecessary bridge instances on every mana query when unification was disabled
## New Features
- Added `/ans mana setdefault <value>` command (op level 2) to configure default max mana at runtime
- Added `/ans mana getdefault` command to view current default max mana
- Added `ENABLE_LP_SYSTEM` config toggle to completely enable or disable the LP (Life Points) system
- Added `DEFAULT_MAX_MANA` config option (range: `1.0` to `100,000`)
- Added startup warning when dual-cost percentages do not sum to `1.0`
## Improvements
- Rewrote `LPDeathPrevention` with a flag-based immunity system, preventing Corpse mod from incorrectly triggering on LP damage
- LP system handlers now respect the `ENABLE_LP_SYSTEM` toggle across all event handlers
- Hardcoded fallback mana values now use the configurable `DEFAULT_MAX_MANA` instead of fixed `100`
- Improved error log formatting in `IronsBridge`
## Housekeeping
- Cleaned up stray build artifacts (`com/`, `nul`) from repository
- Updated `.gitignore` with missing entries
- Added Linux `gradlew` wrapper