Game State

Status: implemented | obsolete

Control flow in the game is centralized in two different places. All navigation throughout the game between puzzles, is controlled by PlayWindow. In addition, all navigation within a crossword once it’s loaded is handled by PlayXword. This doc covers the former. For the latter, see

When the main PlayWindow is first loaded, it loads list of all the possible PlayPuzzleSets that the game knows about and puts them in a GListModel (:play_set_list). It also creates a GtkStack with the contents of the main window as the first page in the stack. These contents are the first element in the stack and have the name main. They shouldn’t change for the lifetime of the window

Once the user selects a puzzle, PlayWindow will call ::start_puzzles on the appropriate puzzle set. It will then call get phase to get widgets to display for the appropriate phases. Puzzles should be prepared to give a widget at the start and populate them as necessary (or display loading information, such as in the case of network-based puzzles).

Control will flow to the PuzzleSet, which can call ::change_phase whenever appropriate to update the stack. Dialogs are fine to popup as well as part of a phase change.

Once a puzzle is finished (either by beating the whole set, or from a UI element), ::puzzles_done is called on the puzzle set which will free up memory / clear any widgets.

It’s up to a puzzle set if it wants to keep the widget around when it is removed from the stack. It should either call ref_sink() and reparent it in future calls, or drop all references after puzzles_done is called.


  • Calling ::change_phase to "main" will not trigger a ::puzzles_done call. However, if the user selects a different puzzle set, it will be called.

  • Every ::start_puzzles call needs to be mirrored by a puzzles_done call before another puzzle set can start. Only one PuzzleSet is run at a time.

  • If a puzzle set intends to keep a widget around between invocations, it should ref_sink it first.