Skip to content

SkyDataLayerStorageMapAccessor fails to apply when remapped by (Architectury) Loom #336

Description

@techno-sam

@Mixin(targets = "net.minecraft.world.level.lighting.SkyLightSectionStorage.SkyDataLayerStorageMap")

targets the inner class SkyLightSectionStorage$SkyDataLayerStorageMap.

Flywheel's compile-time refmap generation recognizes this, and produces the following refmap, which causes this mixin to succeed in production.

"dev/engine_room/flywheel/backend/mixin/light/SkyDataLayerStorageMapAccessor": {
  "currentLowestY": "currentLowestY:I",
  "net.minecraft.world.level.lighting.SkyLightSectionStorage.SkyDataLayerStorageMap": "net/minecraft/world/level/lighting/SkyLightSectionStorage$SkyDataLayerStorageMap",
  "topSections": "topSections:Lit/unimi/dsi/fastutil/longs/Long2IntOpenHashMap;"
}

In development environments, however, the picture can be less rosy.

(Architectury) Loom remaps the flywheel jar when depended on with modRuntimeOnly (which is the recommended dependency type for mods1) using fabric's tiny-remapper.

// https://github.com/FabricMC/tiny-remapper/blob/7834504ce1be97df03e99723bef456e40241c607/src/main/java/net/fabricmc/tinyremapper/extension/mixin/soft/annotation/MixinAnnotationVisitor.java#L49
		if (name.equals(AnnotationElement.TARGETS)) {
			return new AnnotationVisitor(Constant.ASM_VERSION, visitor) {
				@Override
				public void visit(String name, Object value) {
					String srcName = ((String) value).replaceAll("\\s", "").replace('.', '/');

					MixinAnnotationVisitor.this.targets.add(srcName);

					value = data.mapper.asTrRemapper().map(srcName);
					super.visit(name, value);
				}
			};
		}

This transforms the mixin into the following form:

@Mixin(targets = "net/minecraft/world/level/lighting/SkyLightSectionStorage/SkyDataLayerStorageMap")
public interface SkyDataLayerStorageMapAccessor {
/* ... */
}

Note that there is now a /, not a $ separating SkyLightSectionStorage and SkyDataLayerStorageMap. This slash-separated form no longer matches the refmap key, but it also doesn't match a class that exists. This causes the mixin to fail to find its target, which crashes flywheel when rendering.

Solution

Rewrite the target description (in the source) as:

@Mixin(targets = "net.minecraft.world.level.lighting.SkyLightSectionStorage$SkyDataLayerStorageMap")
public interface SkyDataLayerStorageMapAccessor {
/* ... */
}

This is also the form recommended by the fabric wiki.

Mitigations

(i.e. "I depend on Flywheel and am running into this issue")
If your mod happens to use the same mappings as flywheel, it seems to work to use runtimeOnly instead of modRuntimeOnly to depend on flywheel, but this may have side effects that I haven't noticed yet.

Footnotes

  1. where 'mod' is defined as any jar that uses minecraft classes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions