Skip to content
add-puzzle-type logo

Add Puzzle Type

add-puzzle-type

Scaffold a new puzzle type across all 10+ pipeline integration points in jigsawR. Creates the core puzzle module, wires it into the unified pipeline (generation, positioning, rendering, adjacency), adds ggpuzzle geom/stat layers, updates DESCRIPTION and config.yml, extends the Shiny app, and crea...

pjt222/agent-almanac0installs36stars

SKILL.md

Full skill instructions

Add Puzzle Type

Scaffold a new puzzle type across all pipeline integration points in jigsawR.

When to Use

  • Adding a completely new puzzle type to the package
  • Following the established integration checklist (CLAUDE.md 10-point pipeline)
  • Ensuring nothing is missed when wiring a new type end-to-end

Inputs

  • Required: New type name (lowercase, e.g. "triangular")
  • Required: Geometry description (how pieces are shaped/​arranged)
  • Required: Whether the type needs external packages (add to Suggests)
  • Optional: Parameter list beyond the standard (grid, size, seed, tabsize, offset)
  • Optional: Reference implementation or algorithm source

Procedure

Step 1: Create Core Puzzle Module

Create R/<type>_puzzle.R with the internal generation function:

#' Generate <type> puzzle pieces (internal)
#' @noRd
generate_<type>_pieces_internal <- function(params, seed) {
  # 1. Initialize RNG state
  # 2. Generate piece geometries
  # 3. Build edge paths (SVG path data)
  # 4. Compute adjacency
  # 5. Return list: pieces, edges, adjacency, metadata
}

Follow the pattern in R/​voronoi_puzzle.R or R/​snic_puzzle.R for structure.

Expected: Function returns a list with $pieces, $edges, $adjacency, $metadata.

On failure: Compare the return structure against generate_voronoi_pieces_internal() to identify missing list elements or incorrect types.

Step 2: Wire into jigsawR_clean.R

Edit R/​jigsawR_clean.R:

  1. Add "<type>" to the valid_types vector
  2. Add type-specific parameter extraction in the params section
  3. Add validation logic for type-specific constraints
  4. Add filename prefix mapping (e.g., "<type>" -> "<type>_")
# In valid_types
valid_types <- c("rectangular", "hexagonal", "concentric", "voronoi", "snic", "<type>")

Expected: generate_puzzle(type = "<type>") is accepted without "unknown type" error.

On failure: Verify the type string is added to valid_types exactly as spelled, and that parameter extraction covers all required type-specific arguments.

Step 3: Wire into unified_piece_generation.R

Edit R/​unified_piece_generation.R:

  1. Add dispatch case in generate_pieces_internal()
  2. Add fusion handling if the type supports PILES notation
# In the switch/​dispatch
"<type>" = generate_<type>_pieces_internal(params, seed)

Expected: Pieces are generated when the type is dispatched.

On failure: Confirm the dispatch case string matches the type name exactly and that generate_<type>_pieces_internal is defined and exported from the puzzle module.

Step 4: Wire into piece_positioning.R

Edit R/​piece_positioning.R:

Add positioning dispatch for the new type. Most types use shared positioning logic, but some need custom handling.

Expected: apply_piece_positioning() handles the new type without errors and pieces are placed at correct coordinates.

On failure: Check whether the new type needs custom positioning logic or can reuse the shared positioning path. Add a dispatch case if the default path does not apply.

Step 5: Wire into unified_renderer.R

Edit R/​unified_renderer.R:

  1. Add rendering case in render_puzzle_svg()
  2. Add edge path function: get_<type>_edge_paths()
  3. Add piece name function: get_<type>_piece_name()

Expected: SVG output is generated for the new type with correct piece outlines and edge paths.

On failure: Verify get_<type>_edge_paths() returns valid SVG path data and get_<type>_piece_name() produces unique identifiers for each piece.

Step 6: Wire into adjacency_api.R

Edit R/​adjacency_api.R:

Add neighbor dispatch so get_neighbors() and get_adjacency() work for the new type.

Expected: get_neighbors(result, piece_id) returns correct neighbors for any piece in the puzzle.

On failure: Check that the adjacency dispatch returns the correct data structure. Test with a small grid and manually verify neighbor relationships against the geometry.

Step 7: Add ggpuzzle Geom Layer

Edit R/​geom_puzzle.R:

Create geom_puzzle_<type>() using the make_puzzle_layer() factory:

#' @export
geom_puzzle_<type> <- function(mapping = NULL, data = NULL, ...) {
  make_puzzle_layer(type = "<type>", mapping = mapping, data = data, ...)
}

Expected: ggplot() + geom_puzzle_<type>(aes(...)) renders without error.

On failure: Verify make_puzzle_layer() receives the correct type string and that the geom function is exported in the NAMESPACE via @export.

Step 8: Add Stat Dispatch

Edit R/​stat_puzzle.R:

  1. Add type-specific default parameters
  2. Add dispatch case in compute_panel()

Expected: The stat layer computes puzzle geometry correctly and produces the expected number of polygons.

On failure: Check that the compute_panel() dispatch case returns a data frame with the required columns (x, y, group, piece_id) and that default parameters are sensible for the new type.

Step 9: Update DESCRIPTION

Edit DESCRIPTION:

  1. Add new type to the Description field text
  2. Add any new packages to Suggests: (if external dependency)
  3. Update Collate: to include the new R file (alphabetical order)

Expected: devtools::document() succeeds. No NOTE about unlisted files.

On failure: Check that the new R file is listed in the Collate: field in alphabetical order and that any new Suggests packages are spelled correctly with version constraints.

Step 10: Update config.yml

Edit inst/​config.yml:

Add defaults and constraints for the new type:

<type>:
  grid:
    default: [3, 3]
    min: [2, 2]
    max: [20, 20]
  size:
    default: [300, 300]
    min: [100, 100]
    max: [2000, 2000]
  tabsize:
    default: 20
    min: 5
    max: 50
  # Add type-specific params here

Expected: Config is valid YAML. Defaults produce a working puzzle when used by generate_puzzle().

On failure: Validate YAML with yaml::yaml.load_file("inst/​config.yml"). Ensure default grid and size values produce a sensible puzzle (not too small or too large).

Step 11: Extend Shiny App

Edit inst/​shiny-app/​app.R:

  1. Add the new type to the UI type selector
  2. Add conditional UI panels for type-specific parameters
  3. Add server-side generation logic

Expected: Shiny app shows the new type in the dropdown and generates puzzles when selected.

On failure: Check that the type is added to the choices argument of the UI selector, that the conditional panel for type-specific parameters uses conditionalPanel(condition = "input.type == '<type>'"), and that the server-side handler passes the correct parameters.

Step 12: Create Test Suite

Create tests/​testthat/​test-<type>-puzzles.R:

test_that("<type> puzzle generates correct piece count", { ... })
test_that("<type> puzzle respects seed reproducibility", { ... })
test_that("<type> adjacency returns valid neighbors", { ... })
test_that("<type> fusion merges pieces correctly", { ... })
test_that("<type> geom layer renders without error", { ... })
test_that("<type> SVG output is well-formed", { ... })
test_that("<type> config constraints are enforced", { ... })

If the type requires an external package, wrap tests with skip_if_not_installed().

Expected: All tests pass. No skips unless external dependency is missing.

On failure: Check each integration point individually. The most common issue is missing dispatch cases — run grep -rn "switch\|valid_types" R/ to find all dispatch locations.

Validation

  • generate_puzzle(type = "<type>") produces valid output
  • All 10 integration points are wired correctly
  • devtools::test() passes with new tests
  • devtools::check() returns 0 errors, 0 warnings
  • Shiny app renders the new type
  • Config constraints are enforced (min/​max validation)
  • Adjacency and fusion work correctly
  • ggpuzzle geom layer renders without error
  • devtools::document() succeeds (NAMESPACE updated)

Common Pitfalls

  • Missing dispatch case: Forgetting one of the 10+ files causes silent failure or "unknown type" errors
  • strsplit with negative numbers: When creating adjacency keys with paste(a, b, sep = "-"), negative piece labels produce keys like "1--1". Use "|" separator instead and split with "\\|".
  • Using cat() for output: Always use cli package logging wrappers (log_info, log_warn, etc.)
  • Collate order: DESCRIPTION Collate field must be alphabetical or dependency-ordered
  • Config.yml format: Ensure YAML is valid; test with yaml::yaml.load_file("inst/​config.yml")

Related Skills

  • generate-puzzle — test the new type after scaffolding
  • run-puzzle-tests — run the full test suite to verify integration
  • validate-piles-notation — test fusion with the new type
  • write-testthat-tests — general test-writing patterns
  • write-roxygen-docs — document the new geom function

More skills from pjt222

evolve-agent logo
pjt222/agent-almanac

evolve-agent

Evolve an existing agent definition by refining its persona in-place or creating an advanced variant. Covers assessing the current agent against best practices, gathering evolution requirements, choosing scope (refinement vs. variant), applying changes to skills, tools, capabilities, and limitati...

36 0
View
version-ml-data logo
pjt222/agent-almanac

version-ml-data

Version machine learning datasets using DVC (Data Version Control) with remote storage backends, build reproducible data pipelines with dependency tracking, integrate with Git workflows, and ensure data lineage for model reproducibility. Use when versioning large datasets that do not fit in Git, ...

36 0
View
create-2d-composition logo
pjt222/agent-almanac

create-2d-composition

Compose 2D graphics programmatically using SVG generation, diagram layout algorithms, image compositing, and batch processing workflows. Use when generating diagrams, flowcharts, or infographics programmatically, creating reproducible scientific figures, automating production of badges or visual ...

36 0
View
manage-kubernetes-secrets logo
pjt222/agent-almanac

manage-kubernetes-secrets

Implement secure secrets management in Kubernetes using SealedSecrets for GitOps, External Secrets Operator for cloud secret managers, and rotation strategies. Handle TLS certificates, API keys, and credentials with encryption at rest and RBAC controls. Use when storing sensitive configuration fo...

36 0
View
appraise-gemstone logo
pjt222/agent-almanac

appraise-gemstone

Appraise gemstone value using the four Cs (color, clarity, cut, carat), origin assessment, treatment detection, and market factor analysis. Advisory educational guidance only — not a certified appraisal. Use when understanding factors that determine a gemstone's value, pre-screening stones before...

36 0
View
center logo
pjt222/agent-almanac

center

AI dynamic reasoning balance — maintaining grounded reasoning under cognitive pressure, smooth chain-of-thought coordination, and weight-shifting cognitive load across subsystems. Use at the beginning of a complex task requiring multiple coordinated reasoning threads, after a sudden context shift...

36 0
View
build-tcg-deck logo
pjt222/agent-almanac

build-tcg-deck

Build a competitive or casual trading card game deck. Covers archetype selection, mana/energy curve analysis, win condition identification, meta-game positioning, and sideboard construction for Pokemon TCG, Magic: The Gathering, Flesh and Blood, and other TCGs. Use when building a new deck for a ...

36 0
View
setup-prometheus-monitoring logo
pjt222/agent-almanac

setup-prometheus-monitoring

Configure Prometheus for time-series metrics collection, including scrape configurations, service discovery, recording rules, and federation patterns for multi-cluster deployments. Use when setting up centralized metrics collection for microservices, implementing time-series monitoring for applic...

36 0
View
assess-holistic-health logo
pjt222/agent-almanac

assess-holistic-health

Conduct temperament-based health assessment from Hildegard von Bingen's Causae et Curae. Evaluates the four temperaments (sanguine, choleric, melancholic, phlegmatic), elemental correspondences (air, fire, earth, water), and provides dietary and lifestyle recommendations for rebalancing. Use when...

36 0
View
implement-gitops-workflow logo
pjt222/agent-almanac

implement-gitops-workflow

Implement GitOps continuous delivery using Argo CD or Flux with app-of-apps pattern, automated sync policies, drift detection, and multi-environment promotion. Manage Kubernetes deployments declaratively from Git with automated reconciliation. Use when implementing declarative infrastructure mana...

36 0
View
assess-ip-landscape logo
pjt222/agent-almanac

assess-ip-landscape

Map the intellectual property landscape for a technology domain or product area. Covers patent cluster analysis, white space identification, competitor IP portfolio assessment, freedom-to-operate preliminary screening, and strategic IP positioning recommendations. Use before starting R&D in a new...

36 0
View
configure-log-aggregation logo
pjt222/agent-almanac

configure-log-aggregation

Set up centralized log aggregation with Loki and Promtail (or ELK stack), including log parsing, label extraction, retention policies, and integration with metrics for correlation. Use when consolidating logs from multiple services into a searchable system, replacing local log files with centrali...

36 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View