Files
nomines/AGENTS.md
T
bernardo 2dbf64a2e8 Release 1.0.0: rename to NoMines, add leaderboard, theme support and release metadata
- Rename app/binary/app-id to nomines (io.github.bemagri.nomines), config dir
  moves to ~/.config/nomines with legacy path fallback
- Add persistent best-time leaderboard (Glib::KeyFile)
- Theme-aware board following system light/dark preference
- Beveled 3D cells, confetti win animation, keyboard shortcuts,
  right-click chording, per-difficulty window sizing
- Add AppStream metainfo, validate desktop file and metainfo via meson tests
- Fix license metadata to GPL-3.0-or-later and real homepage
2026-08-01 14:06:43 +01:00

3.9 KiB

AGENTS.md

GTK4/gtkmm4 Minesweeper clone ("NoMines") in C++20, built with Meson. ~800 lines total.

Build & run

meson setup build        # or reuse existing build/
meson compile -C build
./build/nomines
  • Dev deps come from the Nix flake via direnv (.envrc uses use flake); nix develop works standalone.
  • Alternative: nix build / nix run.
  • No unit tests; two optional release-validation tests (desktop file + AppStream metainfo via desktop-file-validate/appstreamcli) are auto-added when those tools exist.
  • build/compile_commands.json exists for clangd (it's gitignored, regenerate with meson setup --wipe build if stale).
  • WARNING: flake builds only see git-tracked files. New source files must be git added before nix build works.

Architecture

  • src/minefield.* — pure game logic, no GTK: Minefield (board state, flag counting, chording), Cell bitfield, GameDifficulty presets, GameState enum.
  • src/board_widget.*Gtk::DrawingArea; all rendering is hand-drawn Cairo primitives (draw_cell/draw_digit/draw_flag/draw_bomb), input via Gtk::GestureClick + EventControllerMotion, confetti particle animation on win (frame-rate independent via Gdk::FrameClock).
  • src/window.*Gtk::ApplicationWindow with HeaderBar, difficulty popover (radio-style CheckButtons), leaderboard popover, timer; owns the shared_ptr<Minefield> and swaps it on new game. Keyboard shortcuts via Gtk::EventControllerKey (R/Ctrl+N new game, 1-4 difficulties, L leaderboard).
  • src/leaderboard.* — persistent best times per difficulty via Glib::KeyFile at ~/.config/nomines/leaderboard.ini (recorded on win, shown in a header-bar popover; falls back to the pre-1.0 ~/.config/minesweeper/ path for migration). NOTE: uses the glibmm 2.80 refcounted KeyFile::create() API and gtkmm 4.14 CheckButton (a Widget+Actionable, not a Button — use signal_toggled() + get_active(), and set_group(CheckButton&)).
  • glibmm 2.80 quirk: SignalProxy<R(T...)>::connect() (non-void return signals like signal_key_pressed) requires the after bool explicitly — connect(slot, false). Void signals default it to true.
  • src/main.cpp — single Gtk::Application (io.github.bemagri.nomines); make_window_and_run<MainWindow>.

Release

  • Version 1.0.0 is stamped in FOUR places: meson.build, flake.nix, default.nix, and the <releases> entry in resources/io.github.bemagri.nomines.metainfo.xml. Bump all four together.
  • Release sanity: nix build . (validates the flake), desktop-file-validate + appstreamcli validate --no-net on the resources (wired up as meson tests).
  • The metainfo screenshot URL points at raw.githubusercontent.com/bemagri/nomines/main/... — it 404s until the repo is published; replace if the repo moves.

Gotchas

  • resources/gresource.xml + the gnome.compile_resources step in meson.build compile unused code: the app never loads these SVGs/textures (the confetti.png is also unused). All art is Cairo-drawn. Don't extend the GResource to implement visual features; draw with Cairo instead.
  • README's feature list is mostly accurate but not trustworthy in detail; verify against code. (An older leaderboard.txt CSV may linger in ~/.config/minesweeper/ from a previous experiment — the app now uses ~/.config/nomines/leaderboard.ini.)
  • Code style: snake_case methods/fields, trailing _ on private members, #pragma once, nested-struct headers. C++20 stdlib only, no third-party libs beyond gtkmm/sigc++.
  • Board colors are theme-aware: BoardWidget::resolve_palette() maps GTK CSS named colors (theme_bg_color, theme_base_color, ...) to a light/dark palette each draw. Don't hardcode light grays in draw_* helpers; thread the Palette through instead.
  • Meson source list is explicit in meson.build — new source files must be added there.
  • .direnv/ and build*/ are gitignored; flake builds require files to be committed/tracked.