Home/CTM reference

Documentation / CTM

Connected textures, defined.

CTM helps you add connected textures to your NeoForge mod. Start with seamless surfaces, then try larger patterns, layers, glowing textures, or overlays that appear under specific conditions.

CTM 26.1.2.8JSON modelsFluent datagen

Minimal blockstate model

Put the custom model definition directly at the root of the blockstate JSON. CTM uses NeoForge's neoforge:definition_type; it is not a vanilla loader field.

assets/examplemod/blockstates/connected_block.json
{
  "neoforge:definition_type": "ctm:connected_texture_model",
  "model_location": "examplemod:block/connected_block",
  "connected_faces": ["all"],
  "variant": {
    "block": "examplemod:connected_block",
    "kind": "standard"
  }
}

The referenced block model supplies texture slots and ordinary model properties. You can also add or override slots directly with a texture_slots object.

Supported model kinds

KindBehaviorMain connected slot
standardClassic four-quadrant CTMoverlay_connected
tbsDistinct top, bottom, and side connectionsFace-specific connected slots
bookshelfHorizontal bookshelf joins on horizontal facesoverlay_horizontal
ctmh / ctmvHorizontal or vertical directional CTMDirectional overlay slot
edgesQuadrant edge connections with obscured-face supportoverlay_connected
edges_fullSelects a 4×4 atlas cell and stretches it over the faceoverlay_connected
multiblock_2x2 / 3x3 / 4x4Fixed repeating multiblock artworkMatching multiblock slot
v4 / v9 / v16Deterministic provider-based multiblock2×2, 3×3, or 4×4 slot
r4 / r9 / r16Random per-position selection2×2, 3×3, or 4×4 slot
arDeterministic anti-repeat selectionoverlay_2x2

Texture slots and material controls

JSON fragment
"texture_slots": {
  "base_texture": "examplemod:block/base",
  "overlay_texture": "examplemod:block/unconnected",
  "overlay_connected": "examplemod:block/connected",
  "particle": "examplemod:block/base"
},
"base_tint_index": -1,
"base_emissivity": 0,
"tint_index": -1,
"emissivity": 0,
"shade": true,
"eldritch": false

Common slots include base_texture, overlay_texture, overlay_connected, face-specific TBS slots, overlay_horizontal, overlay_vertical, overlay_2x2, overlay_3x3, overlay_4x4, and particle. Custom overlay rules may refer to additional named materials.

Control what connects

By default, a CTM model connects to the same block. Use connects_to to accept other blocks or a specific block state.

JSON fragment
"connects_to": [
  { "id": "examplemod:connected_block" },
  {
    "id": "minecraft:oak_log",
    "state": { "id": "axis", "value": "y" }
  }
]

A match with any entry in the list allows a connection. To limit connections to certain faces, use names such as north and south, or use ["all"].

Generate a standard CTM model

CTMModelTemplates writes the supporting block model and CTMBlockStateGenerator writes the custom blockstate root.

Java
Identifier base = Identifier.fromNamespaceAndPath(
        "examplemod", "block/connected_block");
Identifier connected = Identifier.fromNamespaceAndPath(
        "examplemod", "block/connected_block_ctm");

TextureMapping textures = new TextureMapping()
        .put(TextureSlot.PARTICLE, base)
        .put(CTMTextureSlots.BASE, base)
        .put(CTMTextureSlots.OVERLAY_CONNECTED, connected);

Identifier model = CTMModelTemplates.STANDARD.create(
        block, textures, blockModels.modelOutput);

CTMModelBuilder builder = CTMModelBuilder.standard(block, model)
        .allFaces();

blockModels.blockStateOutput.accept(
        CTMBlockStateGenerator.of(block, builder));

Builder factories are available for standard, TBS, anti-repeat, bookshelf, horizontal, vertical, edges, edges-full, and fixed 2×2/3×3/4×4 multiblock models.

Layer independent CTM models

Use ctm:layered_connected_texture_model when a block needs two or more independently connected surfaces. Layers draw bottom-to-top and may use different kinds, face sets, connection predicates, and textures.

JSON fragment
{
  "neoforge:definition_type": "ctm:layered_connected_texture_model",
  "layers": [
    {
      "model_location": "examplemod:block/bottom_layer",
      "connected_faces": ["all"],
      "variant": {
        "block": "examplemod:layered_block",
        "kind": "standard"
      }
    },
    {
      "model_location": "examplemod:block/top_layer",
      "connected_faces": ["all"],
      "variant": {
        "block": "examplemod:layered_block",
        "kind": "standard",
        "water_offset": true
      }
    }
  ]
}
Keep overlapping layers from flickering. Use transparency in upper textures and enable water_offset on the upper layer when overlapping quads would otherwise z-fight.