Skip to content

MiracleLoader 1.6.0: known limits, fewer

Choose a tag to compare

@Hronosin Hronosin released this 10 Oct 09:24

1.6.0 works through the known limits: six of them are gone. Mods for 1.x work as they are.

Fallbacks with nested classes

A fallback for an older version is a partial class, and since 1.6 its nested classes work too:

  • a named nested class is whole: it replaces the real one, header and all. A class that implements an interface only the newer game has gets an older twin that doesn't;
  • anonymous and local classes are renamed (Outer$fallback$1_21_11$1) and are nestmates of the real class, so private access works;
  • what only replaced code used goes: the real class's lambdas and anonymous classes that nothing else uses any more are dropped from that version's variant, so their newer calls aren't holes. The bake notes each one.

miracle bake now compiles fallback/<v>/ only for target versions, against that version's own libraries.

Hooks that change things cost what hooks that look do

Measured first: hooks that only read were already free (the JIT removes the context), but hooks that changed something were not. On a method called 20 million times:

hook 1.5 1.6
multiplyReturnValue 35 ns, 176 B 1.2 ns, 0 B
addToArg 84 ns, 360 B 2.8 ns, 0 B
setReturnValue / cancel(value) 185 ns, 1 KB 1.2 ns, 0 B
two hooks on one method 31-53 ns 1.2-2.8 ns

The bare method costs 1.2 ns. The context keeps one set/cancel and the additions and factors for one slot without a list, and several hooks on one method are a chain of constants. The rules and results are the same: two sets, a clamp or effects on several arguments go the full way.

interceptHead on constructors

It runs before super(...): self() is null, the arguments can change, and cancel() throws, because an object can't be left half made.

Scripture: each mod's files are a pack of their own

Since 1.6 a mod's data/ and assets/ are a pack of its own, right above vanilla's, so what the game merges across packs merges:

  • tags, such as data/minecraft/tags/block/mineable/pickaxe.json or data/c/tags/item/ingots.json;
  • atlases;
  • sounds.json;
  • languages.

Before, files in the minecraft namespace were ignored, and two mods' files at the same path didn't merge. Checked in-game on 26.3 and 1.21.11, through /reload.

communes_since

Communion asked for exactly the same version on both sides. communes_since = "1.2.0" in miracle.mod.toml lets 1.3.0 meet any 1.2.x. The newer side decides, because only it knows what changed. The library declares communes_since = "1.6.0" itself.

bonfire sees a running game

The game locks each open world's session.lock. rest now refuses while it's held, and light refuses unless --anyway.

Checked

  • test.sh: 541 of 541, and the same as a Java agent.
  • Real clients 26.3 and 1.21.11:
    • Ultra Somnia 0.8 on 26.3, 26.2, 26.1.2 and 1.21.11;
    • Curse of Insomnia on 26.3;
    • Hallelujah with a probe for merged tags, languages and atlases.