Example Projects

Example projects demonstrating different scripting patterns and game mechanics.


Tic-Tac-Toe

A classic tic-tac-toe game against a simple AI opponent.

Open in Editor | Download

Concepts demonstrated:


ChromaStack

A 2048-style matching game where pieces on a grid move together in cardinal directions. When same-colored pieces collide, they merge and change color.

Open in Editor | Download

Concepts demonstrated:


15 Puzzle (Distributed Scripts)

The classic sliding puzzle where you arrange numbered tiles in order by sliding them into the empty space.

Open in Editor | Download

Approach: Each piece has its own onClick script. A Controller object handles keyboard input with custom onKeyDown handlers that find and move the appropriate piece.

Concepts demonstrated:

Script pattern:

# On each piece
onClick:
  set x self.cellX
  set y self.cellY
  if isEmpty("Grid", x - 1, y):
    set self.cellX x - 1
  # ... check other directions
  Controller.checkWin

# On Controller - keyboard support
onKeyDown "ArrowLeft":
  set empty emptyCells("Grid")
  if length(empty) > 0:
    set ex empty[0].x
    set ey empty[0].y
    foreach p in #piece {
      if p.cellX == ex + 1 and p.cellY == ey:
        set p.cellX ex
        Controller.checkWin
    }

15 Puzzle (Dynamics-Based)

Same 15 puzzle game, but using the dynamics system instead of manual movement scripts.

Open in Editor | Download

Approach: All logic in one cell script. Pieces have no scripts. Uses movable capability with dynamic enable/disable based on adjacency to empty cell.

Concepts demonstrated:

Script pattern:

onEnter:
  # Setup pieces on grid
  foreach piece in #piece {
    set piece.snapToGrid "Grid"
    set piece.blocking true
    # ... position randomly
  }
  self.updateMovable

onKeyDown "ArrowUp" | onKeyDown "ArrowDown" | onKeyDown "ArrowLeft" | onKeyDown "ArrowRight":
  wait movement
  self.updateMovable
  self.checkWin

action updateMovable {
  set empty emptyCells("Grid")
  set ex empty[0].x
  set ey empty[0].y
  foreach p in #piece {
    set isAdjacent false
    if p.cellX == ex - 1 and p.cellY == ey: set isAdjacent true
    if p.cellX == ex + 1 and p.cellY == ey: set isAdjacent true
    # ... check other directions
    if isAdjacent:
      set p movable style slide
    else:
      set p.movable false
  }
}

Comparison:

Aspect Distributed Scripts Dynamics-Based
Script location Each piece + Controller Cell only
Movement Manual cellX/cellY Dynamics system
Piece scripts Required None
Flexibility Full control per piece Centralized logic
Modification Edit multiple scripts Edit one script

When to Use Each Pattern

Distributed scripts (like fifteen.purl):

Dynamics-based (like fifteen-movable.purl):