How to use predicates inside of advancements?



  • I'm trying to use predicates inside of advancement triggers.


    According to the https://minecraft.fandom.com/wiki/Advancement/JSON_format#minecraft:inventory_changed I should be abled to use the player tag, but I couldn't figure out, how the syntax works exactly.

    player: The player that would get the advancement. May also be a list of predicates that must pass in order for the trigger to activate.

    This version

    "trigger": "minecraft:inventory_changed",
    "conditions": {
        "player": [
            "oneheart:holds_flower",
            "oneheart:armor/any"
        ]
    }
    

    gives this error

    Parsing error loading custom advancement oneheart:armor/flower: Object “oneheart:holds_flower” can't be deserialized


    I also found this reddit https://www.reddit.com/r/MinecraftCommands/comments/kh7blq/how_to_detect_predicate_in_advancement_criteria/ , but the syntax given in the answers

    "trigger": "minecraft:inventory_changed",
    "conditions": {
        "player": [
            {
                "condition": "reference",
                "oneheart:holds_flower": true
            },
            {
                "condition": "reference",
                "oneheart:armor/any": true
            }
        ]
    }
    

    gives me an error when reloading as well

    Parsing error loading custom advancement oneheart:armor/flower: Missing name, expected to find a string


    Since the JSON for the player property check is also named predicate, I also just tried this:

    "trigger": "minecraft:inventory_changed",
    "conditions": {
        "player": [
            {
                "condition": "minecraft:entity_properties",
                "entity": "this",
                "predicate": {
                    "reference": {
                        "oneheart:holds_flower": true,
                        "oneheart:armor/any": true
                    }
                }
            }
        ]
    }
    

    This doesn't result in an error when reloading, but the code also doesn't work. Any inventory change will grant the advancement, without checking the predicates.

    What is the correct way to do this?


    Note: I've double checked both predicates and also the combination of both. They aren't the problem.



  • player: The player that would get the advancement. May be a list of predicates that must pass in order for the trigger to activate.

    That text is unclear and I am planning to update it. The replacement text that I am planning to use is:

    player: Checks properties of the player that activated the trigger. Either an entity predicate with the contents shown below, or an array containing predicate conditions.

    As you can see the icons on the left indicate that it can either be an object { } or an array [ ]. What this means is:

    • If you want to use an entity predicate, you put player as an object { }. You then fill it with the contents shown in the expandable purple box directly below:
      {
        "trigger": "minecraft:inventory_changed",
        "conditions: {
          "player": {
            "equipment": {
              "mainhand": {
                "tag": "minecraft:flowers"
              }
            }
          }
        }
      }
      
    • If you want to use predicate conditions, you put player as an array [ ]. You then paste your predicate conditions directly into the file like so:
      {
        "trigger": "minecraft:inventory_changed",
        "conditions": {
          "player": [
            {
              "condition": "minecraft:entity_scores",
              "entity": "this",
              "scores": {
                "test": 5
              }
            }
          ]
        }
      }
      

    You were actually so close! To use an external predicate file for player, you must inbuild a predicate condition that utilizes minecraft:reference. The minecraft:reference predicate condition invokes another predicate file and simply passes back that predicate's result.

    The Reddit post you found was correct. They had the right idea and gave you sample syntax of the correct form. The problem is, you messed up the innards of the minecraft:reference condition. The person who posted that is partially to blame for typing the structure slightly unclearly, but it is also partially your fault too, you did not research the https://minecraft.fandom.com/wiki/Predicate#condition_reference yourself to check the right format after realizing it was wrong.

    You put this:

    {
      "condition": "minecraft:reference",
      "my:other/predicate": true
    }
    

    It should look like this:

    {
      "condition": "minecraft:reference",
      "name": "my:other/predicate"
    }
    

    As a result, you received the following error message:

    Parsing error loading custom advancement oneheart:armor/flower: Missing name, expected to find a string

    This error message was not telling you that you messed up bigtime and you need to reorganize. It was telling you that everything was correct, but you were just missing one thing. What was that thing? The name field, which you accidentally omitted. You would do well not to assume that error messages mean the whole setup is wrong.

    So in summary, use the way the Reddit post gave you, and fix that minor technicality. Then everything should work correctly!

    Missed anything? Let me know in the comments.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2