All skills

Build a puzzle game: grid/board state, move input, rule-based resolution (match-3 cascades, sokoban pushes, tile logic), scoring, and undo. Use for a match-3, sokoban, or grid-logic puzzle.

Use this Skill: https://skilld.dev/gh/gamedev-skills/awesome-gamedev-agent-skills/puzzle

This session only. Nothing lands on disk.

referencesboard-and-resolution.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Puzzle board models and resolution (depth)

Detail behind SKILL.md. Engine-neutral pseudocode. Board coordinates are (y, x) with (0,0) top-left and y growing downward (matches most tilemaps).

1. Match-3 full resolution

The resolution loop is: detect matches → score → clear → gravity → refill → repeat until stable.

def apply_gravity(board):
    for x in range(W):
        # Compact non-empty cells downward within each column.
        column = [board[y][x] for y in range(H) if board[y][x] is not EMPTY]
        pad = [EMPTY] * (H - len(column))
        for y in range(H):
            board[y][x] = (pad + column)[y]      # empties on top, pieces settle to the bottom

def refill(board, rng):
    for y in range(H):
        for x in range(W):
            if board[y][x] is EMPTY:
                board[y][x] = random_piece(rng)  # seeded RNG for reproducibility

Avoid spawning matches on refill if you don't want free cascades: when filling, reject a color that would immediately complete a line, or resolve those cascades intentionally as part of scoring.

Initial board: generate so there are no pre-existing matches but at least one valid move (see deadlocks). A common method: fill randomly, clear any starting matches, then verify a move exists.

2. Deadlock detection and reshuffle (match-3)

A board with no possible matching move is a soft-lock. Detect it and react:

def has_valid_move(board):
    # Try every adjacent swap; if any creates a match, a move exists.
    for y in range(H):
        for x in range(W):
            for dy, dx in ((0, 1), (1, 0)):
                if in_bounds(y+dy, x+dx):
                    swap(board, (y, x), (y+dy, x+dx))
                    ok = bool(find_matches(board))
                    swap(board, (y, x), (y+dy, x+dx))   # swap back
                    if ok: return True
    return False
# If not has_valid_move(board): reshuffle existing pieces (keep counts) until a move exists,
# or end the level, depending on your rules.

3. Cascade scoring

Reward chains so deep setups feel great:

def score_for(matches, chain):
    base = len(matches) * 10
    return base * chain            # linear in chain; or base * 2**(chain-1) for exponential
# Bonus for larger single matches (4 = line-clear piece, 5 = color bomb, etc.) is a common
# layer on top — special pieces created by 4+/5+ matches add strategy.

4. Sokoban / push puzzles

A different rule family: the player pushes blocks; the goal is to place blocks on targets. Resolution is a legality check, not a cascade.

def try_push(board, player, dir):
    ahead  = player + dir
    beyond = player + dir * 2
    if is_wall(board, ahead): return False
    if is_block(board, ahead):
        if is_wall(board, beyond) or is_block(board, beyond):
            return False                       # can't push two blocks or into a wall
        move_block(board, ahead, beyond)
    move_player(board, player, ahead)
    return True
# Win when every target cell holds a block. Undo is essential — sokoban is unforgiving.
# Detect dead states (a block pushed into a corner that isn't a target) to hint a restart.

5. Rule-based / logic puzzles

For logic grids (nonograms, sliding tiles, circuit/flow puzzles), the "resolution" is usually just validity + win check after each move — no cascade. Keep the rule check pure and total: given a board, return solved / unsolved / invalid. Undo and a clear "current constraints" display matter more than animation here.

6. Undo strategies

Strategy Stores Pros Cons
Snapshot full board + counters per move trivial, exact memory on big boards
Command the move + inverse data compact must implement invert per rule
Redo stack future snapshots/commands redo support extra bookkeeping

Whatever you choose, undo must restore everything that affects play: board, score, moves left, RNG state, and any special-piece state. Test undo by hashing full state before a move and after undo — they must match.

7. Solvable generation

Generated levels must be solvable, or players hit unfair dead ends:

  • Generate-and-verify: make a candidate, run a solver (BFS/DFS/A* over board states for push/slide puzzles; move-existence for match-3); keep it only if solvable within the move/time budget. Use a seed so a level is reproducible.
  • Reverse generation: start from a solved board and apply random legal inverse moves; the scrambled result is guaranteed solvable by reversing them. Great for sliding/sokoban puzzles.
  • Tag each level with its seed and intended difficulty so progression curves are tunable and a bad level can be reproduced and fixed.

8. Input locking and presentation

The board model resolves instantly; animation plays the resolution out over time. Lock input until the board is stable so the player can't act on a mid-cascade board. Drive visuals from the sequence of state changes resolution produced (a list of clears/falls/spawns), not by re-reading a half-updated board.

Source: SKILL.md on GitHub

No alerts1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    The skill provides architectural patterns and pseudocode for implementing grid-based puzzle games such as match-3 and Sokoban. No security vulnerabilities or malicious patterns were detected.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: LOW · No issues

Signed by skilld at 3727d02. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 days ago.

Activeupdated 2 months ago

README badge

README badge for gamedev-skills/awesome-gamedev-agent-skills/puzzle