Crosswords 0.3.7: Adaptive Layout, Animations, and Arrows

Howdy folks,

It’s GNOME Crosswords release time again! This is a big release with a lot of changes. Most importantly, I was able to find some time over the holidays to do some long-overdue refactoring of the core game code.

crosswords: 143 files changed, 12619 insertions(+), 5834 deletions(-)
libipuz:     41 files changed,  2345 insertions(+),  736 deletions(-)

A number of early design decisions haven’t panned out, and these decisions  held us back from doing some very basic things with the code. While not directly impactful on the user, this refactoring unlocked some long-overdue features. In addition, loading puzzles and puzzle sets are noticeably faster now.

In this post, I’m going to cover the mobile work, Arrowwords, the hackfest, and the new preferences dialog. Let’s take a look at what’s new:

Adaptive Layout and Animations

In the previous release, I tried to make Crosswords adapt to different screen sizes. It wasn’t all that usable, so I worked more on it this cycle.

First, the good news: I cleaned up a lot of the layout bugs, and (thanks to Carlos) got some form of touch screen keyboard input working. The end result is that I changed the appinfo file to indicate we supported all screen sizes and inputs, which means it should be available on all platforms.

I also had to put all the parts of the game into a custom container widget to get the spacing right. Once that was done, it was trivial to add some animations to it. It turns out AdwAnimation is really cool — and much easier to use then I had expected. I added animations to keep the puzzle centered and to align it vertically as appropriate. Here’s how resizing  now looks:

I’m pretty impressed with how easy it was to do things like this with GTK4.

Unfortunately, despite these changes, it’s not all good news. I don’t think the final results are compelling enough for mobile devices. The touchscreen input is flaky, and the onscreen keyboard isn’t great for crossword puzzles (and is so big!) I never really figured out how input was supposed to work together, and ended up just guessing until it mostly worked. I could really use better documentation on the onscreen keyboard! Or if someone explains it to me, I’m happy to write documentation for future users.

As I don’t actually have a mobile device that runs GNOME and I don’t have a touch screen, I’ve reached the limits of what I can do without additional help. I’d love feedback or advice from anyone who knows more about this space.

Arrowwords

As part of the refactoring focus, I added a bunch of new puzzle types to libipuz (more on this in a future post!) One of these puzzle types was Arrowword puzzles — a crossword style more popular in northern Europe. This had been a semi-regular request and turned out to be easier to implement than expected. We were able to get something going relatively quickly.

I wrote the cell code, Federico helped with the svg overlay arrow rendering, and Philip helped with the testing and downloader. The end result is attractive:

Arrowword Crossword

Puzzle Sets

Due to the big holiday refactor, I was able to add a few small features I’ve wanted to add for a while. First, I changed Puzzle Sets to be opt-in. We’ve ended up accruing so many of them that it makes sense for people to choose the ones they want to play.

Along the way, I added extensions  to the puzzle sets to tag them so users can see more information before trying them. Here’s the dialog to select them.

Puzzle Set selection dialog

Additionally, I added an option to let you hide puzzles that have already been solved. This was another requested feature as the list of puzzles can get quite long.

Finally we show how many puzzles remain unsolved in the main screen. This should have been a simple feature to add, but the old code base made it surprisingly hard to implement. With the rewrite, this was only a few lines of code:

New Main screeen
The new main screen

You can also see an “Add More Puzzles” button in that screenshot.

Hackfest

We held a virtual hackfest a few weekends ago! Four people showed up, and we focused on getting this release out the door. We got most of the last release blockers done during it. Davide added Italian puzzle sets and translations, and fixed the packit CI. Rosanna finished the GNOME Mini Crosswords set and started a new, alphabetically-themed one. Federico documented how to run crosswords out of podman and got the Arrowword SVG overlay themed and working. I landed the final fixes for the tagging, and landed a bunch of build fixes to the puzzle sets.

It was a lot of fun. I will try to hold another one at the end of the next release cycle.

GNOME Mini Crosswords

What’s next?

  • We’ve wanted to add autodownload-on-start for a while, and it should be possible to do that now.
  • I don’t love the current preferences dialog. It could use some design attention and tweaks.
  • And finally, I plan to switch back to work more on the Crossword Editor. It’s overdue for some love.

Until next time!

Crosswords: Puzzle update

Happy New Year, Crossword-lovers!

This is a minor update in preparation for a bigger release in the next few weeks. We’ve done a lot of exciting work on Crosswords over the past few months that’s almost ready for release. However, there are a few things available already that I wanted to highlight early.

Puzzles

There are two updates to the puzzle sets. First, George Ho kindly agreed to add his puzzles to the contrib puzzle-set. He’s written ten fun puzzles with the promise of more in the future! I really enjoyed solving them. There are also a few additional not-for-distribution ones available at his site.

loplop puzzle set

George has put together a truly impressive dataset of cryptic crossword clues. He’s gathered and categorized half-a-million clues over twelve years of puzzle data. I’m really impressed with this work and I’m looking to integrate some of that data into the Crossword Editor this coming year.

Second, I updated the xword-dl plugin to work with latest version of that app. Those folks have been really busy the past few months, and over ten more puzzle sets were added to it, including our first German source (Hint: a German translation would be appreciated). Our launch screen has gotten a lot fuller with both downloaders and shipped puzzles: we now have over 50 possible puzzle sets for playing across three languages.

Despite the ritual pain and suffering  with pip to get it building in a flatpak (NB: still relevant), I managed to get it updated. I’m really impressed at how that project grew in 2022. Great work!

These are available at flathub.

Developer Documentation

Federico gave me an early Christmas gift this year! He set up a developer guide for Crosswords to be built automatically from CI. It’s gorgeous, and hopefully will entice folks to join the rest of us working on the app.

A major goal I’ve had while writing this is to keep it well documented. A few weeks ago, Federico wrote beautifully about the power of documentation. As the game has grown past 30KLOC I’ve found it super valuable to reread what I wrote when revisiting older code sections. Writing the design docs has had a clarifying effect too: I had to write the WordList docs before I could finish that code, and I refresh my memory from it every time I have to touch it.

However, one thing I didn’t have was a good way to tie it all together. Now that we have this site, it’s possible to explain how things fit together. I spent some time this vacation putting together some introductory docs to make it easier to get started with the code base. If you have any interest in contributing, check them out.

What’s next?

We are gearing up for a big release in a few weeks with a lot of changes. They’re mostly internal cleanups, but these changes are already making some new features much easier to write. Here’s a preview of one them that’s in progress:

Can you guess what this will be?

The other thing I’d like to do is to hold a virtual hackfest this weekend. The exact time and date is still TBD pending some availability, but I’ve been meaning to get together with a few folks to work on some of the code together. I don’t know how well this will work virtually, but its worth a shot to open it up to a wider audience.

If you’re interested at all in word games and free software, feel free to drop by #crosswords. While there, let us know if you’re interested in the hackfest. All people are welcome. Come add a feature, add a translation, or try your hand at writing a puzzle. Or just hang out and tell us your favorite clues.

Until next time!

Download on FLATHUB

Crosswords 0.3.5: Border Styles

It’s time for another GNOME Crosswords update. We’ve been busy since GUADEC and have managed to add quite a few user-visible features. We also fixed a bad bug where undo would break autosaving and added French translations. Buckle up, as this release goes to eleven!

As always, this is available on flathub.

Border Style

The first big feature in this release is recoloring the borders between cells. We previously had a single color (black) between the cells no matter what cell type it was. The recoloring is a subtle change, but I think it makes the puzzle look a lot smoother. We go with light borders between open cells, darker borders between blocks, and a really dark border around the outside. We also interpolate colors between cells with a background color explicitly set and to emphasize the cursor. Getting the details right took a good number of iterations but I’m happy with the ultimate effect.

This also validates the decision to create a widget for each border segment, as it made this a lot easier to implement. We use CSS styles to manage all the color combinations.

Border style comparison: new (upper-left) vs old (lower-right)
Highlight of border colors
Border styles with colored backgrounds
Acrostic puzzles also look cleaner

SVG Overlay

The next big feature we added was an SVG overlay over the puzzle. This lets us add graphics that extend beyond the borders of the existing widgets. Doing this lets us finally support enumerations in puzzles.

What’s an enumeration? Some crosswords let you know how many words follow a clue. It does this by putting hints in parentheses. It can also indicate punctuation where appropriate. As an example, (2-6,7) matches “GO-FASTER STRIPES” in 7dn in the puzzle below. In paper crosswords, solvers will often mark these hints in the grid with a pencil. We now do that on their behalf.

Enumerations rendered in the grid

We can also use the svg overlay to support barred crosswords. These puzzles look really cool – though are notoriously difficult to create and solve. I don’t know if we’ll get a good source for these until we seriously improve the editor, but I ported an existing one to .ipuz for testing purposes.

Barred crossword

Multi-character Support

I wasn’t fully happy with the state of editing when the IJ digraph support landed a few releases ago. The input method ended up being pretty obscure. As a result, I added generic multi-character functionality to the game. This feature will let you enter an arbitrary number of characters in a single cell. This is necessary for rebus-style crosswords which you occasionally find in the wild. It can also be used for the Dutch IJ as a more standard entry. You can enable this mode this by typing Ctrl-<period> or Escape.

Rebus-style crossword

This adds exciting functionality for fellow, faux, heavy-metal enthusiasts! We can now enter multi-character glyph. Behold:

Not the real answer, but close!

I’ve always wanted to do a puzzle with “SPıN̈ALTAP” as an answer. The N-diaresis doesn’t have its own unicode glyph and requires a combining character to work (u308). This feature lets you type it into the puzzle.

Keyboard Preferences

I’ve been involved with GNOME long enough to have a healthy suspicion of preference dialogs, and I resisted adding one for a long time. Unfortunately, there’s one preference that I’ve found I can’t avoid. Some people really like their online crossword widget to skip over letters when entering and some like them to overwrite letters — and there’s not a lot of compromise between the two sides. This has been the biggest behavior request I’ve received since releasing this game.

One of the goals this cycle was to refactor the internal state mechanism to make it cleaner (design doc). Along the way, it made this behavior change a lot easier to write.

This concept is so hard to explain! Anyone have suggestions for better text?

GNOME Contributor’s Puzzle Set

One last thing worth mentioning is a new puzzle-set (repo here). Since starting this project, I’ve had a few people send me puzzles to include, and we haven’t had a good place to put them. I created this as a place to ship puzzles from the wider GNOME-community. To start with, we’re including a handful of mini-puzzles and have started adding some standard ones. As soon as we get a bit more critical mass I’ll ship it via flathub.

If you’re interested in trying your hand at writing a crossword, this is a good way to make it available. Let me know if you’re interested.

thanks

Thanks to Federico for massive help and advise with the PlayState refactor, and for providing an SVG widget for the overlay. Hopefully GtkImage will get scalable SVG support in the future.

Thanks to Bob for finding and fixing a number of memleaks, and to the translators for language support.

Thanks to Zana and Carl for contributing puzzles.

And thanks to you for reading this far!

Download on FLATHUB

Introducing GNOME Crosswords

GNOME Crosswords

Howdy folks! I want to announce a game for GNOME that I’ve been working on for a few months.

I’ve always enjoyed solving Crossword puzzles. It’s something I grew up doing as a kid, and we continue to do them as a family at the dinner table at night. I’ve wanted to try my hand at writing crosswords for a while, but there isn’t really a good tool available for doing so, and certainly no free software ones that work well with a recent GNOME release. I recently bought myself a lovely new Fedora-loaded Lenovo, and after it arrived, I thought I’d take a shot at writing such a tool.

Over the past four months or so I managed to get something worth releasing. The code is available here. It should build on relatively recent Linux distributions, though it does need libadwaita from git (toasts!). I also put together a flatpak file for testing here (no repo yet, as getting that set up defeated me). Once I’m more confident that the puzzles are solvable and fun I plan to publish it to flathub.

A dog's day
Non-traditional grid
Guardian cryptic No 28,605
The Guardian Daily Cryptic with reveal answers enabled

Features:

It’s still early, but it already has some fun features:

  • Puzzle Sets. The heart of the game is the Puzzle Set. It’s a collection of crossword puzzles that are tied together by a theme. Solving a puzzle unlocks more puzzles. I currently have one puzzle set (“Cats and Dogs”) with nine puzzles in it, but I have a few more puzzle sets planned. It contains mostly traditional puzzles, but I threw in a cryptic to keep people on their toes.
  • Nontraditional shapes and styles: I wanted to make something a bit little more whimsical and fun, as well as the more traditional puzzle grids. So I added support for colors and shapes as well. My son had fun doing pixel art to create some of the grids.
  • Reveal mistakes: For when you get stuck! It also supports checksums for puzzles that don’t include the solution.
  • Scalable grid: Currently the UI only exposes four sizes, but we have all the pieces to scale crosswords to different sizes.
  • Support for the .ipuz spec: This spec supports a ton of things, and I don’t support it fully yet, but most of the crossword part of the spec is included. There aren’t a ton of .ipuz files floating around, but you can use puzzlepull to download the Guardian Daily puzzle if you want to try some other examples.
Puzzle Set
The first Puzzle Set

Crossword Editor

GNOME Crosswords Editor

As part of building this app, I realized that creating grids was as big a part of the app as writing the actual game itself. To facilitate that, I started writing a crossword editor as well. It’s in the early stages, but it already has one of the most important features: a tool to create the initial grid. Making puzzles that fit well together is surprisingly hard. To make it easier, I wrote a crossword solver that quickly suggests words to fill in the grid. I’m proud of the design – it’s able to efficiently suggest options out of a list of 500K words really quickly (<1 μs on my machine). I was able to use it to build an autofill dialog that can recursively fill in a section of the puzzle when making a grid.

I still have more work to do on the editor and it’s clear that the autofill dialog isn’t a panacea, but it helped me figure out out some tricky corners. Here’s a video of the autofill dialog in action:

Thanks

I especially want to thank Rosanna and my kids for play-testing this and suggesting clues, as well as their patience while I was writing it. Thanks also to Federico for giving great advice, great code, and for being a star. Matthias for helping me relearn GTK and explaining GtkIMContext. Also, the example code in GNOME Builder was immensely helpful for getting this started.

What’s next?

There are a ton of features I’d like to add to this game. It really needs printing support, which should be relatively easy. I’d also love to see it get internationalized (and not just translated) – are crosswords in non-Latin languages a thing? And I’ve seen enough of Benjamin‘s GUADEC presentations over the years to know GTK can do something cooler than popup a dialog when you finish a crossword.

But the most important thing is that the game needs to be fun! For that, we need more puzzles and the existing puzzles need to be better. If you’re interested in joining me in creating a good set of puzzles for Linux, try the game out and let me know.

Mon 23 Aug 2004

  • life: It was a nice day today, so I did what I always seem to do on such nice days; I huddled in the basement fiddling with firewall rules.

  • car: I took my Saturn in to the dealership to get its 100,000 mile service. It was the first time in a while that I’ve stayed in the dealership for the duration of the service, instead of getting a ride. They now have wireless network support, which is a nice bonus. However, the bowl of jelly donuts and bananas is now gone. I’m not sure which I’d prefer.

  • crossword: We finished the Saturday prize puzzle! We’re definitely improving.