164 lines
8.3 KiB
Markdown
164 lines
8.3 KiB
Markdown
# Create/Mekanism Modular
|
|
|
|
A [Truly Modular](https://modrinth.com/mod/modular-item-api) addon for Minecraft
|
|
1.21.1 / NeoForge. It adds 124 materials drawn from 20 mods - Create, Mekanism, Ice
|
|
and Fire, Immersive Engineering, Ender IO, Applied Energistics, Occultism,
|
|
Ars Nouveau, Iron's Spells, Pastel, Crystal Chronicles, NauTec, Superb Warfare,
|
|
Industrial Foregoing, RFTools, Create Deco, Steampunk Dimension and the three
|
|
Create aerospace addons - so their metals, gems, scales and essences can all be
|
|
used to build modular tools and armour.
|
|
|
|
Every source mod is optional. Install any subset - the materials for mods you do
|
|
not have are never registered.
|
|
|
|
## How it is put together
|
|
|
|
Almost all of this mod is data: MIAPI material JSON under
|
|
`src/main/resources/packs/<mod>/data/cmmodular/miapi/materials/`.
|
|
|
|
The small amount of Java exists for two reasons.
|
|
|
|
**Conditional loading.** MIAPI reads materials with its own loader, which does
|
|
not honour `neoforge:conditions` or anything else that could switch a file off,
|
|
and a material whose ingredient item is missing fails to parse. So each source
|
|
mod's materials are a separate built-in datapack, registered in
|
|
`CMModular.java` only when that mod is present.
|
|
|
|
**Identical materials are one material.** Several metals and gems come from
|
|
more than one mod - silver from Ice and Fire, Immersive Engineering, Occultism
|
|
and Superb Warfare, steel from Mekanism, Immersive Engineering and Superb
|
|
Warfare, and so on. There is one entry per metal, and every provider's version
|
|
feeds it: alongside the primary provider's own items each material also accepts
|
|
the `c:` common tag that all of them register into. Any mod's silver ingot is
|
|
just silver.
|
|
|
|
Nothing records where a stack came from, because there is nothing to record -
|
|
MIAPI stores only the material id on the item, so a tool built from Immersive
|
|
Engineering silver is indistinguishable from one built with Ice and Fire silver.
|
|
The primary provider's item is listed first, so anywhere a single representative
|
|
item is read back out - repair and deconstruct previews - it resolves to the
|
|
default rather than to whichever variant was used. Primaries are Mekanism for
|
|
steel/lead/uranium, Ice and Fire for silver, Cosmonautics for titanium; each is
|
|
a one-line change in `tools/materials.py`.
|
|
|
|
The material still lives in its primary provider's pack, so its icon and its
|
|
first ingredient always point at an item that exists. Create: The Air War is the
|
|
one provider that ships no common tags, so `data/c/` adds its titanium to
|
|
`c:ingots/titanium` with optional entries.
|
|
|
|
**Fire immunity.** Cinder essence grants immunity to fire, which is not an
|
|
attribute the game has and not a property MIAPI offers. Instead of coupling to
|
|
MIAPI's internals, `FireImmunity.java` registers a `cmmodular:fire_immunity`
|
|
attribute, the material grants it like any other attribute, and a damage handler
|
|
watches for it. Neither side knows about the other.
|
|
|
|
## Stats
|
|
|
|
Tinkers' Construct 3 is the reference, re-scaled onto MIAPI's vanilla-derived
|
|
numbers (iron 235 durability, diamond 1546, netherite 2016). Materials with no
|
|
Tinkers counterpart are built from what the material actually is, then fitted to
|
|
the nearest tier band:
|
|
|
|
| Tinkers | here | shape |
|
|
| --- | --- | --- |
|
|
| cobalt | titanium | light, fast, durable, unremarkable damage |
|
|
| steel | steel | balanced workhorse, poor enchantability |
|
|
| hepatizon | brass, bronze | copper alloys - quick and enchantable, not durable |
|
|
| manyullyn | dragonsteel | top damage, endgame gate |
|
|
| rose gold | refined glowstone, pixie dust | fragile, huge enchantability |
|
|
| ancient hide | dragon scales, chitin | armour-first, high toughness |
|
|
|
|
Tiers 6 and 7 sit above netherite: 6 is refined obsidian, shadow steel, refined
|
|
radiance, atomic alloy and the two Iron's Spells essences; 7 is the three
|
|
dragonsteels and antimatter.
|
|
|
|
Real-material character does the rest of the work - lead is the heaviest thing
|
|
here and swings slowest, osmium is dense and tough, HDPE weighs nothing and
|
|
cannot cut rock, silver smites the undead.
|
|
|
|
All of it lives in `tools/materials.py`, one entry per material with the
|
|
reasoning in comments next to the numbers.
|
|
|
|
## Palettes
|
|
|
|
Colours are not hand-picked. `tools/generate_materials.py` opens the source
|
|
mods' jars, resolves each material's item model to its texture, and samples that
|
|
texture to build MIAPI's seven-stop `grayscale_map`.
|
|
|
|
The sampling deliberately does *not* normalise a stop's colour to its brightness
|
|
number. A stop key is the brightness of MIAPI's grayscale template; its value is
|
|
whatever the material looks like at that point in its own shading, which is why
|
|
MIAPI's own netherite tops out at a murky `847a84` while iron runs to white.
|
|
Samples are taken at percentiles of the texture's brightness order, so a texture
|
|
with four shades still yields a full ramp and any hue drift between shadow and
|
|
highlight survives. Pure-black outline pixels are excluded - they are not a
|
|
shade of the material - and the darkest stop is extrapolated below the texture,
|
|
which is what MIAPI's own palettes do.
|
|
|
|
The sample points were tuned against MIAPI's hand-authored copper palette and
|
|
reproduce it to within about 2% per channel.
|
|
|
|
## Building
|
|
|
|
```sh
|
|
./gradlew build
|
|
```
|
|
|
|
Needs nothing but NeoForge - Truly Modular is a runtime dependency only, since
|
|
this mod talks to it purely through datapack JSON.
|
|
|
|
## Regenerating materials
|
|
|
|
Only needed after editing `tools/materials.py` or when a source mod changes its
|
|
textures. The generated JSON is committed, so a plain build does not need this.
|
|
|
|
```sh
|
|
python3 tools/generate_materials.py --jars ~/path/to/mod/jars
|
|
```
|
|
|
|
The folder needs one jar per source mod. Every item id in `materials.py` is
|
|
checked against those jars and the run fails on a typo, rather than shipping a
|
|
material that silently refuses to load.
|
|
|
|
Requires `pillow` and `numpy`.
|
|
|
|
## Notes
|
|
|
|
- Titanium's palette comes from Cosmonautics' ingot, which is violet. Air War's
|
|
is blue-white; swap `palette_from` on the titanium entry to prefer it.
|
|
- Cinder essence is nearly black, because its texture is a charred ember. It is
|
|
emissive, so it still reads as fire in game.
|
|
- Dragon scales are one material per colour (12 dragon, 7 sea serpent, 3 death
|
|
worm chitin). Colours within an element share stats and differ only in palette.
|
|
- Interstellar Expansion is mostly machinery. Only three of its items are a
|
|
material rather than a component; solid E-710 is left out because it is rocket
|
|
fuel.
|
|
- Gem sockets do not check the `gem` group. Arsenal gates melee gems on
|
|
`gem_melee` and Armory gates armour gems on `gem_armor`, so every gem-like
|
|
material carries both and fits any gem slot.
|
|
- Immersive Engineering contributes aluminium, nickel, constantan, electrum and
|
|
graphite. Its steel, lead, uranium and silver are not separate materials - see
|
|
overlapping metals above. Superb Warfare's steel/lead/silver and Create Crafts
|
|
& Additions' electrum are skipped for the same reason.
|
|
- Crystal Chronicles and Pastel add whole families of gems that differ by colour
|
|
and lore rather than by kind, so those are generated from a table with shared
|
|
stat bands per tier. What actually tells them apart in game is the palette,
|
|
and that still comes from each gem's own texture.
|
|
- Arcane essence gives max mana per slot: 1300 on a helmet, 900 chest, 800
|
|
legs, 700 boots, 900 held in the main hand, 400 offhand. Separate per-slot
|
|
modifiers rather than one `armor`-wide one, so a weapon reads as a held bonus
|
|
instead of claiming something "when worn". They stack per module - a piece
|
|
built out of arcane essence that also carries an arcane gem counts twice.
|
|
- Titanium adds `miapi:generic.elytra_glide_efficiency` on the chest. Heavy
|
|
armour subtracts `-30 - density*2` from that stat, so this hands a little
|
|
back rather than cancelling it; titanium's flexibility is nudged up too,
|
|
since Armory's wing modules read flexibility and density for glide.
|
|
- Cinder essence uses slot `any`, so one gem grants fire immunity wherever it
|
|
sits, worn or held. The attribute caps at 1 and the handler treats anything at
|
|
or above 1 as immune, so extra pieces neither add nor dilute.
|
|
- Material properties belong under the `default` key, not `armor` or `handheld`.
|
|
A gem socketed into armour is not tagged `armor`: gem modules declare which
|
|
material properties they accept and list only `default` plus their own gem
|
|
tags. Anything filed under `armor`/`handheld` silently never applies to a
|
|
socketed gem. The attribute's own slot is what decides where it counts.
|