Games with grids usually use the tiles but there are also cool things to do with edges and vertices. For construction games the edges can be useful for blocking connections between tiles (walls, chasms, windows) and allowing connections between tiles (doors, pipes, wires).
Let's start with an example: building walls. A common approach to implementing walls is to place thick walls on the tiles. An alternative is to place thin walls on the edges. Click or tap on the tiles or edges to toggle the walls:
Examples#
Sometimes we want both tiles and edges. I try to make one of the two primary and then calculate the other one. In this example showing grid lighting, the tiles are primary. We can light edges when either tile is lit. Click or tap on tiles:
Consider the example of pipes/wires between adjacent tiles. We want to know which tiles are connected to the pipe network, but we also want to know which edges connect tiles to each other. If we make the tiles primary, we can place edges when both tiles are marked. Click or tap on tiles:
Alternatively, we can make the edges primary, and place pipes on tiles when any edge is marked. Click or tap on edges:
Here's an example of adding thin walls when exactly one neighboring tile has a thick wall. Click or tap on tiles:
Whenever possible, I make either tiles or edges primary, and calculate the other using a function. I find this less error prone than putting constraints on what combinations of tiles and edges are allowed. The "pipe" style connectors and the "wall" style dividers use the same logic underneath. A pipe is drawn between the tile centers; a wall is drawn between the corners.
Coordinate systems#
Coordinates for square tiles have two different conventions. In math and in 3D graphics, Y increases upwards; in many 2D graphics systems, Y increases downwards. On this page I'm going to show Y increasing downwards.
How about edges? We could label the four sides of each square:
In many situations we want to treat 0,0,S
and 0,1,N
as the same edge, and similarly 0,0,E
and 1,0,W
. In these situations we can keep the N and W sides and discard S and E. We could've kept S instead of N, or E instead of W, but I'll work out the details for N and W.
Given a tile q,r
its four bordering edges are q,r,N
; q,r,W
; q,r+1,N
; q+1,r,W
.
The rules for edges depend on whether it's an N
or W
edge. Given an edge q,r,N
its two joining tiles are q,r-1
; q,r
. Given an edge q,r,W
its two joining tiles are q-1,r
; q,r
.
For more details, including coordinates for corners and more tile+edge+corner relationships, see my guide to grids.
Pixel lookup#
In some games we want to be able to determine which tile/edge is closest to the mouse position. When working with tiles, we find the closest tile by looking at squares. These squares are exactly the same as the tiles. It's so simple we don't even think about it! Mouse over the map to see the area of pixels that would activate a tile (touch not supported).
When working with tile edges, we find the closest tile by looking squares at a 45° angle. Each square is made from two tile centers and two tile corners. Mouse over the map to see the area of pixels that would activate an edge (touch not supported).
If we want the mouse to work with both tiles and edges, we can build polygons that work with both. The tiles are detected with small squares, and edges are detected with hexagons. Move the slider to control the sizes, and mouse over the map to see what is activated (touch not supported).
Alternatively, calculate both the mouseover tile and mouseover edge, and pick the one that's closer to the mouse pointer.
Corner pieces#
If you're working with square tiles, edges, and corners all in the same system, there's a clever trick of using the low bit of x and the low bit of y: 00 = corner, 01 = west edge, 10 = north edge, 11 = tile. Let's see how this works. Move the slider to see how this data is stored in an array.
This approach lets you store corners, edges, and tiles all in the same array. I haven't had a use for this in my own projects but I'm including it because it's a neat idea that someone might find useful. Anna Harren has a way to do this with hexagons too![1]
More#
- My guide to grids covers coordinate systems for tiles, edges, and corners, not only for square grids, but also for hexagonal and triangular grids.
- A multiplicative voronoi diagram[2] can calculate the pixel areas closest to the edges and tiles. We don't need it for the simple case here, but it is useful if you are working with an irregular grid or if you have variably sized objects on your map.
- Even though many A* implementations are written to work on the tiles, A* itself cares about both tiles and edges, so it can handle maps where each edge is marked as walkable or not.
- David Stark has a blog post about grids in games[3], and points out that Dwarf Fortress uses tile-based walls but edge-based floors.
- I've written a quick explanation of how to detect the diamond shapes around edges using geometry[4] but haven't made a full interactive version on this page.
Some games, such as Oxygen Not Included and Factory Idle, seem to have a hybrid that keeps track of both tile and edge connections. Some games, such as Factorio and Production Line, have directions along the edges; see my page about conveyor belts.