Universal Tweaks

Universal Tweaks

871k Downloads

Roost preregistration tweak hard crashes on startup when used with ContentTweaker MaterialSystem Parts

Delfayne opened this issue ยท 4 comments

commented

For a small, self contained example, I am (pre)registering two chickens:

CustomChickens.zs

#loader preinit
#modloaded chickens

val custom_item_chicken = ChickenFactory.createChicken("custom_item_chicken", Color.fromHex("000000"), <item:contenttweaker:ore_clump>);
custom_item_chicken.setForegroundColor(Color.fromHex("007F7F"));
custom_item_chicken.setSpawnType("NONE");
custom_item_chicken.register();

val custom_part_chicken = ChickenFactory.createChicken("custom_part_chicken", Color.fromInt(0xffffff), <item:contenttweaker:fluix_enriched_egg>);
custom_part_chicken.setForegroundColor(Color.fromInt(0x054549));
custom_part_chicken.setSpawnType("NONE");
custom_part_chicken.register();

They both lay custom ContentTweaker items. The first is created via VanillaFactory. The second is created via the ContentTweaker MaterialSystem Part to quickly create a batch of eggs that use the same icon with a tint:

ContentTweaker.zs:

#loader contenttweaker
#priority 100

var ore_clump = VanillaFactory.createItem("ore_clump");
ore_clump.register();

#Enriched Egg
mods.contenttweaker.MaterialSystem.getPartBuilder()
    .setName("enriched_egg")
    .setPartType(MaterialSystem.getPartType("item"))
    .setOreDictName("enrichedEgg")
    .build();

val eggColorMap as int[string] = {
	"Fluix" : 3342438,
};

for material, color in eggColorMap {
	val part = MaterialSystem.getMaterialBuilder()
		.setName(material)
		.setColor(color)
		.build();
	part.registerPart("enriched_egg");
	print(material + " Enriched egg registered");
}

This crashes on startup with the attached stacktrace. The VanillaFactory item does not exist during preinit, but it's okay because it registers a ghost item and this lines up fine. However this does not appear to work when the eggs are defined as Parts.
I don't think this is a failure with the tweak per se, but its potentially a situation that can come up and should be documented at least.


net.minecraftforge.fml.common.LoaderExceptionModCrash: Caught exception from ContentTweaker (contenttweaker)
Caused by: java.lang.NullPointerException
    at com.setycz.chickens.handler.ItemHolder.<init>(ItemHolder.java:54)
    at com.setycz.chickens.registry.ChickensRegistryItem.setLayItem(ChickensRegistryItem.java:184)
    at com.teamacronymcoders.contenttweaker.modules.chickens.ChickenModule.utInitChickens(ChickenModule.java:613)
    at com.teamacronymcoders.contenttweaker.modules.chickens.ChickenModule.handler$zgd000$utCTChickenInit(ChickenModule.java:544)
    at com.teamacronymcoders.contenttweaker.modules.chickens.ChickenModule.init(ChickenModule.java:28)
    at com.teamacronymcoders.base.modulesystem.ModuleHandler.lambda$init$2(ModuleHandler.java:49)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)
commented

Hi, I'm the author of the Roost tweak. I'm not too familiar with CoT's MaterialSystem, but I'm having trouble reproducing the crash. I'm getting an error in crafttweaker.log of Trying to access Ghost item before it's ready: <item:contenttweaker:fluix_enriched_egg:0>.

I'm importing for CustomChickens.zs:

import mods.contenttweaker.ChickenFactory;
import mods.contenttweaker.Color;

and for ContentTweaker.zs:

import mods.contenttweaker.VanillaFactory;
import mods.contenttweaker.MaterialSystem;

and Roost in UniversalTweaks.cfg should look like this:

        roost {
            # Improves load time by registering CT chickens early for Roost to detect them
            # Note: All CT chickens must be specified in "Custom Chickens" for this tweak to work!
            # Note: The .zs files creating custom chickens must be loaded with '#loader preinit', not '#loader contenttweaker'!
            B:"ContentTweaker: Early Register CT Chickens"=true

            # Adds custom chickens from mods (e.g. ContentTweaker) to Roost's stock texture check
            # Syntax: name
            # name     Chicken name
            S:"Custom Chickens" <
                custom_item_chicken
                custom_part_chicken
             >
        }

Can you provide more info on how to reproduce the crash with your example scripts?

EDIT: Still not able to reproduce the error, but I can see that using a MaterialPart is not supported with the current way the tweak is written. I'll try to rewrite the tweak as I've noticed using the preinit loader was a hack anyway.

commented

Yeah I believe any "unable to resolve" type errors means you used invalid/not yet known syntax and/or the specified item doesn't exist.

From my testing, the egg made through the MaterialSystem is assigned the item id contenttweaker:material_part:0, so I assume any additional materials would be added to the same id under a different metadata. This item id though is not really consistent though because I believe adding more materials will change around metadata.

The stable way to reference such an item (to my knowledge from digging through the docs and code at least) added by the MaterialSystem is the Material Part bracket handler, which I linked in the PR. Using the new loader allows for using any ContentTweaker syntax (and thus the Material Part bracket handler) because the script is loaded after everything in pre-init is setup, which you were unable to do using pre-init loader (which is CraftTweaker's pre-init, before CoT's) and CoT loader (which is before materials, bracket handler, etc. are setup).

The pre-init loader only happened to work before because any @ZenMethods were known by CraftTweaker's pre-init, which does not know about CoT syntax/functions.

commented

The above PR should fix the issue, although I couldn't reproduce the hard crash. The following scripts are what I used. Note the use of a new loader #loader finalize_contenttweaker, only necessary to use MaterialSystem.
CustomChickens.zs:

#loader finalize_contenttweaker
#modloaded chickens
import mods.contenttweaker.ChickenFactory;
import mods.contenttweaker.Color;
import mods.contenttweaker.MaterialSystem;

val custom_item_chicken = ChickenFactory.createChicken("custom_item_chicken", Color.fromHex("000000"), <item:contenttweaker:ore_clump>);
custom_item_chicken.setForegroundColor(Color.fromHex("007F7F"));
custom_item_chicken.setSpawnType("NONE");
custom_item_chicken.register();

val custom_part_chicken = ChickenFactory.createChicken("custom_part_chicken", Color.fromInt(0xffffff), 
<materialpart:fluix:enriched_egg>);
custom_part_chicken.setForegroundColor(Color.fromInt(0x054549));
custom_part_chicken.setSpawnType("NONE");
custom_part_chicken.register();

ContentTweaker.zs:

#loader contenttweaker
#priority 100
import mods.contenttweaker.VanillaFactory;
import mods.contenttweaker.MaterialSystem;

var ore_clump = VanillaFactory.createItem("ore_clump");
ore_clump.register();

#Enriched Egg
mods.contenttweaker.MaterialSystem.getPartBuilder()
    .setName("enriched_egg")
    .setPartType(MaterialSystem.getPartType("item"))
    .setOreDictName("enrichedEgg")
    .build();

val eggColorMap as int[string] = {
	"Fluix" : 3342438,
};

for material, color in eggColorMap {
	val part = MaterialSystem.getMaterialBuilder()
		.setName(material)
		.setColor(color)
		.build();
	part.registerPart("enriched_egg");
	print(material + " Enriched egg registered");
}

2023-04-12_19 44 12

commented

So this error seems to be relatively generic for "ghost item ended up not being resolvable to a real item". I don't know why it couldn't resolve my item.

Some part of the process ended up mapping the CoT-created Material Part to contenttweaker:foo_enriched_egg, and that wasn't happening in my small example.

Eggs using part system wasn't important enough to my approach that it ended up being easier to convert all eggs to tinted VanillaFactory created objects to take advantage of your optimisation rather than get Parts working.

(edit: the above was posted before refreshing and seeing your PR, checking now)