Skip to content

OptiGUI JSON resources

OptiGUI 3.0.0-alpha.1+

Tip

OptiGUI ships with an inspector. Press F12 (default key binding) while a GUI screen is open, and OptiGUI will generate and copy a JSON resource to your clipboard.

File location

Each file in a resource pack must only contain characters a-z 0-9 _. All lowercase, no whitespace. Otherwise, the game will not recognize it.

Each file name must match the regular expression ^[a-z0-9_]+$

OptiGUI loads .json files from a resource pack's assets/<namespace>/optigui/gui folder, including its subfolders in any depth. The namespace can be anything as long as it's valid, not just optigui.

File structure

OptiGUI 3 adds support for a new, JSON-based resource format, with the following deviations allowed from the JSON standard (see GSON code for the full list):

# Comments
// are allowed
/*
Multi-line comments are allowed,
but can't be nested
*/
{
  UnquotedNames: "are allowed",
  'Single-quoted names': "are allowed",
  "Unquoted strings": are_allowed,
  "Single-quoted strings": 'are allowed',
  "Array elements can be separated by": ["commas", "or"; "semicolons"],
  "Unnecessary array separators": ["are treated as", null, /* null */, , ,],
  "Names and values can be separated": {
    "Using": "colons",
    "Using"= "equality signs",
    "Or"=> "arrows"
  },
  "Name/value pairs can be separated": {
    "Using": "commas";
    "Or": "semicolons"
  }
}

containers

Required OptiGUI 3.0.0-alpha.1+

The identifiers of the blocks, entities, or items to change the GUI texture of. This identifier is used by /setblock, /summon, and /give commands.

It can be specified as a single identifier:

{
  "containers": "minecraft:villager"
}

Or a JSON array of identifiers. In this case, OptiGUI will change the textures of any of the specified blocks, entities, or items:

{
  "containers": ["minecraft:villager", "minecraft:wandering_trader"]
}

Tip

  1. Go to the Minecraft Wiki.
  2. Search for a block, entity, or item, and go to its page
  3. Scroll down to Data values/ID/Java Edition
  4. Copy the text from the Identifier column

Tip

If the namespace is minecraft, then it can be omitted.
For example, waxed_lightly_weathered_cut_copper_stairs is the same as minecraft:waxed_lightly_weathered_cut_copper_stairs

textures

Required OptiGUI 3.0.0-alpha.1+

A JSON object specifying the original textures, and what textures to change those to.

{
  "textures": {
    "mod:textures/gui/path/to/texture.png": "example:path/to/changed/texture.png"
  }
}

Tip

If the namespace is minecraft, then it can be omitted.
For example, waxed_lightly_weathered_cut_copper_stairs is the same as minecraft:waxed_lightly_weathered_cut_copper_stairs

if

Optional OptiGUI 3.0.0-alpha.1+

An NBT filter evaluated when loading the JSON resource. If it doesn't match, the JSON resource is not loaded.

match

Optional OptiGUI 3.0.0-alpha.1+

An NBT filter evaluated when changing GUI screen textures.

Caution

Avoid creating two JSON resources, where match filters can match the same NBT.
OptiGUI chooses the least recently used JSON resource's NBT filter, and not the more specific one (for performance reasons), which can lead to the less specific NBT filter always being prioritized over the more specific filter.

Caution

Since block entities don't send all of their NBT to the client, it is possible that some NBT data will "disappear" after disconnecting. This happens with blocks placed by you before being unloaded (like disconnecting, changing dimensions, or going out of render distance). I suggest re-logging before inspecting newly placed blocks.

Filter

JSON Object

A filter is a collection of NBT Matchers.
When multiple matchers are placed into a JSON object, all of them has to match.

JSON Array

A JSON array filter contains other filters.
When multiple filters are placed into a JSON array, any of them has to match.

String

When only the = matcher is used in a JSON object, the string value can be written in place of the JSON object. See = matcher's syntax shortcut.

Number

When only the = matcher is used in a JSON object, the numeric value can be written in place of the JSON object. See = matcher's syntax shortcut.

NBT Matchers

NBT Compound child tag

If the matcher name is @tag, matches an NBT element, if any of the following is true:

  • it is an NBT Compound, has a child tag named tag, and the given filter matches its child tag named tag. If the filter is an empty JSON object, then only the presence of a child tag named tag is checked
{
  "@tag": {}
}

NBT List/Array nth element

If the matcher name is #n, matches an NBT element, if any of the following is true:

  • it is an NBT List/Array, n>=0, has at least n+1 elements, and the given filter matches its nth element (starting from 0). If the filter is an empty JSON object, then only the element count is checked
  • it is an NBT List/Array, n<0, has at least |n| elements, and the given filter matches its size-|n|th element (starting from 0). If the filter is an empty JSON object, then only the element count is checked
{
  "#0":  {}, // First element
  "#1":  {}, // Second element
  "#-1": {}, // Last element
  "#-2": {}  // Second to last element
}

#none

Matches an NBT element, if any of the following is true:

  • it is an NBT List/Array, and none (exactly 0) of its elements match the given filter
{
  "@player": {
    "@Motion": {
      "#none": {
        ">": 1
      }
    }
  }
}

#any

Matches an NBT element, if any of the following is true:

  • it is an NBT List/Array, and any (1 or more) of its elements match the given filter
{
  "@player": {
    "@Motion": {
      "#any": {
        ">": 1
      }
    }
  }
}

#some

Matches an NBT element, if any of the following is true:

  • it is an NBT List/Array, and 0 or more, but not all of its elements match the given filter
{
  "@player": {
    "@Motion": {
      "#some": 0
    }
  }
}

#all

Matches an NBT element, if any of the following is true:

  • it is an NBT List/Array, and all of its elements match the given filter
{
  "@player": {
    "@Motion": {
      "#all": 0
    }
  }
}

>

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a number, and is larger than the given number
  • it is a string, and is lexicographically after the given string (case-sensitive)
{
  "@player": {
    "@health": {
      ">": 10
    }
  },
  "@biome": {
    ">": "minecraft:cherry_grove"
  }
}

>*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

{
  "@biome": {
    ">*": "minecraft:cherry_grove"
  }
}

>=

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

{
  "@player": {
    "@health": {
      ">=": 10
    }
  },
  "@biome": {
    ">=": "minecraft:cherry_grove"
  }
}

>=*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

{
  "@biome": {
    ">=*": "minecraft:cherry_grove"
  }
}

=

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a number, and is equal to the given number
  • it is a string, and is equal to the given string (case-sensitive)
{
  "@player": {
    "@health": {
      "=": 10
    }
  },
  "@biome": {
    "=": "minecraft:cherry_grove"
  }
}

Syntax shortcut

When only the = matcher is used in a JSON object, the value can be written in place of the JSON object:

{
  "@player": {
    "@health": {
      "=": 10
    }
  },
  "@biome": {
    "=": "minecraft:cherry_grove"
  }
}

Can be written as:

{
  "@player": {
    "@health": 10
  },
  "@biome": "minecraft:cherry_grove"
}

=*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a string, and is equal to the given string (case-insensitive)
{
  "@hand": {
    "=*": "Main_Hand"
  }
}

!=

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a number, and is not equal to the given number
  • it is a string, and is not equal to the given string (case-sensitive)
{
  "@player": {
    "@health": {
      "!=": 10
    }
  },
  "@biome": {
    "!=": "minecraft:cherry_grove"
  }
}

!=*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a string, and is not equal to the given string (case-insensitive)
{
  "@hand": {
    "!=*": "Off_Hand"
  }
}

<=

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

{
  "@player": {
    "@health": {
      "<=": 10
    }
  },
  "@biome": {
    "<=": "minecraft:cherry_grove"
  }
}

<=*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

{
  "@biome": {
    "<=*": "minecraft:cherry_grove"
  }
}

<

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a number, and is smaller than the given number
  • it is a string, and is lexicographically before the given string (case-sensitive)
{
  "@player": {
    "@health": {
      "<": 10
    }
  },
  "@biome": {
    "<": "minecraft:cherry_grove"
  }
}

<*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

{
  "@biome": {
    "<*": "minecraft:cherry_grove"
  }
}

regex

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a string, and matches the given regex (case-sensitive)

Test your regex at regex101 or RegExr (not sponsored).
If you need help escaping it as JSON, try this recipe on CyberChef (also not sponsored).
If you'd like to buy me a coffee, you can do so at Ko-fi (sponsored).

{
  "@biome": {
    "regex": "^minecraft:.*jungle$"
  }
}

regex*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a string, and matches the given regex (case-insensitive)

Test your regex at regex101 or RegExr (not sponsored).
If you need help escaping it as JSON, try this recipe on CyberChef (also not sponsored).
If you'd like to buy me a coffee, you can do so at Ko-fi (sponsored).

{
  "@biome": {
    "regex": "^Minecraft:.*Jungle$"
  }
}

wildcard

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a string, and matches the given wildcard (case-sensitive)

  • ? matches exacly 1 character (regex equivalent: .)

  • * matches 0 or more characters (regex equivalent: .*)
{
  "@biome": {
    "regex": "minecraft:*savanna*"
  }
}

wildcard*

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is a string, and matches the given wildcard (case-insensitive)

  • ? matches exacly 1 character (regex equivalent: .)

  • * matches 0 or more characters (regex equivalent: .*)
{
  "@biome": {
    "regex": "Minecraft:*Savanna*"
  }
}

type

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is of a given type
{
  "@block_state": {
    "type": "compound"
  }
}
Type (numeric) Type (string)
0 end
1 byte
2 short
3 int
4 long
5 float
6 double
7 byte_array
8 string
9 list
10 compound
11 int_array
12 long_array

none_of

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • none (exactly 0) of the given JSON array of filters matches the NBT element
{
  "@player": {
    "none_of": [
      {
        "@Health": 20
      },
      {
        "@FoodLevel": 20
      }
    ]
  }
}

any_of

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • any (1 or more) of the given JSON array of filters matches the NBT element
{
  "@player": {
    "any_of": [
      {
        "@Health": 20
      },
      {
        "@FoodLevel": 20
      }
    ]
  }
}

some_of

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • 0 or more, but not all of the given JSON array of filters matches the NBT element
{
  "@player": {
    "some_of": [
      {
        "@Health": 20
      },
      {
        "@FoodLevel": 20
      }
    ]
  }
}

all_of

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • all of the given JSON array of filters matches the NBT element
{
  "@player": {
    "all_of": [
      {
        "@Health": 20
      },
      {
        "@FoodLevel": 20
      }
    ]
  }
}

keys

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is an NBT Compound, and the given filter matches a list consisting of the compound's attributes (keys)
{
  "@mods": {
    "keys": {
      "#any": {
        "=": "avm_staff"
      }
    }
  }
}

values

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is an NBT Compound, and the given filter matches a list consisting of the compound's values
{
  "@mods": {
    "values": {
      "#all": {
        "@version": {
          ">=*": "1"
        }
      }
    }
  }
}

size

OptiGUI 3.0.0-alpha.1+

Matches an NBT element, if any of the following is true:

  • it is an NBT Compound, and the number of the attribute-value pairs in it matches the given filter
  • it is an NBT List/Array, and the number of the elements in it matches the given filter
  • it is a string, and its length matches the given filter
{
  "@player": {
    "@active_effects": {
      "size": {
        ">=": 33
      }
    }
  }
}

Tips

Check if an NBT compound named root doesn't have a child tag named tag

{
  "@root": {
    "none_of": [
      {
        "@tag": {}
      }
    ]
  }
}

Check for a container renamed in an anvil

Since most blocks don't send their custom name to their NBT when sending it to the client without a mod installed on the server like Know My Name, the GUI screen title can be used instead.

The default name of a block is a translated text.
If an anvil is used to rename the block in its item form, it is a plain text.
If a command is used to set its custom name, then it can be any kind of text.

{
  "@screen": {
    "@title": [
      {
        "@text": "Never gonna give you up"
      },
      {
        "@translate": "container.shulkerBox"
      }
    ]
  }
}