Jump to content

[SOLVED] [1.16] Custom Sign won't render


kiou.23

Recommended Posts

I have registered blocks for both a Standing Sign, and Wall Sign and I have registered an item for the sign.

I did reflection for registering a wood type, and am using this wood type in the signs

I have the texture for the wood type under textures/entity/signs

and I have created the blockstate and model files, copying the vanilla ones (where the blockstates point to a model file that only has a texture for particles)

 

However, the Sign still won't render, and the edit sign screen won't show up.

Sometimes the game crashes when I place a sign, with a NPE, but it isn't consistent.

 

Sign block registration:

EFFETE_SIGN = registerNoItem("effete_sign", () -> new StandingSignBlock(
	AbstractBlock.Properties.create(Material.NETHER_WOOD, MaterialColor.LIME)
		.doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD), Main.EFFETE_WOOD_TYPE));
EFFETE_WALL_SIGN = registerNoItem("effete_wall_sign", () -> new WallSignBlock(
	AbstractBlock.Properties.create(Material.NETHER_WOOD, MaterialColor.LIME)
		.doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD).lootFrom(EFFETE_SIGN.get()), Main.EFFETE_WOOD_TYPE));

 

Blockstate and model files:

{
  "textures": {
    "particle": "effetewood:block/effete_planks"
  }
}
{
  "variants": {
    "": {
      "model": "effetewood:block/effete_sign"
    }
  }
}

 

Wood Type registration and Reflection code:

private void setup(final FMLCommonSetupEvent event)  {
	reflectionSetup();

  	try {
		EFFETE_WOOD_TYPE = (WoodType) registerWoodTypeMethod.invoke(null, woodTypeConstructor.newInstance("effete"));
	} catch (Exception e) {
		LOGGER.error("Error registering wood type");
		e.printStackTrace();
	}
}

private void reflectionSetup() {
	if (woodTypeConstructor != null) woodTypeConstructor.setAccessible(true);
	if (registerWoodTypeMethod != null) registerWoodTypeMethod.setAccessible(true);
}

private static final Constructor<WoodType> woodTypeConstructor;
private static final Method registerWoodTypeMethod;

private static Constructor<WoodType> getWoodTypeConstructor() {
	try {
		return WoodType.class.getDeclaredConstructor(String.class);
	} catch (Exception e) {
		LOGGER.error("Exception in getWoodTypeConstructor: " + e.getMessage());
		e.printStackTrace();
		return  null;
	}
}

private static Method getRegisterWoodTypeMethod(){
	try {
		return WoodType.class.getDeclaredMethod("register", WoodType.class);
	} catch (Exception e) {
		LOGGER.error("Exception in getRegisterWoodTypeMethod: " + e.getMessage());
		e.printStackTrace();
		return null;
	}
}

static {
	woodTypeConstructor = getWoodTypeConstructor();
	registerWoodTypeMethod = getRegisterWoodTypeMethod();
}

 

Edited by kiou.23
Link to comment
Share on other sites

1 hour ago, diesieben07 said:
  • You do not need to use reflection to invoke the constructor, just make a subclass.

I had asked on discord and someone suggested using reflection. but yeah, a subclass is way better

This is correct?

public class ModWoodType extends WoodType {

    public static final WoodType EFFETE = new ModWoodType("effete");

    protected ModWoodType(String name) {
        super(name);
    }
}
1 hour ago, diesieben07 said:
  • That is never how you handle exceptions. Think about what happens if these reflection things fail - you now don't have a WoodType instance. What does your sign do then? Return null? Then it's going to crash - but with some random null pointer exception somewhere, which has no bearing on the actual error (the reflection failed). Make your reflection code throw an exception if it fails! That said - you need to use ObfuscationReflectionHelper and SRG names, or your code will not work outside the development environment.

Yeah, you told me that in another thread. But since I don't need to use reflection, I'm going to postpone studying error handling to another week

1 hour ago, diesieben07 said:
  • Sign textures are baked in Atlases.collectAllMaterials - which is called from the static initializer of ModelBakery. This class will be initialized very early, way before any mod loading happens probably. That means, Minecraft won't have your wood type when it is stichting textures / baking models. You probably need to hack them in in some way in ModelRegistryEvent.

And how should I go about doing that?

I tried:

@SubscribeEvent
public static void modelRegistryEvent(ModelRegistryEvent e) {
	Atlases.SIGN_MATERIALS.put(ModWoodType.EFFETE, new RenderMaterial(Atlases.SIGN_ATLAS, new ResourceLocation("effetewood:entity/signs/effete")));
}

It still doesn't work (The edit screen pops up for less than a second, and appear to have the missing pink/black texture), and the actual block just is invisible

(dumb question: I don't need to specify "textures/entity/..." in the resouce location, right?)

Edited by kiou.23
Link to comment
Share on other sites

9 minutes ago, diesieben07 said:

You still need reflection to register it.

Alright, where can I learn about the ObsfuscationReflectionHelper and SRG names? (and by register, you mean registering to the VALUES field from the WoodType class?)

10 minutes ago, diesieben07 said:

I don't know. It might be better to just make your own renderer and not use this vanilla stuff.

doesn't this do it?

Atlases.SIGN_MATERIALS.put(ModWoodType.EFFETE, new RenderMaterial(Atlases.SIGN_ATLAS, new ResourceLocation("effetewood:entity/signs/effete")));

if it doesn't, can you point me towards how I would write my own renderer?

Link to comment
Share on other sites

14 minutes ago, diesieben07 said:

No, because SIGN_MATERIALS is copied into ModelBakery.LOCATIONS_BUILTIN_TEXTURES in Atlases.collectAllMaterials which is called from ModelBakery static init, which happens way before this event. Any changes to SIGN_MATERIALS later will be ignored.

You'd have to also add it to LOCATIONS_BUILTIN_TEXTURES, but I don't know if that would even be enough - worth a try though.

I'll try it (Edit: nvm, no idea how to try it, and it may not even work)

there seems to be another problem tho: I changed the wood type of the sign to OAK, just to see if it rendered with a vanilla wood type, and nope. it's still invisible. however, the edit screen has the oak sign texture (it still only stays up for milliseconds)

this has to be related to something else, right?

Edited by kiou.23
Link to comment
Share on other sites

3 minutes ago, diesieben07 said:

You cannot use the vanilla sign blocks, because they use SignTileEntity, which is only marked valid for the vanilla signs. You need to make your own TileEntityType and use that.

so I also need to write my own Sign blocks? and can I just make them a subclass of the vanilla classes?

Link to comment
Share on other sites

Okay, so my Custom Sign Tile Entity has to extend SignTileEntity, because PlayerEntity#openSignEditor() expects a SignTileEntity.

but from there I can't call super() and pass in my custom Tile Entity Type, because the TileEntityType for SignTileEntity is hardcoded in the constructor.

How to proceed?

Link to comment
Share on other sites

Did the classes, now the edit screen shows up, and if I use a vanilla WoodType for the sign, the texture shows up in the edit screen (not in the actual block tho, it still won't render)

the changes are on github.

How should I go about rendering the Sign again? I'll need to write my own TileEntityRenderer?

Link to comment
Share on other sites

Wow that's alot, I was trying to do the brute force way of simply reimplementing all the classes over, but it didn't quite work.

I'll take a look at your solution and try doing that. Thank you a lot for taking the time to help me with this!

(is it fine for me to dm you on discord if I face a roadblock again? relevant to adding this signs of course)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.