What Is This?
Myth & Metal overhauls Minecraft's progression with a seven-tier rarity system, procedurally generated dungeons, custom boss fights, and new biomes. The interesting part isn't the features—it's how deep I had to go into Minecraft's internals to make them work.
Mixins into the rendering pipeline. Custom world generation via Terrablender. NBT-driven item states. This project showed me that "modding" and "reverse engineering" are pretty much the same thing.
The Rarity System
Seven tiers. Damage multipliers from 1.0× up to 5.0×. The key design choice: rarity is stored per-item, not per-item-type. Two identical swords can have different tiers. This lives in NBT tags.
Making this actually work required Mixins into ItemStack:
- Tooltip injection —
@InjectongetTooltipLinesappends the rarity display - Damage calculation —
@RedirectonEnchantmentHelper.getDamageBonusintercepts the damage math and applies tier multipliers before enchantment bonuses
Upgrading items happens at a custom anvil that extends ItemCombinerMenu. Drop in a higher-tier upgrade ingot, and the item inherits that tier.
Custom Glint Rendering
This is where things got complicated.
Each tier needed its own enchantment glint effect. That meant ~42 custom RenderType instances—7 tiers times 6 variants (basic glint, direct, entity-held, entity-direct, armor, armor-direct). Each one built with RenderType.CompositeState.builder() pointing to tier-specific glint textures.
Mixins into ItemRenderer intercept vanilla glint buffer requests and substitute the right render type based on the item's rarity. The armor mixin is more aggressive—it completely replaces render() via @Inject(at = HEAD, cancellable = true), then manually iterates equipment slots and applies tier-appropriate glints after base armor rendering.
I could have used Forge events. Mixins gave me finer control at the cost of more fragile code.
Procedural Dungeons
Dungeons are wave-based combat arenas that generate when you first enter a portal. The architecture is weird but effective: invisible trigger blocks with BlockEntity instances that manage room state.
Here's how a room activates:
- Player steps on a trigger block
- Recursive 6-directional flood-fill calculates room boundaries by propagating through adjacent
DungeonAirEntityblocks - Indestructible iron bars (
strength = -1.0F) spawn on room edges, trapping the player - Wave spawning begins—16 mobs total, max 6 alive at once
- When all mobs die, barriers vanish and trigger blocks replace themselves with air
Dungeon mobs extend vanilla counterparts with fire immunity, bonus fire damage, and die() overrides that call back to the room entity. Every mob knows which room it belongs to.
Generation Algorithm
When you enter a portal, placedungeon() runs:
- Spawn room placed at a unique offset (tracked via
SavePortalDatato prevent regeneration) - Loop: randomly pick a room type (tree, nether, bone), place the NBT structure via
StructureTemplateManager, add a hallway, advance Z by 17 blocks - Each iteration has a 10% + (10% × iteration count) chance to stop (capped at 95%)
- Boss room placed at the end
The probabilistic termination creates dungeons with an expected length of ~10 rooms but high variance. Some are short sprints. Some are marathons.
Boss Fights
Bosses like Magmaraakh (Lava Dungeon) have animation state machines with timeout counters managing idle/attack transitions. The AI goal stack prioritizes floating, then custom attack behavior, then melee, then movement.
The custom attack goal extends MeleeAttackGoal with a 40-tick wind-up before damage lands—synced to the attack animation. Stats are beefy: 550 HP, 25 armor, full knockback resistance. Boss death triggers room completion via a back-reference to DungeonRoomEntity.
World Generation
Custom biomes integrate through Terrablender, registering overworld regions with weight 4. Each region maps climate parameters to custom biomes:
- Ash Forest — Hot, arid, inland. Surface lava lakes, light-emitting ash logs, magma boulder decorations
- Enchanted Forest — Ambient
ENCHANTED_HITparticles at 0.01f density, custom sound loop, mega jungle-style trees with 2×2 trunks
Tiered ores get progressively rarer: T2 spawns 12 times per chunk across all heights, T7 spawns once per chunk below Y=-16 with triangle distribution. Tree placement uses countExtra(9, 0.5f, 7)—base 9 plus a coin flip for 7 more.
Dimension System
The dungeon dimension is registered via Forge's ResourceKey system. Fixed noon lighting, no skylight, zero ambient light, disabled beds. A FixedBiomeSource points to the dungeon biome. Portal blocks handle bidirectional transport with return coordinates stored in player persistent data.
Patterns I Relied On
- Deferred Registration — All blocks, items, and entities use Forge's lazy initialization pattern
- Distributed room state — Each trigger block has its own BlockEntity, but they share a single
DungeonRoomEntityvia flood-fill propagation - NBT persistence — Room state survives world saves via
saveAdditional()/load() - Structure composition — Dungeons are multiple NBT structures placed sequentially along Z