Constraints
The basic configuration of a generator involves setting up tiles, and painting those tiles to show how they can be placed next to each other.
This page documents further configuration you can do to tightly control the generation process.
There are many constraints available in Tessera:
- Initial Constraints
- Pins fix a particular tile in place
- Volume constraints filter a particular area to a subset of tiles
- Skyboxes controls how tiles on the boundary of the generation work
- Submesh filters applies per material settings when working with surface meshes.
- Generator Constraints
- CountConstraint - ensures the number of tiles in a given set is less than / more than a given number.
- MirrorConstraint - ensures the output remains symmetric.
- PathConstraint - detects contiguous paths between tiles, and ensures various properties about those paths, such as connectedness.
- SeparationConstraint - ensures that the given tiles are spaced at least a certain distance apart
Initial Constraints
Initial constraints configue the intial conditions of the generator. They generally set up by adding behaviours into the world.
- Pins fix a particular tile in place
- Volume constraints filter a particular area to a subset of tiles
- Skyboxes controls how tiles on the boundary of the generation work
- Submesh filters applies permaterial settings when working with surface meshes.
Pins
Sometimes you just want to place a tile at a particular location without Tessera choosing for you. For example, you might want to place a entrace manually at one side, or write custom code to draw path ways for you. Pinned tiles lets you do this, and then have Tessera generate the rest of the tiles for you.
There's multiple ways to specify pins - all of them involve putting a game object inside or adjacent to the generator area, in the position of the cell you want to affect. They will be automatically detected and incorporated into the generation.
The most flexible way is to great a game object with the TesseraPinned component. You can then specify the PinType and the tile to pin as properties of that component.
As a convenient short cut, you can also just place a Tessera tile directly. These will be interpreted the same as a TesseraPinned component that references that tile, and has pin type FacesAndInterior.
You can also place an object with both a Tessera tile component and a TesseraPinned component. The TesseraPinned will be assumed to reference the tile component on the same game object.
Here is an example. A generator is set up and a few tiles manually placed.
When the generator is run, the new tiles join up with the placed tiles.
Configuring pins
TesseraPinned has two key properties:
- Tile determines what tile to use for pinning.
- PinType controls how exactly the pinned tile effeects generation.
These two values are inferred in some cases, as described above.
There are three types of pin:
With this pin type, the generator is forced to generate the referenced tile at the location of the pin.
The referenced tile must already be in the generator's tile list (though it can have weight 0).
With this pin type, the faces of the referenced tile are used to constrain the cells adjacent to the location of the pin, and the generator is free to pick any tile for that cell.
With this pin type, the faces of the referenced tile are used to constrain the cells adjacent to the location of the pin. Also the cells covered by the pin are masked out so no tiles will be generated in that location. You may therefore need to manually place a tile or other game object to fill the gap. Unlike PinType.Pin, the refenced tile does not need to be in the generator's tile list.
The different pin types can be used to generate a variety of effects. FacesOnly, for example, is good at restricting the generation along a given plane, without forcing any particular tile. FacesAndInterior allows you to put in custom tiles (often called "hero" pieces) that never otherwise appear in generation. And Pin is good for forcing a particular tile to be placed, while still allowing that cell to be part of generation. That can be important if you need the cell to interact with generator constraints or other Tessera features.
Volumes
Add a GameObject with the Tessera Volume component to filter an area of cells to only use a subset of tiles.
To use it, add a game object with the volume component, and set the cells you want to filter to. You can optionally specify a generator for convenience, but it's not necessary.
Next add colliders to the game object to define the area selected. A cell is in the volume if its center is inside at least one collder.
Here's a dungeon generated with a box collider volume in the center, configured to filter to just an empty tile.
Unlike pins, volumes have no way to configure the rotation and reflection of the generated tile.
Volumes can also be used to remove tiles from the generator entirely, by setting the volume type to MaskOut. This behaves similarly to pinning tiles with FacesAndInterior - the missing cells interact differently with constraint.
API
The default behaviour of generators is to search the scene for appropriate pins and volumes. This can be slow for large scenes, and it's not suitable for advanced customization. You can use the C# API to set pins and volumes directly.
First, disable the automatic detection by setting searchInitialConstraints to false. Then you can supply your own initial constraints by setting initialConstraints. You need to call GetInitialConstraintBuilder to get a utility to convert various objects to initial constraints.
Skybox
Setting the skybox property of the generator will automatically constrain all tiles on the boundary of the tile area. The skybox should be a TesseraTile component. Whatever is painted on the top of the skybox, will constrain the top of every tile on the topmost layer of the generator. Similarly for the other sides of the cube.
In this example, the skybox has been used to force the bottom edge to be all paths, and the other edges to have no paths.
Notes
The tile used for a skybox should not be a big tile, this will cause wierd behaviour.
If a pinned tile constraint and the skybox both apply at a particular location, the tile constraint takes precedence.
Note that a given skybox face is repeated as a constraint for all tiles which have a corresponding face on the boundary. This can sometimes cause counter-intuitive results. For example, if you have a 3d example like in this tutoral, then you cannot have a skybox that is "grass" on the sides. Doing so allows surface tiles, but would stop air and solid tiles from touching the boundary, which will cause the boundary to fail.
The solution to this is to make a new palette color just for the skybox. You can then set that color connect with multiple other colors, so that it's possible to place all the tiles that can abut the boundary.
Submesh filters
Note
Submesh filters are only available in Tessera Pro
If you are generating on a mesh surface, and that mesh has multiple submeshes, (i.e. multiple material slots), then you can filter which tiles are appropriate for which part of the submesh, similar to volumes, above.
The Generator inspector will automatically detect this case. Simply turn on "Filter By Submesh" and then select which tiles appear where.
Generator Constraints
Note
Generator constraints are only available in Tessera Pro
These constraints control the global behaviour of generation. They are very powerful, but can use generation to fail more frequently.
To use them, find the game object that has the generator, and add additional components to it from the Component > Tessera
menu.
At present the constraints are:
- CountConstraint - ensures the number of tiles in a given set is less than / more than a given number.
- MirrorConstraint - ensures the output remains symmetric.
- PathConstraint - detects contiguous paths between tiles, and ensures various properties about those paths, such as connectedness.
- SeparationConstraint - ensures that the given tiles are spaced at least a certain distance apart
There is a tutorial on how to use path constraints.