Syntax¶
Pretty colors¶
The syntax describes how OptiFine's resource pack features will behave and operate.
Different formats and types of values are used within files used by OptiFine-specific features. Rather than describe these common types separately in each feature's section, they are summarized here instead.
File structure¶
Many OptiFine features use properties files to control how OptiFine-specific elements will work within a resource pack.
Properties files are simple text files similar to the Windows INI format.
Each line is a property, specified as name=value.
# Comments begin with a hashtag and are ignored.
property1=value
property2=some_other_value
# Blank lines are allowed.
property3=yet_another_value
All property names are case-sensitive; renderpass is not the same as renderPass.
The order of properties within the file does not matter.
Many properties have default values and can be omitted, and in some cases, the entire properties file is optional.
Paths, file locations¶
Often, OptiFine requires specifying a path to a texture or other file within the resource pack. A path is a "location" of where a file is.
All paths must match the regex ^[a-z0-9_.\/-]+$ (Test this pattern on Regex101).
Hint
Must be lowercase, no spaces, a through z, 0 through 9, and _ . / - only.
The folder structure within a resource pack is deeply nested, so OptiFine has some shortcuts to make paths easier to write. Any of these options can be used to specify the same path.
Always use the forward slash "/" to separate folders.
Caution
Regardless of the operating system, do not use the backslash "\", or the game will not properly recognize the path.
The below table summarizes path shortcuts:
Symbol |
Resolves to |
|---|---|
None |
|
|
File's folder |
|
Not valid syntax |
|
|
|
|
Bare filenames with no slashes will refer to the file relative to /assets/minecraft/optifine/, ignoring subfolders.
texture=texture.png
# Resolves to /assets/minecraft/optifine/texture.png
You can use . to denote the current directory, regardless of location. This does work in subfolders.
texture=./texture.png
texture=./subdirectory/texture.png
The tilde character ~ can be used to refer to /assets/minecraft/optifine/.
texture=~/texture.png
texture=~/subfolder/texture.png
An optional "namespace" prefix can be added. This example refers to exactly the same "creeper.png" file as default:
texture=minecraft:textures/entity/creeper/creeper.png
For textures used by mods, the namespace will be something other than minecraft:
texture=MODID:subfolder/texture.png
This refers to /assets/MODID/subfolder/texture.png, not to /assets/minecraft/MODID/subfolder/texure.png.
Important
In this documentation, a green box captioned "File location" tells you where the respective file(s) should be. It uses bash syntax. In summary:
GLOBSTAR:
**will match infinitely many directories, including zero.STAR PATTERN:
*will match all filenames.*.pngwill match "anynamehere.png" but not "notpng.jpeg".BRACE EXPANSION:
{a,b}will match bothaandb.*.{png,json}will match "file.png" and "thing.json".
Biomes¶
See also
See this page for the 1.13 biome changes.
For features that call for a list of biomes, use this page. Biomes added by mods can also be used.
biomes=ocean deep_ocean river beach modid:biome
Components, NBT¶
OptiFine supports conditions based on an item's data. These are most often used in Custom Item Textures.
Components are the newest format, added in Minecraft 1.20.5. Prior to this, the format was NBT.
For general behavior that applies to both components and NBT, this documentation uses the name "data rules" to refer to both format types.
Entities (such as Random Entities) still use the NBT format.
Hint
To view the data of something, use the command /data get.
For example, to inspect the item you are holding in your main hand, use /data get entity @s SelectedItem.
For more details, see Commands/data - Minecraft Wiki.
General behavior¶
If multiple data rules are provided, all of them must match.
A value starting with an exclamation mark "!" negates the match (match the opposite of this).
Multiple exclamations do nothing; !!0 is not equivalent to 0.
Important
If components are expected, NBT rules should not be used.
If
componentsandnbtrules are both specified, the NBT rules are ignored and a warning will be logged.If there are no
componentsrules and not everynbtrule can be mapped to a component, the entire file is skipped as invalid.
Example
If value of X is Y:
X=YIf Y is in list X:
X.*=YIf Y is the first entry of list X:
X.0=YIf list X has 5 elements:
X.count=5If X is in range:
X=range:0-100If X exists:
X=exists:trueIf Y key exists in any compound in list X:
X.*.Y=exists:trueName:
components.item_name="My Sword"Escapes:
components.item_name="\u00a74\u00a7oMy Sword"First line of lore:
components.lore.0=My Lore TextAny line of lore:
components.lore.*=My Lore Text
Component format¶
Components are specified as keys with the components. syntax.
Components may include a namespace.
To specify a namespace, the first : must be escaped - prefixed with a backslash \\.
If no namespace is specified, it defaults to minecraft:.
Components and component keys that use the minecraft: namespace can be shortened with a tilde (~) instead.
For example, components.enchantments.levels.~thorns becomes components.minecraft\:enchantments.levels.minecraft\:thorns.
components.minecraft\:custom_namecomponents.custom_namecomponents.mod\:coolness_factorcomponents.enchantments.levels.minecraft:thornscomponents.minecraft:custom_namecomponents.minecraft\\:custom_namecomponents.mod.coolness_factor
Legacy
Some legacy NBT checks are automatically converted into Component format for backwards-compatibility only.
nbt.display.Namebecomescomponents.minecraft\:custom_namenbt.display.Lorebecomescomponents.minecraft\:lore
Do not rely on this functionality for new packs.
NBT format¶
NBT are specified as keys with the nbt. syntax.
For older versions of Minecraft and for entities, the NBT format is used instead of the Component format.
Types¶
Strings¶
A string is text, optionally wrapped in double- or single-quotes " '.
If a strings contains only the characters 0-9 A-Z a-z _ - . +, it does not need to be wrapped in quotes.
You can test this on Regex101.
All characters can be escaped with the Unicode codepoints, like \u2605 for ★,
This is recommended for characters with a codepoint above U+007E TILDE ~.
Hint
If the character isn't on your keyboard, it's likely above U+007E and should be escaped!
When matching strings, any formatting (like color or bold) is stripped out.
To test specifically for this formatting, use raw instead.
Important
Any backslashes must be escaped with another backslash. Matching backslashes within a regular expression or wildcard must be quadrupled.
regex:\\d+regex:\\\\/\\/\\regex:\d+(missing a backslash for\d)regex:\\(for matching\\\\; would match\alone)/\/\\(missing a backslash for\/)
Example
"All your base are belong to us"'{looks:"like something fancy",but:"alas, this is just a string!"}'"Oh hello, \"Jeanine\"..."'My reflection \"winked\" at me. I covered the mirror in the attic just to be safe.'
Lists¶
A list (or array) is a sequence of elements wrapped in brackets [ ] and delimited by commas: [E0,E1,E2,...].
They are an ordered collection of data of the same type.
Each element can be accessed with its index, its position in the list.
Lists are zero-indexed; this means that 0 refers to the first element, and 1 is the second.
The length of a list (the number of elements in it) can be accessed with the count attribute:
components.banner_patterns.count=range:0-9
[1,2,3,4][]["strings","too",and,"emacs is superior"][["can nest other lists in lists","like this!"],[1,2,3,4,-5],["vim is superior"]][{emacs:"is bad",vim:"is bad",ed:"is best"},{'but also':"pen and paper","can be...":"stronger"}][true,false,true,true][1,"string",64s][{"mixing types in lists":"is no good"},"-Sonic Sez"]
Compounds¶
A compound (or object, map, dictionary) is a sequence of key-value pairs wrapped in braces { } with
pairs delimited by commas and split by colons :: {key:value,a:b,...}.
Each key is unique and points to a value. Keys are always Strings.
Unlike Lists, values do not have to be of the same type in a compound.
For example, {a:1,b:"string",c:64s} is valid, while the list [1,"string",64s] would not be.
Each value can be accessed with its key. With lists, elements are accessed with their index. Likewise, values are accessed with their key as the "index".
{key:value,fishy:anchovies}{"who owes me money":nephew}{1:"key is actually a string","another type":[1,2,3]}{"I'm getting":{"a sense of":{"deja-vu":true},"with all of these":confusing},"nesting":"Matryoshka dolls"}{}{this needs to be quoted:"I took his advice"}{1, 2, 3}
Numbers¶
A number is a byte, short, integer, long, float, or double. This term is used to refer to all of these types collectively, so "number" itself is not a real type.
Type |
Details |
|---|---|
Byte |
Suffixed with |
Short |
Suffixed with |
Integer |
No suffix. Also known as int. Signed 32-bit integer, ranges from -2147483648 to +2147483647. |
Long |
Suffixed with |
Float |
Suffixed with |
Double |
Suffixed with no suffix, |
Important
Values like components.dyed_color.rgb are stored as integers representing colors.
They are commonly formatted as #RRGGBB, where R, G, B are hexadecimal values for red, green, and blue.
For instance, #FFAA00 equals the integer 16755200.
For convenience, you can match these values using the same format.
For example, components.dyed_color.rgb=#ffaa00 would match if rgb was 16755200.
This does not work for integers above #FFFFFF, 16777215.
Example
120b31045s-32768S-643579687596278847L#ced3570.333f0.4525D
Booleans¶
A boolean is either true or false.
NBT does not have a boolean type, however.
The values true and false are simply aliases for 1b and 0b, respectively (byte 1 and byte 0).
Typed Arrays¶
A typed array is a byte array, int array, or long array. This term is used to refer to all of these types collectively, so "typed array" itself is not a real type.
They are wrapped in brackets [ ] and the first element is an identifier of their type.
For example, [N;e,e,e,...] where N is the identifier and e are elements.
Important
These are special types in NBT and are not the same as lists, although they do look similar!
Note that [I;1,2,3,4] and [1,2,3,4] are not the same thing.
Identifier is B;: [B;1b,2B,3b]
Identifier is I;: [I;53,63872,-258973,0]
Identifier is L;: [L;0L, 5245757867447459784747l, -258965432855427280L, 35l]
Prefixes¶
A prefix can be used to change how a key or value is tested. Some prefixes can be combined with other prefixes.
Exists¶
The prefix exists: checks if a key is defined at all. It takes 1 value, true or false.
truewill apply if the key exists.falsewill apply if the key does not exist - it is not defined.
Example
components.lore=exists:true
components.item_name=exists:false
components.pot_decorations.0=exists:true
components.potion_contents.custom_effects.*.show_icon=exists:false
Pattern¶
The prefix pattern: and ipattern: match with wildcards.
Wildcards are shorter versions of regular expressions - they only support two special symbols:
The symbol
?matches any one character.The symbol
*matches any number of characters.
? is equivalent to the regular expression . (1 of anything).* is equivalent to the regular expression .* (0 or more of anything).patternis case-sensitive;pattern:awill not match "A".ipatternis case-insensitive;pattern:awill match both "A" and "a".
pattern:*
The wildcard * matches 0 or more of anything. This includes nothing at all.
aOne must always reign beneath DuskGet to the choppah*⠀
pattern:?at
The wildcard ? matches just 1 character.
batCatsat5atMatatstatHats for everyone
ipattern:look at me
ipattern makes the search case-insensitive.
look at meLOOK AT MElook at MELOOK at melOOk at meLook at me!Don't look at meLookAtMe
pattern:Lamp oil, rope, bombs – you want it\\? It's yours, my friend, as long as you have enough rupees.
To use a wildcard character as normal, escape it by prefixing it with a backslash. Backslashes must be doubled to be recognized correctly.
Lamp oil, rope, bombs – you want it? It's yours, my friend, as long as you have enough rupees.lamp oil, rope, bombs – you want it? it's yours, my friend, as long as you have enough rupees.Sorry, Link, I can't give credit! Come back whey you're a little – mmmm – richer.I wonder what's for dinner.
pattern:* letter to my grand?a
You can use any combination of wildcards.
A letter to my grandmaThe letter to my grandpaSome letter to my granddaNo letter to my grand!aI didn't write a letter to my grand aletter to my grandpaA letter to my grandfatherA letter to my grandma.
ipattern:Mr. *, I'm * at street ?, looking for *p!
Wildcards can be surrounded by other non-wildcard characters to create accomodating patterns.
Mr. Leno, I'm indeed at street A, looking for soup!Mr. Bruce Wayne, I'm not at street 9, looking for shoes with !Mr. Spock, I'm on a mysterious planet... I'm near street 1, looking for some food in the ship!Mr. I'll have you know, I'm somewhere at street 23, looking for a lollipop!Mr. Crosh, hi, I'm uh, at a street 2, looking for your bipartisanship!Well, Gordon Freeman! And about time, too.
Range¶
The prefix range: checks if an integer value is within a list of other integers or integer ranges.
Items are delimited by a space, as in range:1 2 3 9-15 4. Items do not need to be in order.
Example
components.max_damage=range:(-50)-(-25) 200 0-100
components.instrument.*.range=range:3-18
components.potion_contents.*.custom_effects.*.duration=range:(-1)-3 5 10 26
Integers that are not in a range match that integer only.
A range between two integers is written as X-Y.
If Y is absent, the upper bound is 65535.
If X is absent, it's a negative number and not a range.
If X and Y are absent, the range is invalid;
-alone is not valid.
Negative bounds must be enclosed in parentheses.
For instance, range:(-9)-(-5) matches -9, -8, -7, -6, -5.
Note
To match values less than or equal to a number, use a full range like 0-100, not -100.
Raw¶
The prefix raw: matches exact SNBT values.
Raw can be used to match types explicitly, such as bytes, shorts, floats, doubles, and typed arrays. It can also be used to match formatted text, since formatting is normally removed for checks against Strings.
raw: can also be combined with all other prefixes. For example: raw:pattern:, raw:iregex:, etc.
Important
Spaces in between elements must be removed. For example, [1,2,3,4] and not [1, 2, 3, 4].
Example
components.item_name=raw:'[{"text":"Dark red italics","italic":true,"color":"dark_red"}]'
components.bucket_entity_data.Health=raw:10.0f
nbt.1.UUID=raw:[I;-1668711424,-1434628111,-1613745989,1749596493]
nbt.5.someRandomShort=raw:64s
Regex¶
The prefix regex: and iregex: match with regular expressions.
Regular expressions (or regex) are patterns that can match complex text succinctly.
Regexes can be a simple Hi, .*! or a complex ^(?:(?:25[0-5]|2[0-4]\d|1?\\d{1,2})(?:\\.(?!$)|$)){4}$.
The syntax understood by OptiFine is the Java syntax. OptiFine regular expressions are not multiline and are not global ("/gm").
To match a string with regular expressions, use the regex: or iregex: prefix;
regexis case-sensitive;regex:a{4}will not match "AAAA".iregexis case-insensitive;iregex:a{4}will match both "AaAA", "aaaa", "aaAA", etc.
regex:.*
This regex is equivalent to the wildcard *.
Note
iregex would be useless here, as there is no case-sensitivity applicable in the pattern.
Mmmm. Steamed Clams!No, it's an Albany expression.Enough! You are indeed... worthy.Blue Skull KeyWho are you calling pinhead?
iregex:[ae]ffect
[] matches any one of the characters in between the brackets.-, like [A-Z].^: [^abc].affectAFFECTEffecteffectaffecTaeffectA bad effectEffectingaffect someone else
regex:\\d{4,}
\d matches any digit.{n,} matches the previous element if it occurs at least n times.Hint
Remember that backslashes must be doubled.
1234358000001111135873589638974389676434574675098000Room number 556755555.
regex:Something fishe?y is(n't)? brewing\\.+
? matches the previous character 0 or 1 times. In other words, it's optional.() is needed for the ? to apply to that whole group; isn't? is not the same as is(n't)?.+ matches the previous character 1 or more times.\. is a literal period, not a metacharacter.Hint
Remember that backslashes must be doubled.
Something fishey is brewing.Something fishy is brewing.....Something fishey isn't brewing...Something fishy isn't brewing.Something fishy is brewing.Something fishey isn't brewingsomething fishy is brewing...A smelly smell that smells.... smelly. Anchovies.
iregex:i want more (apple|orange)s[.!?]
| character for "OR". It will match the element before or after it.. ? do not need to be escaped when in a character class ([]).I want more apples!i want more oranges.I WANT MORE ORANGES?i want MORE apples!i want more apples.I want more applesI don't want any applesGrapes are far better.
regex:\\(\\d{3}\\) \\d{3}-\\d{4}
Groups can also be escaped to match parentheses literally.
(345) 867-5309(000) 000-0000(123) 456-7890Left on read
Client-side data¶
Not all data can be detected.
Minecraft operates on a server/client model, even when in singleplayer mode. As OptiFine functions as a client-side mod, it only has access to data transmitted from the server to the client. If the data is exclusively server-side and not mirrored on the client side, it cannot be tested under NBT rules.
A general guideline is as follows: if the component/NBT visibly alters it, it can likely be used.
There is no definitive list yet of what data tags are client-side and which ones are not.
Blocks, items¶
Blocks and items can be specified in the same way that they are in Minecraft, by name.
The block name format is [namespace:]name[:property1=value1:property2=value2:...].
Optional parts are in brackets [ ]. The default namespace is minecraft.
Example
This will apply to oak stairs that are east- or west-facing and are the bottom half.
blocks=minecraft:oak_stairs:facing=east,west:half=bottom
blocks=oak_stairs:facing=east,west:half=bottom
The minecraft: namespace is optional, so it can also be omitted.
Block states¶
Block states are extra data attached to a block. They are simple key-value pairs.
Block states can be specified in addition to the block name.
Block states are specified after a block name and are delimited by the : character.
Each block state that follows is a simple key=value pair.
To match more than one possible value for the key, split the value's options by a ,.
For example, facing=west,east will match a block state where facing is equal to either west or east.
Block state keys and values themselves can only be simple strings. An infinite number of block states may be specified. Any invalid block states (states not applicable to a block) are ignored.
Blending methods¶
See also
See Blend modes on Wikipedia for some illustrations.
When two or more textures are combined, OptiFine offers several options for specifying the blending operation, if applicable.
"This" or "current" texture refers to the texture currently being applied. "Previous" refers to whatever has been rendered so far, which could be a single texture or the result of an earlier blending operation.
|
Replace the previous layer entirely with the current bitmap. No blending. |
|
Blend the two textures using this texture's alpha value. This is the most common type of blending. |
|
RGB value > 0.5 brightens the previous image, < 0.5 darkens. color is a synonym for this method. |
|
Add this texture's RGB values multiplied by alpha to the previous layer. |
|
Subtract this texture's RGB values from the previous layer. |
|
Multiply the previous RGB values by this texture's RGB values |
|
Add this texture's RGB values to the previous layer. |
|
New RGB = (1 - Current RGB) * Previous RGB |
|
New RGB = 1 - (1 - Current RGB) * (1 - Previous RGB) |