# Puzzle Sets
**Status**: Implemented | 2022

## Background

**Puzzle sets** are the way we group puzzles together. At its heart,
Crosswords is a simple UI: It shows available puzzle sets, lets you
select them, and then play all the puzzles within the set.

The `PuzzleSet` class is a `GObject` that represents a set of puzzles,
and can be used by the game to both control the UI and load/save
files. It isn't a widget directly, but provides widgets for the game
to display depending on the state of the game.

By default, there is a `GResource` containing a `GKeyFile` for every
PuzzleSets that stores all information about the set. Originally more
PuzzleSet config formats were planned, but over time it became clear
that a the resource puzzle set could be extended to provide everything
we need.

## Interacting with PlayWindow

The PuzzleSet is the primary way for the PlayWindow to communicate
with widgets or puzzles.

The main game window provides some UI functionality in the
header. That includes the navigation controls, as well

There's a default implementation of the play_window UI control
interfaces within the PuzzleSet. For it to work, three things need to
happen. First, `::get_widget()` has to be stable and the widget
returned have to be constant for the life of the puzzle set. Second,
the `PUZZLE_PHASE_GAME` widget must be PlayXword. Third, subclasses
need to chain up to the parent widget.

It is recommended that a subclass either handles none of the
PlayWindow interface and chains up, or all of it without chaining.

## PuzzleSet properties

PuzzleSets have two game phases that they need to handle: the
**PICKER** phase and the **GAME** phase.

* **PICKER**: Let the user pick a puzzle to play and potentially show
  a meta-puzzle. This phase is optional but used by every instance in
  the current game.
* **GAME**: Solve an actual crossword.

By default, we provide two different widgets that can be used as a
picker (`PickerList` and `PickerGrid`). These can be customized and
extended through the keyfile.

There is a `PuzzlePicker` base class to share common functionality
between the two pickers, and it's plausible to write completely
type of picker using it.

## Directories and File Names

Puzzle sets are all installed in:
```
$XDG_DATA_DIRS:crosswords/puzzle-sets/
```

It will search all directories within that path, and can be overridden
with the `$PUZZLE_SET_PATH` environment variable.

The filename should be named either `$ID.gresource` or `$ID.config`
depending on the type of the puzzle set.

---

Saved files are all saved in:
```
$XDG_DATA_DIRS:gnome-crosswords/saved-games/$ID/
```

Where $ID is the ID of the puzzle-set.

---

Finally the resource puzzle-set can save files that it has
downloaded. Those are stored in

```
$XDG_DATA_DIRS:gnome-crosswords/downloads/$ID/
```

Where $ID is the ID of the puzzle-set.

