Overview

In terraria, tiles that don't have a U/V coordinate stored in the map will have their U/V coordinates calculated at runtime. The calculations involve the types of tiles that surround the tile, as well as a small bit of randomness. I will cover the three main types of tile textures, as well as the rules that determine which part of the texture is shown.

Texture Template

The figure to the right is the overall tile texture template. Pretty much all calculated tile textures (with the exception of #19—wooden platform, and #80—cactus) use a part of this template. There are four notable areas of the template. The first area, marked in blue is the "base zone". This zone is used by all tile textures. Wall textures are comprised of solely this base zone. The second area, marked in purple is the "blend zone". This zone is used by tiles that blend with dirt. The third area, marked in green is the "grass zone". This zone is used by grass textures. The final area, marked in orange is the blend/grass zone. This zone is used by both blend and grass textures.

It looks rather complicated, but breaking it down into zones makes it easier to work out. A grass texture would first check rules that fall in the green "grass zone" and the orange "blend/grass" zone. If it failed to find a match, it would then check rules that fall in the blue "base zone". It will definitely find a match in the base zone, since it has the broadest rules.

Finally, There are 3 types of tiles that use these textures. Grasses, which are all the grasses (corrupt, hallowed, normal). These use the grass zone, the blend/grass zone, and the base zone. Tiles which blend into dirt, these use the blend zone, the blend/grass zone, and the base zone. Finally tiles which aren't grass and don't blend to dirt. These use the base zone only.

One note about blending. You might think that stone and gemstones "blend" with each other. They don't. Stone and gemstones are considered the same thing. When checking the neighbors, ruby will treat nearby stone as more ruby. Ruby will treat nearby emerald as more ruby. Stone will treat any gemstone as more stone, and so forth.

The texture grid is actually 3 times bigger than it needs to be. You'll see several blocks are joined by dotted-lines into a 3x1 or 1x3 area. These actually represent a single tile, but with 3 different variants. The particular variation is chosen randomly, this gives repeating textures some "noise", and makes them interesting. Every texture block has 3 variations. Looking at the template, you can see A1, B1, and C1 are all variations of each other. Basically they all match the same ruleset. However, you'll notice that D1 doesn't seem to have any variants. It does, but they're not grouped together. D1, D3, and D5 are all part of the same group. D2, D4, and D6 are a group as well.

Rules

Now that we have an overview, let's look at the rules. Basically, what we care about are the tiles that surround our tile. We care which, if any, of these tiles "match" our tile. A match could mean the adjacent tile is the same tile type, or it could mean the adjacent tile "blends" with our tile type. We then choose the texture that fits.

Let us look at a very limited example, let's just look at a tile (call it X), and take into consideration the tile next to it (call it Y). There are 3 different possible states. State 1: X and Y are the same type. State 2: X and Y are different types, but can blend. State 3: X and Y are not the same.

Naturally, in this very limited viewpoint, there would be 9 different tiles for those 3 different states (Don't forget each tile has 3 variations, that's why there are 9 tiles in this case, not 3).

If you're doing the math, you'd see that for 8 surrounding tiles (up, down, left, right, upper left, upper right, lower left, lower right), and 3 states per relation, there would be 512 different states, and 1,536 unique textures per texture file. Of course there aren't that many blocks in each texture file, not by a long shot. This is because not every possible state has a unique texture.

For the most part, only care about the corner tiles in very specific circumstances. In the following tables, the corner tiles can be anything, unless explicitly marked as included or excluded (with "!"). The same can't be said for the edges. If an edge isn't listed, then it must not match.

For example, A7-A9 in the Base Zone shows a single match of Bottom. This means that the tiles to the Top, Left, and Right must not match, and the corner tiles can match or not, it doesn't matter.

The corners are represented by TL = Top Left, TR = Top Right, BL = Bottom Left, BR = Bottom Right.

Another example is A11-C11. In this case, all the sides must match, but the Top Left and Bottom Left tiles must *not* match. We don't care whether or not the Top Right or Bottom Right tiles match.

Base Zone Specifics

Now let's look at the actual base zone, and the tile rules that determine which blocks to use. With the base zone, we don't care about blending, we only care if tiles match, or don't match.

TilesMatches
A1-C1Top, Bottom, Right
A2-A4Left, Bottom, Right
A5-C5Top, Bottom, Left
A6-C6Top, Bottom
A7-A9Bottom
A10-C10Right
A11-C11All, !TL, !BL
A12-C12All, !TR, !BR
A13-C13Left
B2-B4All, default
B7-B9All, !TL, !TR
C2-C4Left, Top, Right
C7-C9All, !BL, !BR
D1,D3,D5Bottom, Right
D2,D4,D6Bottom, Left
D7-D9Top
D10-D12Nothing
E1,E3,E5Top, Right
E2,E4,E6Top, Left
E7-E9Left, Right

Blend Zone Specifics

This zone is for tiles that blend into dirt. These rules should be checked alongside the rules for Blend/Grass zone. If those rules fail, mark all blends as "not a match" and try the Base zone.

TilesMatchesBlends
A14-A16Left, RightBottom
B14-B16Left, RightTop
C14-C16Top, BottomRight
D14-D16Top, BottomLeft
F1,H1,J1AllBR
F2,H2,J2AllBL
F12-H12BottomLeft, Top, Right
F13-H13RightTop, Bottom, Left
G1,I1,K1AllTR
G2,I2,K2AllTL
I12-K12TopLeft, Bottom, Right
I13-K13LeftTop, Bottom, Right

Grass Zone Specifics

This zone is for tiles that are considered grasses. Corrupt grass, hallowed grass, etc. These rules should be checked alongside the Blend/Grass zone rules. If those blends fail, all blends should be marked as a match (this is different than the tiles which use the Blend zone), and then you should try the Base zone.

If a side or corner is in both the matches and blends column, it means either one can match.

TilesMatchesBlends
M8,M11,M14---unused------unused---
M9,M12,M15Left, Bottom, Right, !BL, !BR!BL, !BR
M10,M13,M16---unused------unused---
O8,O11,O14Top, Bottom, Right, !TR, !BR!TR, !BR
O9,O12,O15All, !TL, !TR, !BL, !BR
O10,O13,O16Top, Bottom, Left, !TL, !BL!TL, !BL
P8,P11,P14---unused------unused---
P9,P12,P15Left, Top, Right, !TL, !TR!TL, !TR
P10,P13,P16---unused------unused---
Q1-S1RightTop, Bottom
Q2-S2LeftTop, Bottom
Q3-Q5BottomLeft, Right
Q6-Q8Bottom, Right, !BR!BR
Q9-Q11Bottom, Left, !BL!BL
Q12-Q14BottomLeft, Top, Right
R3-R5TopLeft, Right
R6-R8Top, Right, !TR!TR
R9-R11Top, Left, !TL!TL
R12-R14TopLeft, Bottom, Right
S3-S5All, !TL, !BR
S6-S8All, !TR, !BL
S9-S11RightTop, Bottom, Left
S12-S14LeftTop, Bottom, Right
T1-T3Left, Bottom, Right, BL, !BRBL, !BR
T4-T6Left, Bottom, Right, !BL, BR!BL, BR
T7-T9All, !TL, !TR, !BLBR
U1-U3Left, Top, Right, TL, !TRTL, !TR
U4-U6Left, Top, Right, !TL, TR!TL, TR
U7-U9All, !TL, !BL, !BRTR
V1-V3Top, Bottom, Right, !TR, BR!TR, BR
V4-V6Top, Bottom, Right, TR, !BRTR, !BR
V7-V9All, !TL, !TR, !BRBL
W1-W3Top, Bottom, Left, TL, !BLTL, !BL
W4-W6Top, Bottom, Left, !TL, BL!TL, BL
W7-W9All, !TR, !BL, !BRTL

Blend/Grass Zone Specifics

Used by both Grass and Blend tiles.

TilesMatchesBlends
F3,H3,J3Bottom, RightTop, Left
F4,H4,J4Bottom, LeftTop, Right
F5-H5Top, RightBottom
F6-H6Top, LeftBottom
F7-H7Bottom
F8-H8TopBottom
F9-F11Left, Top, RightBottom
G3,I3,K3Top, RightBottom, Left
G4,I4,K4Top, LeftBottom, Right
G9-G11Left, Bottom, RightTop
H9-J9Top, Bottom, LeftRight
H10-J10Top, Bottom, RightLeft
H11-J11Top, BottomLeft, Right
I5-K5Bottom, RightTop
I6-K6Bottom, LeftTop
I7-K7Top
I8-K8BottomTop
K9-K11Left, RightTop, Bottom
L1-L3Bottom, RightLeft
L4-L6Bottom, LeftRight
L7-L9All
L10-L12Left, Right
M1-M3Top, RightLeft
M4-M6Top, LeftRight
M7-P7Top, Bottom
O1-O3Left
O4-O6Right
P1-P3RightLeft
P4-P6LeftRight

Order of evaluation

Some tile layouts can match more than one rule. When deciding between multiple matches, you should use the one that is most specific. For example, in the base zone B2-B4 matches "All", while B7-B9 matches "All, !TL, !TR". Due to not caring about the corners, any tiles that match B7-B9 would also match B2-B4. You should go with B7-B9 since has more specific rules.

This applies to matching tiles from multiple zones as well. Grass and Blend/Grass zones should be considered the same priority. Failing to find any matches, you should then drop to the Base zone and check for matches there. The Base zone is considered lower priority than the other zones.

You may have noticed that you could turn the matches and blends rules into a bitmask, and use a lookup table to speed up the comparisons. This is what Terrafirma does.

Cactus and Wooden Platforms

Cactus and wooden platforms do *not* use this method. Instead they have their own algorithms for determining which texture to use based on the tiles nearby.