I wanted to explore how to represent conveyor belts on a grid.
In Factorio, each grid tile with a conveyor belt has a direction. Adjacent tiles combine together to determine what type of conveyor belt is on the tile. The main operations are: build belt, destroy belt, rotate belt. The model is simple and can express straight belts, curved belts, and joins. It does not support splits, and Factorio uses a separate splitter object for that. Each tile has 5 states: empty, east, north, west, south. Click a tile to cycle through the states:
In Production Line, each grid tile with a conveyor belt may have multiple flows, allowing for both joins and splits. I implemented a data model that supports that functionality, but what I show here is not exactly the same as what the game uses. Each tile has 2 states: full, empty. Each edge between adjacent full tiles has 3 states: east/south, west/north, neither. Click a tile or an edge to cycle through its states:
Another model is for each tile to have flow information on all four edges, but that allows the possibility that adjacent tiles have inconsistent flow directions.
Both games have a much nicer drag-move UI than what I have here. The UI here was just for me to edit the state and see the results.
Thoughts: I was hoping to find that one of these models was much better than the other, but I didn’t find that. The tile model is better by being simpler. The edge model is better by supporting 2-way and 3-way splits. The tile model has some nonsense configurations, such as two tiles pointing at each other. The edge model also has some nonsense configurations, such as a tile that doesn’t point anywhere.
(Making-of: when I started this page I thought I would find a different model, involving connecting adjacent edges together. I built some diagrams and they made me realize my model wouldn’t work. I slept on it, slept on it again, and came up with a simpler model.)
Implementation note: I used edge coordinates x,y,W and x,y,N as described in my article on grid coordinates. Each tile has data for itself (full or empty) and its north side and its west side. To get information about the east side, the tile at x,y asks the tile at x+1,y for its west edge. To get information about the south side, the tile at x,y asks the tile at x,y+1 about the north side. The edge flow is stored only once and used by both adjacent tiles.