Syntax¶
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.
This page also details the rules and other resource pack-related technical information.
File name¶
For any file in a resource pack to be visible to the game, it must match the regular expression ^[a-z0-9_.]+$
(r101).
Hint
Must be lowercase, no spaces, a through z, 0 through 9, and _ only.
Textures must be in PNG format with the .png
extension.
All text files must be encoded in UTF-8 without BOM.
JSON files must follow the JSON specification strictly and have the .json
extension.
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¶
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.
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
.
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
NBT¶
From NBT format - Minecraft Wiki:
The Named Binary Tag (NBT) is a tree data structure used by Minecraft in many save files to store arbitrary data.The format is comprised of a handful of tags. Tags have a numeric ID, a name, and a payload.A user-accessible version in the form of strings is the stringified Named Binary Tag (SNBT) format.
OptiFine supports conditions based on an item's NBT.
If multiple NBT rules are provided, all of them must match.
A value starting with an exclamation mark "!
" negates the match (match the opposite of this).
List indexes start at 0; 0 is the first element, 1 is the second.
All Unicode codepoints can be escaped with \uXXXX
,
but this is not required and is recommended for non-visible characters or characters above U+007E TILDE ~.
Some examples include:
Match if Y is in list X:
nbt.X.*=Y
Match a specific value:
nbt.X=Y
Match X in range:
nbt.X=range:0-100
Match if Y is the first entry of list X:
nbt.X.0=Y
Match if X exists:
nbt.X=exists:true
Match item display name:
nbt.display.Name=My Sword
Match item display name with escapes:
nbt.display.Name=\u00a74\u00a7oMy Sword
Match item lore (first line only):
nbt.display.Lore.0=My Lore Text
Match item lore (any line):
nbt.display.Lore.*=My Lore Text
Exists¶
You can check for the presence of an NBT value for a given tag by using the exists:
prefix.
It takes only two values: true
and false
.
true
will apply if the NBT key given has any value associated with it.
false
will apply if the NBT key given is not present.
# Apply to items that have any lore
nbt.display.Lore=exists:true
# Apply to items that have no lore at all
nbt.display.Lore=exists:false
New in version I1.
Raw¶
See also
Familiarize yourself with (S)NBT data types.
Exact SNBT values may be matched by using the raw:
prefix.
Raw can be used to match types explicitly, such as bytes, shorts, floats, doubles, etc.
All values for raw:
must match exactly as the game reports it, except that the spaces in between values must be removed.
nbt.display.Name=raw:[{"text":"Dark red italics","italic":true,"color":"dark_red"}]
nbt.3.OnGround=raw:1b
nbt.1.UUID=raw:[I;-1668711424,-1434628111,-1613745989,1749596493]
nbt.someRandomShort=raw:64s
raw:
can also be combined with all other prefixes. For example: raw:pattern:
, raw:regex:
, etc.
New in version I1.
Range¶
Ranges of numbers can be matched by using the range: prefix.
They use a simple a-b
syntax:
nbt.N=range:A-B
nbt.number=range:0-100
New in version I1: pre1
Strings¶
This section is about matching strings and values using different matching methods.
By default, any formatting (like color
or bold
) is stripped out.
To test specifically for the presence of this formatting, use Raw.
Strings can be matched in several ways.
Important
Any backslashes must be doubled. Matching backslashes within a regular expression or wildcard must be quadrupled.
nbt.display.name=regex:\\d+
nbt.display.name=regex:\\\\
nbt.display.name=/\\/\\
nbt.display.name=regex:\d+
(missing a backslash for\d
)nbt.display.name=regex:\\
(for matching\\\\
; would match\
alone)nbt.display.name=/\/\\
(missing a backslash for\/
)
Exact value¶
For strings, you may either type the string directly: Letter to Herobrine
matches the exact string Letter to Herobrine
and nothing else.
You may also use the Raw syntax.
Wildcards¶
Wildcards are shorter versions of regular expressions, in that they only support two unique constructs:
The symbol
?
matches any text, as long as it exists.The symbol
*
matches any text, regardless of its presence.
*
is equivalent to the regular expression .*
(0 or more).?
is equivalent to the regular expression .+
(1 or more).Wildcard patterns must start with either pattern:
or ipattern:
.
Note
The meanings of ?
and *
are swapped in contrast to regular expressions. It is unknown if this is a bug.
pattern
is case-sensitive.
Example: pattern:*Letter to ?
Letter to Herobrine
Letter to a creeper
My Letter to John
(note the uppercase L)letter to Herobrine
(case sensitivity)Letter from Herobrine
(doesn't match "to")Letter to
(doesn't match "?")
ipattern
is case-insensitive, meaning that "ABC" and "abc" are viewed the same.
Example: ipattern:*Letter to ?
Letter to Herobrine
My letter to Herobrine
Letter to a creeper
letter to Herobrine
letter to STEVE!
A letter from CJ
Letter from Herobrine
Regular expressions¶
Regular expressions are strings that create "patterns" that other strings can be matched against.
Patterns can be as simple as .
, to IP address validation.
OptiFine supports two types of regular expressions, depending on the case sensitivity.
In addition, OptiFine does not support
expression flags.
The syntax understood by OptiFine is the Java syntax. OptiFine regular expressions are not multiline and are not global ("/gm").
Regular expressions must start with either regex:
or iregex:
.
A case-sensitive regular expression.
Example: regex:Letter (to|from) .*
Letter to Herobrine
Letter from Herobrine
letter to Herobrine
(letter case)A Letter to Herobrine
(A
is not in expression)
iregex
is similar to regex
, except that it is case-insensitive.
Example: iregex:Letter (to|from) .*
Letter to Herobrine
Letter from Herobrine
letter to Herobrine
LETTER TO HEROBRINE
A Letter to Herobrine
(A is not in expression)LETTER TOFROM HEROBRINE
Client-side data¶
Not all NBT tags 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 NBT 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 NBT tag visibly alters the entity, it can likely be used.
There is no definitive list yet of what NBT tags are client-side and which ones are not.
Numbers, ranges¶
Numbers can be specified simply by typing them. Additionally, you can match more than one number with lists, ranges, or both.
Inclusive ranges between numbers are defined with a -
between those digits.
If there is no number present on the right side of the -
, the range will match to positive infinity.
Ranges can be combined and intermixed with lists.
For example,
# 1, 2, 3
numbers=1-3
# Multiple ranges
# 1 through 3, or 6, or 8, or 10 through 15
# 1, 2, 3, 6, 8, 10, 11, 12, 13, 14, 15
numbers=1-3 6 8 10-15
# Greater than or equal to
# 100, or 200, or 5340, or 25902, etc.
numbers=100-
# Negative number, not a range
# Only matches negative 100, not -4, -7, or -101
numbers=-100
# Negative numbers in range
# -3, -2, -1
numbers=(-3)-(-1)
Since 1.18 (with OptiFine H5), negative values may also be specified. When used in a range, they must be surrounded by parentheses to prevent ambiguity.
Important
There is no range for less than or equal to; use a full range: 0-100
, not -100
to match ≤100.
Lists¶
Lists are defined with a space between each item. An item can be any text that is not used in the NBT selection. Multiple values are listed separately, split with a space.
For example,
numbers=1 2 3 4 5 6
biomes=ocean plains flower_forest
blocks=bricks gold end_portal_frame oak_stairs:facing=west,north:half=top
A list can have only 1 element.
Colors¶
Note
There is no support for HSL, CMYK, etc.
Color values are specified in hexadecimal RGB format, without the leading hashtag:
# White
color=ffffff
# Black
color=000000
# Red
color=ff0000
# Green
color=00ff00
# Blue
color=0000ff
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
.
blocks=minecraft:oak_stairs:facing=east,west:half=bottom
blocks=oak_stairs:facing=east,west:half=bottom
The above will apply to oak stairs that are east or west facing and are the bottom half.
The minecraft:
namespace is optional, so it can also be omitted.
Item NBT can only be specified (if available) through the nbt.X=Y
rules.
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 and only simple on/off transparency. |
|
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. |
|
\(RGB_{new} = (1 - RGB_{current}) * RGB_{previous}\) |
|
\(RGB_{new} = 1 - (1 - RGB_{current}) * (1 - RGB_{previous})\) |