Favicon and my profile picture

Collection Spec

Table of Contents

Licensed under the GPL-3.0. Maintained alongside Puzzled on GitHub

You can create your own puzzle collection by creating a JSON file with the following structure. Note that any behavior not explicitly described here is subject to change without prior notice or increased version number. If you want to add new features or define behavior not described here, please open an issue. Usually, when loading a malformed file, the application will show an error message and refuse to load the file. If it does not give an error message, when this specification suggests it should, please open an issue as well.

{
    "puzzled": "1.0.0",
    "name": "Example Puzzle",
    "author": "Puzzled",
    "description": "Fill the board with trominoes.",
    "custom_tiles": {
        "looong": [
            [1, 1, 1]
        ]
    },
    "custom_boards": {
        "3x3": {
            "layout": [
                [0, 0, 0],
                [0, 0, 0],
                [0, 0, 0]
            ]
        }
    },
    "puzzles": [
        {
            "name": "Simple",
            "tiles": [
                "looong",
                "L3",
                [
                    [1, 1],
                    [0, 1]
                ]
            ],
            "board": "3x3"
        }
    ]
}

This file can be loaded by Puzzled to add a new puzzle collection for the user to solve. The fields have the following meaning:

Field Type Required Description Default Version
puzzled String true The version of Puzzled this collection is made for. If you try to load a collection into Puzzled which is made for a newer versin of Puzzled, the load operation will fail. - 0.2.0
name String true The name of the puzzle collection. MUST not be blank. The name SHOULD be short (5 to 20 characters) and not contain the word Collection. - 0.2.0
author String true The author of the puzzle collection. MUST not be blank. - 0.2.0
id String true An id to identify the collection. It MUST be in the reverse domain name format like: tld.vendor.Author.Collection. So it might look like de.til7701.Puzzled.PuzzleADay. Only the characters matching [a-z][A-Z][0-9]- are allowed in between the dots. The id is case sensitive. - 0.2.0
allow_board_rotation Boolean false Flag to define whether the boards in this collection may be rotated in a way deemed most suitable by the application. You may want to disable the rotation for boards that represent a certain shape and do have a “correct” orientiation. true 0.2.0
version String false The version of the collection set by the author. This may be any string. This is not checked, it is just displayed to the user. - 0.2.0
description String false A short description of the puzzle collection. MUST not be blank if specified. None 0.2.0
progression Progression false The progression settings for this collection. See Progression for details. Any 0.3.0
preview Preview false Can be used to not show previews of locked puzzles. (See Progression) Any 0.3.0
custom_tiles Map<String, Tile> false A map of custom tile definitions to reuse in this file. See Custom Tiles for details. Empty Map 0.2.0
custom_boards Map<String, Board> false A map of custom board definitions to reuse in this file. See Custom Boards for details. Empty Map 0.2.0
puzzles List<Puzzle> true The list of puzzles in this collection. See Puzzles for details. The order of puzzles in this list SHOULD not change since it MAY be used by Puzzled to bind data to it. When adding a new puzzle to a collection, add it at the end of the list. - 0.2.0

Custom Tiles

Custom tiles can be used to define tiles that are not part of the standard tile set. They can then be referenced in the tiles field of a puzzle by their name. The value of each entry in the custom_tiles map is a tile definition, which is explained in the Tiles section below. You can also override standard tiles by defining a custom tile with the same name. Standard tiles are shown below.

Custom Boards

Custom boards can be used to define boards that you want to reuse in multiple puzzles. They can then be referenced in the board field of a puzzle by their name. The value of each entry in the custom_boards map is a board definition, which is explained in the Board section below.

Puzzles

A puzzle describes a single challenge for the user to solve. It has the following fields:

Field Type Required Description Default
name String true The name of the puzzle. MUST not be blank. -
id String false The id of the puzzle to identify it in case the order of puzzles in a collection changes or new ones are added in between. This defaults to the zero-based index of the puzzle in the collection. Index of the puzzle in the collection
description String false A short description of the puzzle. MUST not be blank if specified. None
difficulty Difficulty false The difficulty of the puzzle. If provided, it MUST be one of: Easy, Medium, Hard or Expert. None
unsolvable Boolean false If set to true, the puzzle is marked as unsolvable and does not count towards solving all puzzles in the collection. false
tiles List<Tile> true The list of tiles available to solve the puzzle. This list MUST not be empty. -
board Board true The board to solve the puzzle on. See below for details. -
additional_info Map<String, String> false Additional information about the puzzle. This may contain statistics about how many solutions there are, or anything else, which is in a key-value format and does not feel right to be in the description. Empty Map

Tiles

A tile defines a shape that can be placed on the board. Tiles can be defined in three ways: by name, with an array or as a more complex custom object.

Name

A tile can be referenced by its name as a String. Those tiles are either standard tiles (see below) or custom tiles defined in the custom_tiles map.

Example:

"L3"

The following standard tiles are available:

Name Shape Required Version
Domino
I2
Trominoes
I3
L3
Tetrominoes
I4
J4
L4
O4
S4
T4
Z4
Pentominoes
F5
I5
L5
N5
P5
T5
U5
V5
W5
X5
Y5
Z5
Hexominoes
A6 0.3.0
B6 0.3.0
C6 0.3.0
D6 0.3.0
F6 0.3.0
f6 0.3.0
G6 0.3.0
H6 0.3.0
I6 0.3.0
J6 0.3.0
K6 0.3.0
L6 0.3.0
M6 0.3.0
m6 0.3.0
N6 0.3.0
n6 0.3.0
O6 0.3.0
P6 0.3.0
p6 0.3.0
Q6 0.3.0
R6 0.3.0
S6 0.3.0
T6 0.3.0
t6 0.3.0
U6 0.3.0
u6 0.3.0
V6 0.3.0
W6 0.3.0
w6 0.3.0
X6 0.3.0
x6 0.3.0
Y6 0.3.0
y6 0.3.0
Z6 0.3.0
z6 0.3.0

Array

A tile can also be defined by a 2D array of integers. The array represents the shape of the tile, where 1 indicates a filled cell and 0 indicates an empty cell.

For example, the following array defines a Z5 tile:

[
    [1, 1, 0],
    [0, 1, 0],
    [0, 1, 1]
]

Which, as a reminder, looks like this:

Z5 Tile

Custom Object

Some more extensive tiles need more information than just the shape, so they can be defined as an object with additional fields. This looks like this:

{
    "layout": [
        [1, 1, 0],
        [0, 1, 0],
        [0, 1, 1]
    ],
    "color": "#AABBCC",
    "count": 2
}

The layout must be defined as described in the name or array section above, but additional fields can be added to define additional properties of the tile, like its color.

Field Type Required Description Default Version
layout Array2<u8> true The layout of the tile where 1 indicates a filled cell and 0 indicates an empty cell. -
color String false The color of the tile. It must start with a # and continues with a hex representation of the color in the order red, green and blue. You may also add the alpha channel. However, this is not recommended, since transparency is reserved for other purposes. You should also keep in mind that people are playing in light or dark mode. So choose colors that can be seen well in both modes. -
count NonZeroU32 false How many of the tiles should be added. MUST not be zero or lower. - 0.4.0

Board

A board defines the layout on which the puzzle is to be solved. There are two variants of boards, which can be defined in three ways, so pay attention. Boards can be referenced by name, defined as a Simple Board or as an Area Board.

Name

Similar to tiles, a board can be referenced by its name as a String. Standard boards or custom boards defined in the custom_boards map can be referenced this way.

Example:

"my_custom_board"

The following format of standard boards are available:

You can define a simple rectangular board of any size using the following naming scheme: <width>x<height>, where <width> and <height> are positive integers. The following board definitions will result in the same board:

"4x3"
{
    "layout": [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 0, 0, 0]
    ]
}

Simple Board

A simple board is defined by a 2D array of integers, where 0 indicates an empty cell where a tile can be placed and 1 indicates a blocked cell where no tile can be placed.

Field Type Required Description Default
layout Array2<u8> true The layout of the board where 0 indicates empty cells and 1 indicates blocked cells. -

Example:

{
    "layout": [
        [0, 0, 0],
        [0, 1, 0],
        [0, 0, 0]
    ]
}

Here, tiles can be placed in all cells except the one in the center.

Area Board

An area board is a board, where one cell has to be left empty in each area when solving the puzzle. This is the board type used in the original Puzzle A Day.

Field Type Required Description Default
area_layout Array2<i32> true The layout of the areas on the board. -1 indicates, that no tile can be placed in this cell. The rest is the index of the area the cell belongs to. The index starts at 0 and goes up to the length of the areas list minus one. -
values Array2<String> true The values to show in each cell. Entries MUST not be empty, when the area_layout is not -1 in the corresponding cell. -
value_order Array2<i32> true The order of values. This order is used to sort the options when selecting a target. -1 marks cells that no tile can be placed in. The rest of the values MUST be any non-negative number and MAY not start at zero and MAY not be consecutive. The natural order of the number is the only thing that matters. If the same number appears more than once in an area, the behavior is undefined. -
areas List<Area> true The list of Areas in this board. The index of the area in this board is the same as the index for the area in the area_layout array. -
target_template String true Template to format a target selected by the user. This is shown to inform the user about the currently selected target. The formatters defined in the area are used to format the value from the board values array. In the template, {<area_index>} is replaced with the formatted value. So {0} and {1} is a template for a baord with two areas. The resulting string may look like this: first and second, where first is the formatted value from the first area and second is the formatted vlaue from the second area. -

Example:

{
    "area_layout": [
        [0, 0, 0, -1],
        [-1, 1, 1, 1]
    ],
    "values": [
        ["A", "B", "C", ""],
        ["", "D", "E", "F"]
    ],
    "value_order": [
        [0, 1, 2, -1],
        [-1, 0, 1, 2]
    ],
    "areas": [...],
    "target_template": "{0} and {1}"
}

Area

The area gives additional information about an area on an area board.

Field Type Required Description Default
name String true The name of the area to show in the target selection dialog. -
formatter AreaFormatter true The formatter that defines, how to format a value for this area. -
default_factory DefaultFactory true The default factory that defines how to generate the default target for this area. The factory MUST produce a value that is equal to a value on the board. The cell where the values match, is supposed to be left empty when solving the puzzle. -

Example:

{
    "name": "Day",
    "formatter": {
        "type": "Nth"
    },
    "default_factory": {
        "type": "CurrentDay"
    }
}

Area Formatter

The area formatter takes the raw value from the board and formats it for display to the user.

Plain

Returns the value as is.

{
    "type": "PLain"
}
Nth

Appends “st”, “nd”, “rd” or “th” to the value based on its last character. It is expected that the value ends with a digit.

{
    "type": "Nth"
}
PrefixSuffix

Appends a prefix and/or suffix to the value.

{
    "type": "PrefixSuffix",
    "prefix": "x",
    "suffix": "z"
}

Default Factory

The default factory generates the default target for an area. The product of the default factory MUST be equal to a value on the board in the area the factory is used for.

Fixed

Returns a fixed value.

{
    "type": "Fixed",
    "value": "example"
}
CurrentDay

Returns the current day of the month as a string.

{
    "type": "CurrentDay"
}
CurrentMonthShort

Returns the current month as a three-letter abbreviation. E.g., “Jan” for January, “Feb” for February, etc.

{
    "type": "CurrentMonthShort"
}
CurrentYear2FirstDigit

Returns the first digit of the current 2-digit-year as a string. E.g., “2” for the year 26.

{
    "type": "CurrentYear2FirstDigit"
}
CurrentYear2SecondDigit

Returns the second digit of the current 2-digit-year as a string. E.g., “6” for the year 26.

{
    "type": "CurrentYear2SecondDigit"
}

Progression

The progression field defines how puzzles in this collection are unlocked for the user. This field is available since version 0.3.0 of Puzzled.

Example:

{
    "type": "Any"
}

The following progression types are available:

Type Description
Any All puzzles are available from the start.
Sequential Puzzles are unlocked one by one in the order they are defined in the puzzles list. The first puzzle is available from the start.

Preview

The preview field defines whether to show previews of locked puzzles. This field is available since version 0.3.0 of Puzzled.

Example:

{
    "show_board": true,
    "show_tiles": false,
    "show_tile_count": false,
    "show_board_size": false
}
Type Description Default
show_board Show Board true
show_tiles Show Tiles true
show_tile_count Show Tile count true
show_board_size Show Board size true