Connected Textures

_images/icon5.webp

The textures appear to "connect".

File location

/assets/minecraft/optifine/ctm/**/*.properties

Connected Textures (CTM) connects matching blocks together, making them appear unified.

_images/settings4.webp

Video Settings ‣ Quality

Different types of connected texture methods are available with different requirements and restrictions.

General properties

These properties apply for all CTM methods.

Note

matchBlocks can be omitted if is can be inferred from the filename. Defined keys override this.

  • ~/ctm/xxx/block_<name>.properties assumes matchBlocks=<name>

method

Values: ctm, ctm_compact, horizontal, vertical, horizontal+vertical, vertical+horizontal, top, random, repeat, fixed, overlay_ctm, overlay_random, overlay_repeat, or overlay_fixed
Required

Method to use when choosing a block's replacement texture:

  • ctm: Standard 8-way method, 47 tiles.

  • ctm_compact: Compact 8-way method, uses 5 tiles. Cannot be combined with any overlay method.

  • horizontal: Connect to blocks on left and right only.

  • vertical: Connect to blocks above and below only.

  • horizontal+vertical: Connect horizontally, then connect vertically.

  • vertical+horizontal: Connect vertically, then connect horizontally.

  • top: Connect to block above only.

  • random: Pick a tile at random.

  • repeat: Repeat a fixed pattern over large areas.

  • fixed: Use a single fixed tile, equivalent to random with only one tile.

  • overlay: Overlay for block transitions, uses 17 tiles.

  • overlay_ctm: Overlay variant of ctm method.

  • overlay_random: Overlay variant of random method.

  • overlay_repeat: Overlay variant of the repeat method.

  • overlay_fixed: Overlay variant of fixed method.

Note

The overlay method can be combined with other methods if it comes before the other methods in the order alphabetically.

Warning

The ctm_compact method cannot be combined with any overlay method.

tiles

Values: Space-split list of tiles
Required

List of replacement tiles to use.

Different methods require a different number of tiles: some need as many as 47, some need only 1. This Each tile must be a separate image, just like terrain and item textures. Tiles can be specified in several ways:

  • name -> name.png

  • name.png -> name.png

  • 8-11 -> 8.png, 9.png, 10.png, 11.png

  • <skip> -> Skip this tile, continue with next CTM properties.

  • <default> -> Use the default texture for that block/tile.

  • full/path/name.png -> full/path/name.png

In all cases except the last (full path), the PNG file must be in the same directory as the properties file itself.

The formats can be mixed and matched: tiles=0-4 5 some/other/name.png.

Important

The overlay methods may use the special name <skip> for empty tiles to be skipped; overlay methods cannot use the <default> special name.

Tile index ordering

The order in which each tile name appears is its tile index. This index ordering is zero-indexed (starts from 0). It is ordered after expansion, for example: 0 1 3-5 6 counts as 7 tiles (0, 1, 2, 3, 4, 5, 7), not 4.

Index ordering is independent of the tile names. For example, 1 2 3 0 name 30-35 would have the index ordering of

Index ordering example

Tile index

Tile name

0

1

1

2

2

3

4

0

5

name

6

30

7

31

8

32

9

33

10

34

11

35

matchTiles

Values: List of strings
Optional

List of tiles this method should apply to.

Multiple .properties file can refer to the same block/tile and they will be processed in alphabetical order by filename. All tile-based entries are checked before block ID-based ones; the first match wins.

matchBlocks

Values: Space-split list of blocks + optional properties
Optional

List of blocks this method should apply to.

To refer to a tile from vanilla Minecraft, simply use its name in textures/block: matchBlocks=dirt To refer to a tile from a mod, its name must be known: matchBlocks=botania:blazeblock

Tiles output by CTM rules can also be matched by another rule; the tile name is simply the full path to the tile: matchBlocks=optifine/ctm/mygrass/1.png

Block format: (optional parts are in []) [namespace:]name[:property1=value1,value2...:property2=value1,value2...] For example:

  • Short name: oak_stairs

  • Full name: minecraft:oak_stairs

  • Full name + properties: minecraft:oak_stairs:facing=east,west:half=bottom

connect

Values: block, tile, or state
Optional
Default: block for blocks, tile for tiles

The conditions under which two blocks should connect. For methods that connect to adjacent blocks, this rule specifies how the game should decide if two blocks should be connected:

  • block: Connect if this block's name == neighbor block's name.

  • tile: Connect if this block's tile texture == neighbor tile's texture.

  • state: Connect if this block's full state (block + properties) == neighbor block's state.

faces

Values: List of strings
Optional

Limit CTM to certain faces of the block:

  • bottom: Bottom face (negative Y).

  • top: Top face (positive Y).

  • north: North face (negative Z).

  • south: South face (positive Z).

  • east: East face (positive X).

  • west: West face (negative X).

  • sides: Shorthand for north south east west.

  • all: All sides.

This works for all blocks, regardless of shape.

Note

If the block has the axis block state property, the face to check is appropriately rotated.

biomes

Values: Space-split list of biomes
Optional

Biome restrictions. Modded biomes also can be used.

If the first character is !, the list is inverted. For example:

biomes=!jungle deep_ocean birch_forest

will match a biome that is neither a Jungle, Deep Ocean, or Birch Forest.

Note

Prefixing each biome name with ! does nothing.

heights

Values: Space-split list of integers or integer Range.
Optional

Height restriction, no limit.

minHeight

Legacy

Legacy property for heights.

maxHeight

Legacy

Legacy property for heights.

name

Optional

Only for blocks which have corresponding nameable tile entities. Generally, this means containers that can be renamed.

For example: Beacon, Brewing Stand, Enchanting Table, Furnace, Dispenser, Dropper, Hopper, and Command Blocks.

Method properties

ctm: standard 8-way

Note

Implies method=ctm.

_images/ctm.webp

Important

The 47th tile is unused; it is marked in black.

tiles

Values: Space-split list of 47 tiles
Required

List of the 47 tiles to use when connecting.

innerSeams

Values: Boolean
Optional
Default: false

Whether to show seams on inner edges when connecting to adjacent blocks.

ctm_compact: compact 8-way

Note

Implies method=ctm_compact,

_images/compact.webp

tiles

Values: Space-split list of 5 tiles
Required

List of the 5 tiles to use when connecting.

innerSeams

Values: Boolean
Optional
Default: false

Whether to show seams on inner edges when connecting to adjacent blocks.

ctm.N

Values: Tile index
Optional

Compact CTM tile replacement. Allows definition of replacement tile for a specific CTM case.

N is the index of the tile from the full ctm method template (47 total tiles, indexed 0-46).

With ctm_compact and this option, more than 5 tiles can be defined.

Important

This is generally only used for special cases where you want to override the default behavior.

horizontal: horizontal only

Note

Implies method=horizontal.

_images/horizontal.webp

tiles

Values: Space-split list of 4 tiles
Required

List of the 4 tiles to use when connecting.

vertical: vertical only

Note

Implies method=vertical.

_images/vertical.webp

tiles

Values: Space-split list of 4 tiles
Required

List of the 4 tiles to use when connecting.

top: top face only

Note

Implies method=top.

tiles

Values: String
Required

The single tile to use when connecting.

random: random connect

Note

Implies method=random.

tiles

Values: Space-split list of tiles
Required

List of the tiles to use when connecting. Can be infinitely long or short.

weights

Values: Space-split list of integers
Optional

List of weights to apply to the random choice.

For example, for tiles=1 2 3 4; weights=10 1 10 5, tile 1 has weight 10, 2 has 1, 3 has 10, and 4 has 5. Weights do not have to total any value; in the above example, tiles 1 and 3 will each be used ~38% of the time.

The amount of numbers in this list should be equal to the amount in tiles but it does not have to be.

  • If fewer: Missing weights are all the average of the defined weights.

  • If greater: Extra weights are ignored.

randomLoops

Values: Integer Range from 0 to 9
Optional
Default: 0

Repeats the random function by this amount to increase randomness. Can be used to make different textures use different random patterns.

Warning

A high randomLoops value may decrease the chunk loading speed.

symmetry

Values: none, opposite, or all
Optional
Default: none

Desired level of symmetry for the faces of each block.

Applies to standard 6-sided blocks only (dirt, glass, not fences).

  • none: All 6 faces are textured independently.

  • opposite: 2-way symmetry; opposing faces have the same texture, but each pair can potentially have a different texture.

  • all: All 6 faces have the same texture.

linked

Values: Boolean
Optional
Default: false

Whether to link textures between related blocks.

If true, OptiFine uses the same random number seed for all blocks of a contiguous column. For example, the top and bottom halves of tall grass. This allows randomized textures that will remain consistent within each set of blocks.

If false, the two halves will be scrambled, chosen independently.

Important

For linked to work, multiple properties files with linked=true and the same number of replacement textures and same set of weights must be present. For example, double_plant_top.properties:

method=random
tiles=grass_top1 grass_top2 grass_top3
weights=1 2 3

repeat: repeated

Note

Implies method=repeat.

width

Values: Integer
Required

The width of the repeating pattern.

height

Values: Integer
Required

The height of the repeating pattern.

tiles

Values: Space-split list of tiles
Required

A list of tiles. The number of elements must equal width * height.

fixed: one texture

Note

Implies method=fixed.

tiles

Values: String
Required

Single tile to use.

overlay: texture atop

Note

Implies method=overlay

_images/overlay.webp

Important

17th, 18th, 19th, and 20th tiles are unused.

tiles

Values: Space-split list of tiles
Required

List of replacement tiles to use.

May use the special name <skip> for empty tiles to be skipped; cannot use the <default> special name.

connectTiles

Values: Space-split list of tiles
Optional

Connect only to blocks which are using the specified tiles.

connectBlocks

Values: Space-split list of blocks
Optional

List of blocks to connect to.

tintIndex

Values: Integer
Optional
Default: -1; disabled

What tint index to use for the tile's texture.

Use -1 to disable it.

tintBlock

Values: Block
Optional

The block used for the tile texture tinting.

Different blocks use different colors for the same tint index.

layer

Values: String of cutout_mipped, cutout, or translucent
Optional
Default: cutout_mipped

The layer on which the overlay texture should be rendered.

Values:

  • cutout_mipped: Transparent textures with mipmaps.

  • cutout: Transparent textures without mipmaps.

  • translucent: Translucent textures with mipmaps.

JSON schema

Note

Although this page is .properties based, it can be mapped to JSON.

{
	"$schema": "http://json-schema.org/draft/2020-12/schema",
	"$id": "https://gitlab.com/whoatemybutter/optifinedocs/-/blob/master/schemas/ctm.schema.json",
	"title": "Connected Textures",
	"description": "Connected Textures (CTM) connects matching blocks together, making them appear unified.",
	"type": "object",
	"properties": {
		"method": {
			"enum": [
				"ctm",
				"ctm_compact",
				"horizontal",
				"vertical",
				"horizontal+vertical",
				"vertical+horizontal",
				"top",
				"random",
				"repeat",
				"fixed",
				"overlay_ctm",
				"overlay_random",
				"overlay_repeat",
				"overlay_fixed"
			],
			"description": "Method to use when choosing a block's replacement texture."
		},
		"tiles": {
			"type": "string",
			"description": "Space-separated string of replacment tiles to use."
		},
		"matchTiles": {
			"$ref": "common.schema.json#/$defs/item_id_list",
			"description": "Space-separated string of tiles this method should apply to."
		},
		"matchBlocks": {
			"$ref": "common.schema.json#/$defs/item_id_list",
			"description": "Space-separated string of blocks this method should apply to."
		},
		"weight": {
			"type": "integer",
			"default": 0,
			"description": "If multiple properties files match the same block, the highest weighted one is used."
		},
		"connect": {
			"enum": [
				"block",
				"tile",
				"state"
			],
			"description": "The conditions under which two blocks should connect."
		},
		"connectTiles": {
			"$ref": "common.schema.json#/$defs/item_id_list",
			"description": "Connect only to blocks which are using the specified tiles."
		},
		"faces": {
			"type": "string",
			"pattern": "(bottom|top|north|south|east|west|sides|all) ?",
			"description": "Limit CTM to certain faces of the block."
		},
		"biomes": {
			"type": "string",
			"description": "Space-separated string of biome restrictions."
		},
		"heights": {
			"type": "string",
			"description": "Height restriction ranges."
		},
		"minHeight": {
			"type": "integer",
			"minimum": -65535,
			"deprecated": true,
			"description": "Legacy key for heights."
		},
		"maxHeight": {
			"type": "integer",
			"maximum": 65535,
			"deprecated": true,
			"description": "Legacy key for heights."
		},
		"tintIndex": {
			"type": "integer",
			"minimum": -1,
			"default": -1,
			"description": "Tint index, only for overlay method."
		},
		"tintBlock": {
			"$ref": "common.schema.json#/$defs/item_id",
			"description": "The block used for the tile texture tinting."
		},
		"layer": {
			"enum": [
				"cutout_mipped",
				"cutout",
				"translucent"
			],
			"default": "cutout_mipped",
			"description": "The layer on which the overlay texture should be rendered."
		},
		"name": {
			"type": "string",
			"description": "Only for blocks with have corresponding nameable tile entities."
		}
	},
	"patternProperties": {
		"^ctm\\.\\d+$": {
			"type": [
				"string",
				"integer"
			],
			"minimum": 0,
			"description": "Compact CTM tile replacement. Allows definition of replacement tile for a specific CTM case."
		}
	},
	"required": [
		"tiles"
	],
	"additionalProperties": false,
	"allOf": [
		{
			"if": {
				"properties": {
					"connectTiles": {}
				}
			},
			"then": {
				"properties": {
					"method": {
						"const": "overlay"
					}
				}
			}
		},
		{
			"if": {
				"patternProperties": {
					"^ctm\\.\\d+$": {}
				}
			},
			"then": {
				"properties": {
					"method": {
						"const": "ctm_compact"
					}
				}
			}
		},
		{
			"if": {
				"properties": {
					"tintIndex": {}
				}
			},
			"then": {
				"properties": {
					"method": {
						"const": "overlay"
					}
				}
			}
		},
		{
			"if": {
				"properties": {
					"layer": {}
				}
			},
			"then": {
				"properties": {
					"method": {
						"const": "overlay"
					}
				}
			}
		},
		{
			"if": {
				"properties": {
					"method": {
						"const": "ctm"
					}
				}
			},
			"then": {
				"properties": {
					"innerSeams": {
						"type": "boolean",
						"default": false,
						"description": "Whether to show seams on inner edges when connecting to adjacent blocks."
					}
				}
			}
		},
		{
			"if": {
				"properties": {
					"method": {
						"const": "ctm_compact"
					}
				}
			},
			"then": {
				"properties": {
					"innerSeams": {
						"type": "boolean",
						"default": false,
						"description": "Whether to show seams on inner edges when connecting to adjacent blocks."
					}
				},
				"patternProperties": {
					"^ctm\\.\\d+$": {
						"type": [
							"string",
							"integer"
						],
						"minimum": 0,
						"description": "Indexes of replacement tiles for specific CTM cases."
					}
				}
			}
		},
		{
			"if": {
				"properties": {
					"method": {
						"const": "random"
					}
				}
			},
			"then": {
				"properties": {
					"weights": {
						"type": "string",
						"description": "Space-separated string of weights to apply to the random choice."
					},
					"randomLoops": {
						"type": "integer",
						"minimum": 0,
						"maximum": 9,
						"description": "Repeats the random function by this amount to increase randomness."
					},
					"symmetry": {
						"enum": [
							"none",
							"opposite",
							"all"
						],
						"default": "none",
						"description": "Desired level of symmetry for the faces of each block."
					},
					"linked": {
						"type": "boolean",
						"default": false,
						"description": "Whether to link textures between related blocks."
					}
				}
			}
		},
		{
			"if": {
				"properties": {
					"method": {
						"const": "repeat"
					}
				}
			},
			"then": {
				"properties": {
					"width": {
						"type": "integer",
						"minimum": 1,
						"maximum": 16384,
						"description": "The width of the repeating pattern."
					},
					"height": {
						"type": "integer",
						"minimum": 1,
						"maximum": 16384,
						"description": "The height of the repeating pattern."
					},
					"symmetry": {
						"enum": [
							"none",
							"opposite"
						],
						"default": "none",
						"description": "Desired level of symmetry for the faces of each block."
					}
				},
				"required": [
					"width",
					"height"
				]
			}
		}
	]
}

Assumes the latest OptiFine version.
Updated to commit 7b2f8c63.

Last update: 2024 September 26