A snippet of a properties file.

This page details the rules and formats for specifying how OptiFine features work in a resource pack.

File naming rules

For any file in a resource pack to be visible to the game, it must match the regular expression ^[a-z0-9_.]+$.


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. Do not use an ASCII encoding.

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 resourcepack.

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.

# Blank lines are allowed.

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.

Certain types of objects are used within properties files by different OptiFine features. Rather than describe these common types separately in each feature section, they are summarized here instead.


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 forward slashes "/" to separate folders.


Regardless of operating system, do not use backslashes "\", or the game will not properly recognize the path.

The below table summarises path shortcuts:


Resolves to






Not valid syntax





Bare filename

Bare filenames with no slashes will refer to the file relative to /assets/minecraft/optifine/, ignoring sub-folders.


Dot and dot-dot

You can use ./ to denote the current directory, regardless of location. This does work in subfolders. .. can be used to travel up a folder, into the parent directory.



The tilde character ~ can be used to refer to /assets/minecraft/optifine/.



An optional "namespace" prefix can be added. This example refers to exactly the same "creeper.png" file as default:


For textures used by other mods, the namespace will be something other than minecraft:


This refers to /assets/MODID/subfolder/texture.png, not to /assets/minecraft/MODID/subfolder/texure.png.

Namespaces can also apply to blocks, items, and biome IDs.


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


OptiFine supports conditions based off of an item's NBT.

If multiple NBT rules are provided, all of them must match.

A value starting with ! negates the match (match all EXCEPT 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 specific value: nbt.X=Y

  • Match number in range: nbt.X=range:0-100

  • Match if Y is 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


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 in the item's NBT.

# Apply to items that have any lore

# Apply to items that have no lore at all

New in version I1.


See also

Familiarize yourself with (S)NBT data types.

Raw exact values may be matched by using the raw: prefix. All values for raw: must be typed exactly as they are shown in the game's output log.

Raw can be used to match types explicitly, such as bytes, shorts, floats, doubles, etc.

nbt.display.Name=raw:'[{"text":"Dark red italics","italic":true,"color":"dark_red"}]'

The value must match exactly as the game reports it.

raw: can also be combined with all other prefixes. For example: raw:pattern:, raw:regex:, etc.

New in version I1.

Blocks and items

See also

See this page for the ID to name conversions
See this page for the 1.13 block & item changes


Do not use 1.7- IDs in 1.13+ packs!

In 1.13, many variant blocks were "flattened" to several simple blocks, and the block metadata was removed from their ID.

The block name format is [namespace:]name[:property1=value1,...:property2=value1,...]. Optional parts are in angle brackets [ ]. The default namespace is minecraft.

  • Before 1.7, items can only be specified by ID.

  • Since 1.7, items can also be specified by name, alongside ID.

  • Since 1.13, items can only be specified by name, not ID.

The block IDs continue to exist within the game internally, but can no longer be specified in the configuration files as they are unstable. For example, Stone used to be ID 1, but is now named minecraft:stone.

As with textures, the "minecraft:" prefix is optional, so just "stone" will also work, as "minecraft:" is the default.

In the event of mods, they will likely use a namespace other than minecraft:, so the prefix will be required for referring to modded items.


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.


This section is about matching strings and values using different matching methods. Strings can be matched in several ways.


Any backslashes must be doubled. Matching backslashes within a regular expression or wildcard must be quadrupled.





  •\\ (for matching \\)

  •\/\\ (missing a backslash)

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 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.

The wildcard * is equivalent to the regular expression .* (0 or more).
The wildcard ? is equivalent to the regular expression .+ (1 or more).

Wildcard patterns must start with either pattern: or ipattern:.


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 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


  • A Letter to Herobrine (A is not in expression)



Numbers can be matched simply by typing the number. Additionally, you can match more than one number as well as a range of numbers with lists and ranges.



There is no range for less than or equal to; use a full range: 0-100, not -100 to match ≤100.

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

# 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.

# Negative number, not a range
# Only matches negative 100, not -4, -7, or -101

Since 1.18 (with OptiFine H5), negative values may be specified also. When used in a range, they must be surrounded by parentheses.

To use negative numbers in a range, parentheses must be around those negative numbers.


These can be combined to create vast ranges of possible numeric values.



range: was added in 1.19.2 I1 pre1.

Ranges of numbers can also be matched by using the range: prefix. They use the same syntax as the above, except they explicitly have range:.



Lists are defined with a space between each number. Multiple values are listed separately, split with spaces.

Each "entry" in the list can be either a single number, or a range.

For example,

numbers=1 2 3 4 5 6
numbers=10 70 23 -6 210
numbers=(-100)-200 500 900-



There is no support for HSL, CMYK, etc.

Color values are specified in hexadecimal RGB format, without the leading hashtag:

# White

# Black

# Red

# Green

# Blue

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.

"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})\)

Assumes latest OptiFine version.
Updated to commit 8ed2130d.