Crazy Advancements API 1.14.3

Add your own custom Advancements programmatically, supports player-specific advancements

  1. ZockerAxel
    Native Minecraft Version:
    Tested Minecraft Versions:
    • 1.17
    Source Code:
    API for creating Advancements in 1.17 (older versions support 1.12 - 1.16.5)​

    What this API can do:
    Create, add, remove, refactor and manage custom Advancements at Runtime with the following features:
    - Give your advancement a name, description, icon, background texture
    - Set the required criteria for an advancement (not like in Vanilla!!!!)
    - Set the coordinates of an Advancement
    - Add advancements to all players
    - Add advancements to specific players/player groups
    - Set who can see which advancement (even if they would/wouldn't be visible in Vanilla)
    - Save Advancement progress for specific players and specific advancements
    - Load Advancement progress for specific players and specific advancements
    - Create Advancements from JSON Strings
    - Export Advancements as JSON Strings
    - Set the Active TAB in the Advancement Menu
    - Create an EventHandler for listening if the Advancement TAB has changed or if the menu has been closed

    Why should I use this API instead of any other?
    This API does not create any files for advancements unless you strictly tell the plugin to do so and doesn't interfere with Vanilla/Spigot Advancements because this API is based on NMS. It also allows you to change the display of your advancement while the player is viewing the Advancement Screen and has an API ready for saving player's progress whereever you want (just get the save string and put it whereever you want and put it in when you want to load it). Also, there are custom Visibility options for advancements

    How can I install this API

    Just drop it into your Plugins folder and reload or start your server

    How to use it


    Online Documentation
    You can find the Documentation at

    The GitHub Repository can be found here:

    Get an Advancement Manager
    First of, you need to create a custom AdvancementManager which you can add Players to
    Code (Text):
    AdvancementManager manager = new AdvancementManager(Player... players);
    You can also not specify any player to create a manager without players if you want to. You can add or remove Players at any time. Players can be added to multiple managers and will see every advancement of every manager.
    NOTE: Due to a bug you need to add Players to the manager at least two ticks after they join, else advancements will not be visible to the Player. For examples, visit the Discord Server!

    Creating an Advancement
    Javadoc for AdvancementDisplay:

    Creating a Root Advancement works like following:
    Code (Text):
    AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.ARMOR_STAND, "My Custom Advancements", "With cool additions", AdvancementFrame.TASK, false, false, AdvancementVisibility.ALWAYS);
    Advancement root = new Advancement(null, new NameKey("custom", "root"), rootDisplay);
    A Root Advancement will create a new Tab with the background texture.

    If you want to add a Children Advancement, you need to specify the Coordinates for the Display and link to the parent advancement. If you don't specify the Coordinates, the advancements will overlap in a single space.
    Code (Text):
    AdvancementDisplay childrenDisplay = new AdvancementDisplay(Material.ENDER_EYE, "To the right", "Your Goal", AdvancementFrame.GOAL, true, true, AdvancementVisibility.VANILLA);
    childrenDisplay.setCoordinates(1, 0);//x, y
    Advancement children = new Advancement(root, new NameKey("custom", "right"), childrenDisplay);
    PRO TIP: Coordinates are floats, so you can also put 1.5 there and it will work

    More about Advancement Display

    Putting Chat Colors into the Display will create weird effects when displaying a chat message, so if you want to use text formatting, use BaseComponent when creating the AdvancementDisplay like that:
    Code (Text):
    AdvancementDisplay display = new AdvancementDisplay(Material.ANVIL, new JSONMessage(/*Your Base Component here*/), new JSONMessage("\"Highway to Hell\""), AdvancementFrame.GOAL, true, true, AdvancementVisibility.VANILLA);
    The two booleans stand for showToast and announceToChat
    PRO TIP: You can also give the constructor an ItemStack instead of a Material if you want it to have e.g. an enchantment glow, a data value (e.g. for wool or a sword with a custom texture) or change the skull owner of a player skull.

    This is how you create them, but there are additional things you can do with them:

    Set the amount of Criteria
    Code (Text):
    Advancement#setCriteria(int criteria)
    Display a message that the advancement has been awarded to ALL Online Players (will not actually be awarded)
    Code (Text):
    Advancement#displayMessage(Player player)
    Change the Position Origin (where the coordinates are relative to)
    Code (Text):
    AdvancementDisplay#setPositionOrigin(Advancement originPosition)

    Adding Advancements
    Javadoc for AdvancementManager: https://crazyadvancements.endercent..._advancements/manager/AdvancementManager.html

    Now that you've created your own advancement(s), you can add them. To reduce network traffic, add all your advancements at once (Please choose better names for your advancements ;))
    Code (Text):
    manager.addAdvancement(root, children, anotherOne, allYourAdvancements, itsGreat, nice);
    You can specify as many advancements as you want and they will all be sent in the same packet if you do it as shown above or you can just input an Array of Advancements. Just make sure that the parents are before their children in the list or every advancement will have their own tab (and a missing texture background:()

    If you want to update your Advancement (different title, description, icon, coordinates), you can just edit it and call this method again, you don't need to remove it first, it will just update.
    NOTE: If you are updating an advancement, you MUST ONLY specify ONE advancement in the addAdvancement Method! Also, updating coordinates will still show a ghost advancement at the old position which doesn't show anything when hovered until the player opens the advancement tab again (only if he has it opened right when you update it)

    Removing Advancements

    Removing Advancements is just as easy as creating them, either have your advancement saved somewhere or get it using
    Code (Text):
    manager.getAdvancement(new NameKey("custom", "root"))
    Then you can just do that:
    Code (Text):
    Removing your advancement will remove the whole tree if its a root advancement even though the other advancements are still there and can be gathered but they won't be shown anymore (unless you get another one, which will create a new advancement tab)

    Granting/Revoking Advancements

    If you want to grant or revoke an advancement, you simply call this method:
    Code (Text):
    manager.grantAdvancement(player, advancement);
    manager.revokeAdvancement(player, advancement);
    PRO TIP #1: If you grant the advancement BEFORE adding it, the player will NOT recieve a toast notification/chat message
    PRO TIP #2: If you want that your player doesn't recieve a toast notification/chat message when they join, add him to your manager after granting the advancements


    You can also grant or revoke a single criterion (or multiple):
    Code (Text):
    manager.grantCriteria(player, advancement, criterion, criterion2);
    manager.revokeCriteria(player, advancement, criterion, criterion2);
    The criterion name can be set to a custom one using expert tools (info if you scroll down) but the default format used by the API for criteria names is criterion.<NUMBER> where <NUMBER> is starting at 0 to have as much criteria as specified

    Or set/get the Criteria progress:
    Code (Text):
    manager.setCriteriaProgress(player, advancement, progress);
    manager.getCriteriaProgress(player, advancement);
    Getting the criteria progress will show how many of the maximum criteria you have, but if you are an expert, you can create more advanced Advancements, which don't need all criteria to be met (e.g. only one of 2). This will not be taken into account by this method. Learn more about Expert stuff if you scroll down more!

    Custom Advancement Visibility
    Javadoc for AdvancementVisibility: https://crazyadvancements.endercent...crazy_advancements/AdvancementVisibility.html

    Custom Advancement Visiblity has been added in 1.6 and allows you to customize when your advancements are visible for the Player.

    Included in this API
    There currently are 4 pre-made Visibilities:
    ALWAYS: Is always shown
    PARENT_GRANTED: Only shown, when parent is granted or any child is granted
    VANILLA: Only shown, when parent of parent is granted or any child is granted
    HIDDEN: Only shown when granted or any child is granted

    Your own Advancement Visibility
    You can easily access them but you might not want to be limited to these 4. So just create your own!
    Here's an example how the PARENT_GRANTED was coded:
    Code (Text):
    new AdvancementVisibility() {

                public boolean isVisible(Player player, Advancement advancement) {
                    if(advancement.isGranted(player)) return true;
                    Advancement parent = advancement.getParent();

                    return parent == null || parent.isGranted(player);
    You can write any code there, like checking for player gamemode or something else. If you do anything that hasn't got something to do with the parents or childs of the advancement, don't forget to update the visibility using the AdvancementManager!

    Saving and Loading Progress
    Javadoc for AdvancementManager: https://crazyadvancements.endercent..._advancements/manager/AdvancementManager.html

    Advancement Progress can easily be loaded and saved via the API as of Update 1.4. (Has been updated in 1.9.2)

    If you decide to save progress, make sure to choose a save method for your advancement first. There are two options: DEFAULT and NUMBER. Default will save all the criteria values that have been granted while Number will save the criteria progress. If you want to use default, you can skip this step, otherwise the number option:
    Code (Text):
    To save progress, simply run of this method:
    Code (Text):
    manager.saveProgress(player, namespace);
    But this won't load the saved things by default, to load advancement progress, you have to load it, when a player joins the first time after a server restart or when the server has been reloaded:
    Code (Text):
    manager.loadProgress(player, advancement1, advancement2); //Load as many advancements as you want
    NOTE: All advancements specified have to be in the same namespace. if not, they will be ignored

    The advancements will be saved in a specific folder inside the plugins folder. Every player will get their own JSON file for every advancement namespace that exists.
    If you want to save it somewhere else, theres an easy solution for this, instead of saving the progress, you can get the JSON String using the following method;
    Code (Text):
    manager.getProgressJSON(player, namespace);
    You can additionally add the parameter namespace to only recieve a json string with the advancements with the set namespace which are in that advancement manager. If you want to load it again, it's as simple as that:
    Code (Text):
    manager.loadCustomProgress(player, json, advancement1, advancement2); //Load as many advancements as you want
    manager.loadCustomProgress(player, json, namespace);
    manager.loadCustomProgress(player, json);
    It will just load depending on the method you use.

    Saving and Loading Advancements
    Javadoc for Advancement:

    Advancements can be saved/loaded via this API as of Update 1.5 (has been updated in 1.6).
    All advancements in (SERVERDIRECTORY)/plugins/CrazyAdvancementsAPI/advancements/main will automatically be loaded on server start/server reload. They will load in alphabetical order, so every advancement has to be alphabetical after their parent if they have a parent.

    Example for a root advancement:
    Code (Text):
        "name": "custom:root",
        "display": {
            "icon": "BRICK",
            "title": {
                "json": "{\"text\":\"My Custom Advancements\"}"
            "description": {
                "json": "{\"text\":\"With cool additions\"}"
            "frame": "TASK",
            "showToast": false,
            "announceChat": true,
            "visibility": "always",
            "backgroundTexture": "textures/blocks/concrete_yellow.png"
        "criteriaAmount": 10
    Example for a non-root advancement (children)
    Code (Text):
        "name": "custom:children",
        "display": {
            "icon": "BRICK",
            "title": {
                "json": "{\"text\":\"My Custom Children\"}"
            "description": {
                "json": "{\"text\":\"The first addition :o\"}"
            "frame": "TASK",
            "showToast": false,
            "announceChat": true,
            "visibility": "vanilla",
            "x": 1.0,
            "y": 0.0
        "criteriaAmount": 1,
        "parent": "custom:root"
    NOTE: These advancements will be added to the main advancement manager and won't group in the correct tab, when they aren't ordered correctly, might change in future versions!
    You can also load them yourself by
    Code (Text):
    or save them by getting the json and saving it somewhere you want:
    Code (Text):
    Advancement Screen

    Changing the current Advancement TAB

    You can change the current Advancement TAB a player is viewing by the following:
    Code (Text):
    CrazyAdvancements.setActiveTab(player, nameKey);
    This will also work if the player isn't viewing the Advancement Screen but will show it when the player opens it the next time

    Testing if Player changes Advancement Tab/Closes Screen

    When a Player changes his Advancement Tab, the
    Code (Text):
    will be called. Cancelling it will display a black advancement screen saying that there doesn't seem to be anything, changing the tab inside will select the desired tab. This event is also called when the player opens the Advancement Screen

    When a Player closes his Advancement Screen, the
    Code (Text):
    will be called. There pretty much isn't any way to edit this event, but you can use it for detection purposes.

    For Experts

    If you are an expert and know how advancements work, you might want to look at the following methods. These methods contain Classes directly from the minecraft server code and you will have to change the imports every minecraft update!

    Code (Text):
    Advancement#saveCriteria(Map<String, Criterion> save)
    Save the criteria, putting in the map works like that:
    Code (Text):
    map.put("criterion_name", new Criterion(new CriterionInstance() {
    public MinecraftKey a(){
    return new MinecraftKey("minecraft", "impossible");

    public JsonObject a(LootSerializationContext lootSerializationContext) {
    return null;
    You can use vanilla criteria here, but it won't trigger!

    BUT you can set which criteria is required and it will absolutely work.
    Code (Text):
    Advancement#saveCriteriaRequirements(String[][] save)
    You might wonder, how the String[][] has to look:
    Code (Text):
    new String[][] {{"a", "b"},{"c"}}
    In this example, you would always need c and either a or b. So for example if you haven't got a but have b and c or if you have a and c, but not b, it will be granted, use the same names like you did when putting the map together!

    If you want to grant a criterion, just use the advancement manager, it will work with custom criteria too!
    PRO TIP: These things even work in the .json Saving of Advancements, as easy as that: "criteria": ["a", "b", "c"] and "criteriaRequirements": [["a", "b"], ["c"]] but don't tell anybody ;)

    Tell me what you think in the comments! Feature requests/bug reports are much appreciated! Also, discussion is OPEN on the discord:

Recent Reviews

  1. Shanka
    Version: 1.14.3
    Had a minor issue with how text was displayed on the hover-over, joined the Discord server, posted the issue in the bugs channel, and it was resolved really quickly with a new update. Would HIGHLY RECOMMEND, respectful and responsive developer, and pretty much plug and play :)
  2. NutellaJunge
    Version: 1.14.2
    Best Advancements API out there. And great to look how to make Custom Advancements in NMS. Thanks Allot. :D
  3. _Obliviate_
    Version: 1.14.1
    works. thats enough .
  4. DefinitlyEvil
    Version: 1.14
    This is the only advancement API I could find online, and it's pure packet-based. Very efficient and nice to have in your plugins.
  5. Virus610
    Version: 1.13.8
    I'm using this plugin to make a sort of tutorial for new players on my server. Works fantastically! (I'm currently on 1.15.2)

  6. i0xHeX
    Version: 1.13.3
    Nice API, started to learn all of that. I love this unique packet sending without changing vanilla and easy management. Code is clear, that's nice. But some things to say. Firstly - make please multiversion support (via reflection or interfaces) in order to support future updates easely. Secondly - update tutorial, cause EYE_OF_ENDER changed to ENDER_EYE on 1.13 and background does not work. Thanks for API!
    1. ZockerAxel
      Author's Response
      Thank you for your review. I'm already planning on adding multiversion-support. I hope i get time to update the Tutorial Video ASAP
  7. tomasekCZE
    Version: 1.13.2
    Great API. It's so simple make custom advancements with CrazyAdvancementsApi.
    (thank you for adding source code)
  8. DrOreo002
    Version: 1.11
    The best API that I've ever seen!. Tysm for making this API!

    10/10 would review 5 star again if you post more updates
    1. ZockerAxel
      Author's Response
      Thank you for your review. If you have any requests/ideas, let me know!
  9. feerko
    Version: 1.11
    Thanks for great update!
  10. Scorpion
    Version: 1.10.2
    It looks good but also update that video as it seems FAR outdated and does not at all use the features currently present and are mostly deprecated
    1. ZockerAxel
      Author's Response
      Thanks for your review. I'm holding the video back because the next update will make huge changes on how the API works "behind the scenes" which will probably remove/change some methods, so the video will be updated once that is done and it covers all the new features of that version too