Zigsaw Infinite

Zigsaw Infinite is an experimental jigsaw game about turning public-domain art into infinitely replayable puzzles with lightweight generative models. Its compact models are single-image generative models, each trained from scratch using only its corresponding public-domain artwork. They ship with the game and generate new variations locally on the CPU, keeping the whole release under 300 MB.

Features

  • 511 public-domain paintings playable as jigsaw puzzles.
  • A matching single-image generative model for each artwork can create small variations. Keep expectations low!
  • 4 classical music tracks for a relaxed puzzle session.

Design Constraints

Zigsaw Infinite was built around three design constraints.

  • Every image-generation model had to be trained from scratch using only public-domain artwork. No existing models or distillation were allowed.
  • Image generation had to run entirely locally, without requiring an expensive GPU.
  • The full package, including all models, had to stay under 300 MB.

These constraints came mostly from my preference for self-contained software. Instead of running a huge model trained on a huge dataset on expensive hardware, I wanted the game to bundle extremely small models and generate images quickly and cheaply, without depending on the network.

Generative Model

Early in the project, I tried training diffusion models on publicly available datasets. Given the constraints on training cost, model size, and package size, I could not get results that I wanted to turn into jigsaw puzzles.

I needed a generative model that could still work with extremely limited training data. The GM-DC survey is a useful map of this area: it frames generative modeling under limited-data, few-shot, and zero-shot settings. The part that fit this game was the single-image approach, where a model learns from one image by modeling its internal patch distribution.

The model used in Zigsaw Infinite is ConSinGAN . It is a SinGAN-family model trained from a single image, but with several stages trained concurrently, feature maps passed between stages, and a rescaling strategy that makes it possible to train with fewer stages.

All source artwork images are resized so their longest edge is 250 px. The model weights are stored with INT8 quantization. Because all 511 models share the same architecture, each model is about 439 kB, for a combined 224.6 MB.

Training was intentionally lightweight. Each model was trained across 7 scales with 2,000 iterations per scale, 48 base channels, and 3 convolution blocks per stage. Each model reached its final checkpoint in about 10.5 minutes on an NVIDIA GeForce RTX 4090 with 24 GB of VRAM.

Each model is dedicated to exactly one source painting. It is not a general image generator, and it cannot create a completely new puzzle image. What it can do is produce small variations that keep the original painting recognizable while shifting local structure, texture, and detail enough to add a little replayability.

As one concrete measurement, generating a variant of the image below took only 455 ms on my development machine, an Apple M2 Max MacBook Pro with a 12-core CPU and 96 GB of unified memory, and produced a 250 x 223 image.

Source Source artwork: The Entrance to the Tautira River, Tahiti. Fisherman Spearing a Fish by John La Farge
Generated Generated variation of The Entrance to the Tautira River, Tahiti. Fisherman Spearing a Fish by John La Farge
The Entrance to the Tautira River, Tahiti. Fisherman Spearing a Fish , c. 1895, by John La Farge. The generated result is one example from the model. This artwork/result pair is cherry-picked from the higher-quality cases in the set; many generated results are rougher.

The quality varies widely from image to image, and the results are not consistently satisfying. But within the constraints above, it works.

Tech Stack

The "Zig" in Zigsaw is literal: Zigsaw Infinite is written in the Zig programming language .

It does not use an existing game engine. The game is built directly on SDL3 and its companion libraries: SDL3_ttf for fonts, SDL3_image for image loading, and SDL3_mixer for audio.

Zig worked well for this project mostly because of three things: C interoperability, compiled-language speed, and cross-compilation. SDL is a C library, so the game can import the SDL headers directly with Zig's @cImport instead of going through a larger wrapper framework.

The Windows build is the clearest example. The project keeps the platform-specific SDL binaries and build settings inside the build system, so from my macOS development machine, building a Windows executable is mostly a matter of adding -Dtarget=x86_64-windows to the build command.

The release packaging is handled the same way: the build process can bundle the game assets, collect the required runtime libraries, and produce the archive used for distribution.

Package Size

The release package is still mostly model data. Unpacked, the macOS build is 251.2 MB and the Windows build is 245.0 MB. The downloadable ZIPs are smaller: 204.7 MB for macOS and 204.2 MB for Windows. The macOS executable and third-party libraries are larger because they are universal binaries containing both x86_64 and arm64 code.

251.2 MB
macOS .app
245.0 MB
Windows .exe package
Models 511 single-image models 224.6 MB
Third-party libraries SDL runtime libraries macOS 11.5 MB Windows 6.2 MB
Source artwork images 511 resized WebP images 6.8 MB
BGM + sound effects 8 audio files 5.4 MB
Executable Platform binary macOS 2.0 MB Windows 1.2 MB
Other bundled data Fonts, config, metadata 1.0 MB
The chart uses unpacked package contents rather than compressed ZIP sizes, so each category reflects its bundled size.

Credits

The full credits, license text, and redistribution notices are included in the THIRD_PARTY_NOTICES.txt file bundled with every release. The short version is below.

Release Date
Store Pages
Supported Platforms
  • macOS
  • Windows