Iridescent Modular Spells Tetra Migration - silvariasereneblossom/IridescentCraft GitHub Wiki
Status: 6A done; 6B in progress (2026-04-26)
Reason: a tester directive. The design was always meant to be Tetra-native (mirroring TSB on CurseForge for ISS books, plus Ars). Phases 1-5 use a parallel NBT slot system (imodspells_slots) that doesn't work with the Tetra workbench.
License note: TSB (Tetra Spell Books, by Inolia_Zaicek on CurseForge) is All Rights Reserved. The modpack ships as a public release, so Phase 6 is a license-clean reimplementation. It mirrors TSB's structure (the slot model, schema layout and ISS/Ars stat keys, all dictated by the Tetra/ISS/Ars APIs and not copyrightable), while the Java code, JSON values and textures are our own. Decompiled TSB sources at /tmp/tsb_probe and /tmp/tsb_decomp are reference only.
- 8 modular books (5 ISS metal-cover + 3 Ars cloth-cover)
- Slot system:
imodspells_slotsNBT key withcover+pagesstrings - Material installation:
AnvilModuleInstaller.java, an anvil pattern that consumes a stack to install - Stat aggregation:
AttributeApplier.javascans the held stack every server tick, sums the per-material bonus map and applies an AttributeModifier - Tetra workbench compatibility: NONE; the Tetra UI doesn't recognize the books
- Books implement
se.mickelus.tetra.items.modular.IModularItem - Slots registered as Tetra schemas under
data/tetra/modules/double/<slot>.json - Per-material variants registered as Tetra modules / improvements
- Material installation via Tetra workbench (UI-driven, replaces
AnvilModuleInstaller) - Stat aggregation via Tetra's
getStat/getDamageModifierchain (replacesAttributeApplierfor module bonuses) - Existing
imodspells_slotsNBT migrated to TetraModulesNBT on first interaction
- A class cannot extend both
ISS.SpellBookandItemModular(Java has single inheritance), so our existing subclasses must implement theIModularIteminterface directly - Same applies to
ArsSpellBookfor Ars side - Tetra hard-deps Geckolib + tetra-mutil; both already in libs/
- Backwards compatibility for existing modular books in tester saves: NBT migration on read
- Enable
compileOnly tetra-1.20.1-6.12.0.jarin build.gradle - Add
tetraas mandatory mod dep in mods.toml (versionRange[0,)) - Bump mod version 0.1.0 β 0.2.0 to mark migration start
- Update custom-JAR allowlists in 4 locations (.bat scripts + .sh + .gitignore)
- Verify build still passes with all Phase 1-5 functionality intact
-
Commit target:
Phase 6A: enable Tetra compile dep, bump 0.2.0
- ModularSpellBookItem + ModularArsSpellBookItem implement IModularItem
- 12 abstract methods (per Tetra 6.12.0):
getItem,clearCaches,getMajorModuleKeys,getMinorModuleKeys,getRequiredModules,getHoneBase,getHoneIntegrityMultiplier,canGainHoneProgress,getAllSynergyData,getAttributeModifierCache,getEffectDataCache,getPropertyCache - Slot keys (final, derived from TSB pattern, our namespace):
- ISS:
["iss_book/core", "iss_book/front_cover", "iss_book/back_cover", "iss_book/spine", "iss_book/pages"]: 5 majors, no minors - Ars:
["ars_book/front_cover", "ars_book/back_cover", "ars_book/dye", "ars_book/spine"]: 4 majors, no minors
- ISS:
-
getRequiredModulesreturns empty array for now (so books work without modules, AttributeApplier stays authoritative through 6C) -
getHoneBase450,getHoneIntegrityMultiplier200,canGainHoneProgressfalse (TSB's convention for non-tool items) - 4 Guava caches per class (attribute / tool / effect / properties), 1000-entry / 5-min TTL
-
appendHoverTextchains: super (vanilla/ISS/Ars draws the spell list), then the existing iridescent slot tooltip, then TetragetTooltipfor the module breakdown - Books appear on Tetra workbench (UI recognizes them) but have no installed modules yet
- AttributeApplier remains authoritative for stat bonuses (read from
imodspells_slots) -
Commit target:
Phase 6B: IModularItem skeleton β books appear in Tetra workbench
Files under src/main/resources/data/iridescent_modular_spells/tetra/:
-
modules/iss_book/core/iss_core.json: the 5-majors definition for the core slot; references the custom material categoryiridescent_modular_spells:iss_books/ -
modules/iss_book/{front_cover,back_cover,spine,pages}/base_*.json: uses Tetra's built-in material tagsmetal/ wood/ stone/ gem/ skin/ fabric/ fibre/ bone/ -
modules/ars_book/{front_cover,back_cover,spine,dye}/base_*.json: the same material tag set -
schematics/...: workbench install recipes mirroringmodules/ -
materials/iss_books/{copper,iron,gold,diamond,netherite}_spell_book.json: per-base-book stat overrides (each entry'smaterial.items: [<iss_id>]registers the ISS book as a core variant) - Stat values (a starting point, open to rebalancing):
-
front_cover:**irons_spellbooks:spell_power = 0.005(multiplied by Tetra material count) -
back_cover:irons_spellbooks:max_mana = 5(flat) +**mana_regen = 0.005 -
spine:**cooldown_reduction = 0.01 -
pages:**cast_time_reduction = 0.01(tertiary) - Ars
front_cover:ars_nouveau:ars_nouveau.perk.mana_regen = 0.3 - Ars
back_cover:ars_nouveau:ars_nouveau.perk.max_mana = 3
-
- A
**prefix is multiplicative (Tetra convention); a plain prefix is additive -
Commit target:
Phase 6C: module schemas + per-material variants
- One-time migration on first stack interaction:
- Read existing
imodspells_slots.cover+pagesstrings - Use
IModularItem.putModuleInSlot(stack, ...)to seed Tetra Modules NBT - Clear old
imodspells_slotskey
- Read existing
- Remove
AttributeApplier(Tetra handles stat aggregation now) - Remove
AnvilModuleInstaller(Tetra workbench replaces it) - Recipe revisions: shapeless
<base_book> + <cloth/leather>gives the modular variant with the default cover module pre-installed -
Commit target:
Phase 6D: NBT migration + remove imodspells_slots parallel system
- Tooltips: rely on Tetra's built-in module display (replacing our manual tooltip from Phase 1)
- Codex entry update: rewrite Modular Spell Books page to reflect Tetra workflow
- Update CLAUDE.md notes about NBT migration
- Test all 6 ISS materials Γ 5 books = 30 valid combos + all 4 Ars materials Γ 3 books = 12 combos
-
Commit target:
Phase 6E: tooltip cleanup + codex rewrite + Tetra workflow docs
- 6A: 30 minutes (build config)
- 6B: 1-2 hours (interface implementation)
- 6C: 2-3 hours (schema authoring Γ 4 schemas + variant JSONs)
- 6D: 1-2 hours (migration logic + cleanup)
- 6E: 1 hour (docs)
Total: 5-8 hours focused work, spread across multiple sessions.
- The Tetra workbench UI may not handle non-tool items cleanly. The TSB mod (CurseForge) reportedly works, so it is possible, though visual quirks are possible.
- Stat translation: Tetra's stat keys (
damage,attackSpeed, etc.) don't all map cleanly to spell-book bonuses (max_mana,mana_regen). May need custom stat keys + a statβattribute bridge, similar to how Tetra integrates with attribute system. - Module visual: Tetra renders modules with overlay textures. Spell book covers may need texture authoring (or accept basic-tinted defaults).
- Backwards compat for in-game stacks: if a tester has a Phase 1-5 modular book with
imodspells_slots, the migration must run on next interaction without losing data.
- Custom Tetra schematics (no-recipe synthesis at the workbench): deferred to Phase 7
- Module enchantments via Tetra's improvement system: deferred to Phase 7
- Multi-slot modules (e.g., a single material affecting both cover + pages): deferred to Phase 7
- ISS:
iss_book/{front_cover, back_cover, spine, pages}; dropiss_book/corefromgetMajorModuleKeys. Each item is tier-locked at registration time, with no in-place tier swap. - Ars:
ars_book/{front_cover, back_cover, spine, dye}, already 4 majors.
- Front and back covers each have two install schematics:
- Main install (
displayType: major,materialSlotCount: 1): consumes a cover material from Tetra built-in categories (skin/,metal/,bone/,gem/). - Lining install (
displayType: improvement,materialSlotCount: 1): consumes a lining material; outcome routes by category to one of three improvement keys.
- Main install (
- 3 lining categories with thematic stat bonuses:
-
fabric/(wool, manaweave_cloth, sorcerer_robes, spell_cloth, silk) β mana_regen ("steady flow") -
fibre/(paper, parchment) β cast_time_reduction ("quick page turns") -
skin/(leather, rabbit_hide, vellum) β max_mana ("vessel volume") - Magic-flavor cloths sit inside
fabric/and get stronger numbers through Tetra'scountmultiplier instead of a separate stat type.
-
- Spine slot: 1-mat install only, no lining (cooldown_reduction).
- Pages slot: 1-mat install only, no lining (cast_time_reduction).
- Ars
dyeslot: cosmetic, no stat bonus (matches TSB pattern).
front_cover.main: **spell_power 0.005 (per material count)
front_cover.lining (improvement, +1 lvl):
fabric: **mana_regen 0.015
fibre: **cast_time_reduce 0.015
skin: +max_mana 8 flat
back_cover.main: +max_mana 5 (per material count)
back_cover.lining (improvement):
fabric: **mana_regen 0.020
fibre: **cooldown_reduce 0.010
skin: +max_mana 8 flat
spine: **cooldown_reduce 0.010
pages: **cast_time_reduce 0.010
ISS keys use irons_spellbooks:*; Ars keys use ars_nouveau:ars_nouveau.perk.* with the same value pattern (separate improvement JSONs per system since the attribute namespaces don't bridge).
data/iridescent_modular_spells/tetra/
βββ modules/
β βββ iss_book/{front_cover,back_cover,spine,pages}.json (4)
β βββ ars_book/{front_cover,back_cover,spine,dye}.json (4)
βββ schematics/
β βββ iss_book/
β β βββ front_cover_main.json back_cover_main.json
β β βββ front_cover_lining.json back_cover_lining.json
β β βββ spine.json pages.json (6)
β βββ ars_book/ (mirror of above) (6)
βββ improvements/
β βββ iss_book_lining_{fabric,fibre,skin}.json (3)
β βββ ars_book_lining_{fabric,fibre,skin}.json (3)
βββ replacements/
βββ {copper,iron,gold,diamond,netherite}_spell_book.json (5)
βββ {novice,apprentice,archmage}_spell_book.json (3)
Each replacement converts the vanilla ISS/Ars book into our modular variant on its first inventory tick and pre-installs default modules, so the book works out of the box (cover=leather/main + paper/lining; back_cover=leather/main + paper/lining; spine=iron; pages=paper).
Drop iss_book/core from MAJOR_KEYS in ModularSpellBookItem.java. No code change in ModularArsSpellBookItem.java (already 4 slots).
Add alongside the existing 10 classes (Archmage stays).
| Class | Element | School bonus | Drawbacks vs Archmage |
|---|---|---|---|
| Pyromancer | Fire | +50% fire_spell_power | -10% melee (vs Archmage's -25%); no stacking magic baseline |
| Cryomancer | Ice | +50% ice_spell_power | -10% melee |
| Necromancer | Blood/Eldritch | +50% blood_spell_power + +50% eldritch_spell_power | -10% melee |
| Priest | Holy | +50% holy_spell_power | -10% melee; +bonus heal-aura passive |
| Druid | Nature | +50% nature_spell_power | -10% melee; passive friendliness with neutral mobs |
| Stormcaller | Lightning | +50% lightning_spell_power | -10% melee |
Design intent: Elementalists trade Archmage's broad +50-65% all-school magic for +50% to ONE school, with milder downsides. On their own school they are no stronger than Archmage, and they are not glass cannons. No starter armor (player request).
Boss-drop integration: Elemental classes pair with the Phase 6F boss-drop books. A Pyromancer killing the ISS fire_boss to get the blaze_spell_book is the intended progression loop.
Out of scope for Phase 7 design pass: starter kits, codex entries, AStages tier gates. Those come once class JSONs exist.