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.
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.
{
"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
| Kind | Behavior | Main connected slot |
|---|---|---|
standard | Classic four-quadrant CTM | overlay_connected |
tbs | Distinct top, bottom, and side connections | Face-specific connected slots |
bookshelf | Horizontal bookshelf joins on horizontal faces | overlay_horizontal |
ctmh / ctmv | Horizontal or vertical directional CTM | Directional overlay slot |
edges | Quadrant edge connections with obscured-face support | overlay_connected |
edges_full | Selects a 4×4 atlas cell and stretches it over the face | overlay_connected |
multiblock_2x2 / 3x3 / 4x4 | Fixed repeating multiblock artwork | Matching multiblock slot |
v4 / v9 / v16 | Deterministic provider-based multiblock | 2×2, 3×3, or 4×4 slot |
r4 / r9 / r16 | Random per-position selection | 2×2, 3×3, or 4×4 slot |
ar | Deterministic anti-repeat selection | overlay_2x2 |
Texture slots and material controls
"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": falseCommon 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.
"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.
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.
{
"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
}
}
]
}water_offset on the upper layer when overlapping quads would otherwise z-fight.