Syntax

_images/icon24.webp

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_.]+$.

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

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.

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

Caution

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

The below table summarises path shortcuts:

Symbol

Resolves to

None

/assets/minecraft/optifine/

./

/assets/minecraft/optifine/

../

Not valid syntax

~

/assets/minecraft/optifine/

namespace:

/assets/namespace/

Bare filename

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

texture=texture.png

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.

texture=./texture.png
texture=../texture.png
texture=../../subfolder/texture.png

Tildes

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

texture=~/texture.png
texture=~/subfolder/texture.png

Namespaces

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

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

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

NBT

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

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

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

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"}]'
nbt.3.OnGround=raw:1b
nbt.1.UUID=raw:'[I;-1668711424,-1434628111,-1613745989,1749596493]'
nbt.someRandomShort=raw:64s

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

Danger

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.

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.

Strings

This section is about matching strings and values using different matching methods. 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+

  • nbt.display.name=regex:\\ (for matching \\)

  • nbt.display.name=/\/\\ (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

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

Note

The meanings of ? and * are swapped in contrast to regular expressions. It is unknown if this is a bug.

pattern

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

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

regex

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

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

Numbers

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.

Ranges

Important

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

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.

list=(-3)-(-1)

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

Range

Note

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

nbt.N=range:A-B
nbt.number=range:0-100

Lists

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-

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

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

Replace the previous layer entirely with the current bitmap. No blending and only simple on/off transparency.

alpha

Blend the two textures using this texture's alpha value. This is the most common type of blending.

overlay

RGB value > 0.5 brightens the previous image, < 0.5 darkens. color is a synonym for this method.

add

Add this texture's RGB values multiplied by alpha to the previous layer.

subtract

Subtract this texture's RGB values from the previous layer.

multiply

Multiply the previous RGB values by this texture's RGB values

dodge

Add this texture's RGB values to the previous layer.

burn

\(RGB_{new} = (1 - RGB_{current}) * RGB_{previous}\)

screen

\(RGB_{new} = 1 - (1 - RGB_{current}) * (1 - RGB_{previous})\)


Assumes latest OptiFine version.
Updated to commit 8ed2130d.