Using predicates in ".json" files to dynamically change a texture

Started by Keter_Nihilo on

Topic category: Help with modding (Java Edition)

Last seen on 01:29, 21. Mar 2021
Joined Jul 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Using predicates in ".json" files to dynamically change a texture

I'm currently working on a bionicle mod, and I'm hoping to make it so that a single mask item can have multiple textures that can be changed via nbt tags (Probably damage) without having to create individual items where only the texture is different, I think the only issue that I'm coming across currently is the path of which a texture is called

{
  "parent": "item/generated",
  "textures": {
    "layer0": "kanohimc:items/kanohi_hau"
  },
 
  "overrides": [
        { “predicate”: { “custom_model_data”: 1}, “model”: "item/kanohi_hau_blank” },
        { “predicate”: { “custom_model_data”: 2}, “model”: "item/kanohi_hau_tahu” }
      ]
}

Last seen on 01:29, 21. Mar 2021
Joined Jul 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
I've figured out a solution!…
Sun, 07/19/2020 - 14:17

I've figured out a solution! It's a bit messy, but it's a bit cleaner and feels nicer than having to make unique items for each texture.

I'll post a small tutorial here later for anybody who's interested.

Pros: Dynamic texture changes in game, single item to contain multiple textures

Cons: Only works with existing predicates, textures need both a json file and a texture file, requires an additional resource pack along with the mod (may be a work around), if using damage it shows damage bar(can be fixed with unbreakable tag, which is still a bit ugly) which interferes with damagable items

Last seen on 10:28, 30. Oct 2023
Joined Aug 2018
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
I would like to follow this…
Sun, 07/19/2020 - 14:23

I would like to follow this case :D

Last seen on 16:48, 17. Dec 2020
Joined Jun 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
How did you end up doing it?
Thu, 08/13/2020 - 18:40

How did you end up doing it?

Last seen on 01:29, 21. Mar 2021
Joined Jul 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
Hey, super sorry for the…
Wed, 10/21/2020 - 22:07

Hey, super sorry for the late reply (Lots of stuff going on in my personal life) but my theory was correct! Minecraft has a built in "Dynamic texture changing mechanic" through resource packs (I believe it's also how the bow and fishingline work), where you add a few json files to change the texture, either using an nbt "CustomModelData" tag or through the damage tag (There may be others that work better, but these worked best for me) The problem is it requires a lot of tweaking/trial and error to get the right results. I made a seperate resource pack and figured out where the item texture was by using a seperate texture in the resource pack, then I followed a few tutorials on YouTube to figure out how to redirect the texture with a json file (Same name as the json file used to load the initial texture, not necessarily the same name as the png file) then you can basically make it branch off into different files based on damage, tag and probably a few other things. Honestly, it's not too complicated once you understand, but it's kinda messy and hard to get your head around when you're working on your first texture change. I recommend taking it step by step and looking into making a resource pack with changing textures (Or do what I did, and download a resource pack and reverse engineer it) if people are really struggling I'll try and make a follow up

 

Last seen on 18:13, 20. Mar 2024
Joined Oct 2020
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
did this all work? a little…
Tue, 11/17/2020 - 19:59

did this all work? a little more direction would be grreatly appreciatet.

Last seen on 02:16, 22. Aug 2023
Joined Mar 2018
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
my guy a few months later…
Wed, 03/03/2021 - 20:34

my guy a few months later and im begging ya, youtube video on your process

 

Last seen on 00:30, 30. May 2022
Joined May 2022
Points:

User statistics:

  • Modifications:
  • Forum topics:
  • Wiki pages:
  • MCreator plugins:
  • Comments:
For the sake of those who…
Sun, 05/08/2022 - 02:14

For the sake of those who find this later on,

I went through the trouble of making something similar to this work. I am making a bundles mod, and as such, I wanted to add the empty/filled variation used in the vanilla bundles. 

I am doing this using a forge mdk for 1.18.2. I don't know whether that matters tho, as I've only been modding for about a month.
 

My solution uses the same predicates mentioned above, so I thought I would share.

For starters, you will have to have 1 major json for your itemmodel, and subsequent jsons for each variant texture involved.

Each minor json will look like a normal model:

{
  "parent": "minecraft:item/generated",
  "textures": {
    "layer0": "examplemod:item/example_item_variant_one"
  }
}

The major json will look as follows:

{
  "parent": "minecraft:item/generated",
  "textures": {
    "layer0": "examplemod:item/example_item"
  },
  "overrides": [
    { "predicate": { "examplemod:predicatename": 0.25 }, "model": "examplemod:item/example_item_variant_one" },
    { "predicate": { "examplemod:predicatename": 0.5 }, "model": "examplemod:item/example_item_variant_two" }
  ]
}

 Notes, the models mentioned should each reference one of the minor json files.

These each, (hopefully obviously) reference a texture.png.

After the jsons are setup, we need to make a function to decide which variant we should land on. This should be done with a function in the Item's class. 

The function I'm using looks like this:

public static float getFullnessDisplay(ItemStack itemStack) {
    return (float)getContentWeight(itemStack) / (float) MAX_WEIGHT ;
}

It has to be static, and it has to return a float between 0 and 1. The arguments can be any/all of these: itemStack, clientLevel, livingEntity, numberArg. I don't know what any of them do other than the itemStack. You will have to play to get exactly what you want.

Finally, you have to register the property. Based on the docs for it: 

https://mcforge.readthedocs.io/en/latest/resources/client/models/itempr…

And the tutorial I was working from ( lookup "Cy4 minecraft modding" on youtube).

I added the following to a clientSetup function in my code.

ItemProperties.register( ItemInit.EXAMPLE_ITEM.get(), new ResourceLocation("predicatename"),
      (itemStack, clientLevel, livingEntity, numberArg) -> ExampleItem.getFullnessDisplay(itemStack));

Final note, the floats in the predicate section of the json are >=. So the example above will display the default texture if the function returns anything under .25. Anything .25 <= x < .5 returns variant_one, and anything >= .5 returns variant_two.

Note, the function in question appears to run with the render engine every tick.

Disclaimer: I don't know anything about what I'm talking about, I just wanted to respond as I had found an answer (or something like one).

 

Hope this helps.