Cover image for Building an Escape Room Puzzle Designer in typescript with NodeJS

Nisa Fatima

Escape rooms have become increasingly popular as interactive entertainment experiences. The key to a great escape room lies in its puzzles—they need to be challenging enough to be engaging, but not so difficult that players become frustrated. In this post, we'll build an Escape Room Puzzle Designer using HazelJS that helps create balanced puzzles, provide progressive hints, and track player solutions.

The Problem

Escape room designers face several challenges:

  • Puzzle Creation: Designing engaging puzzles with clear solutions
  • Difficulty Balancing: Ensuring puzzles are appropriately challenging for the target audience
  • Hint Management: Providing progressive hints that guide without spoiling
  • Solution Tracking: Verifying solutions and analyzing player performance

Our agent will address these challenges using HazelJS's multi-agent architecture, RAG-powered puzzle search, and intelligent difficulty balancing.

Architecture Overview

The Escape Room Puzzle Designer uses a multi-agent architecture where each agent specializes in a specific aspect of puzzle design:

  • PuzzleDesignerAgent: Designs escape room puzzles with type, difficulty, theme, and solution
  • DifficultyBalancerAgent: Balances puzzle difficulty and estimated time for optimal player experience
  • HintProviderAgent: Provides progressive hints for puzzles based on hint level
  • SolutionTrackerAgent: Tracks puzzle solutions, verifies correctness, and analyzes performance
  • PuzzleManagerAgent: Orchestrates the workflow using supervisor routing

This separation allows each agent to focus on its specialty while the supervisor ensures smooth coordination between them.

RAG-Powered Puzzle Search

One of the key features of our agent is the ability to search through a database of puzzles using Retrieval-Augmented Generation (RAG). We maintain a knowledge base of puzzles with metadata including:

  • Type (logic, pattern, riddle, physical, code-breaking)
  • Difficulty (easy, medium, hard, expert)
  • Estimated time to solve
  • Theme (detective, sci-fi, fantasy, horror, adventure)
  • Required items

When a designer asks about puzzles, the PuzzleDesignerAgent uses semantic search to find relevant puzzles based on their query. For example, a query like "Find logic puzzles with detective theme" would return puzzles matching those criteria.

The RAG implementation uses HazelJS's RAGPipeline with a MemoryVectorStore for efficient semantic search:

@Service()
export class PuzzleKnowledgeBaseService {
  private readonly embeddings = new LocalPuzzleEmbeddingProvider();
  private readonly vectorStore = new MemoryVectorStore(this.embeddings);
  private readonly rag = new RAGPipeline({
    vectorStore: this.vectorStore,
    embeddingProvider: this.embeddings,
    topK: 3,
  });

  async answer(query: string, topK = 3) {
    const sources = await this.search(query, topK);
    return {
      answer: sources.map((source) => source.content).join('\n\n'),
      sources: sources.map((source) => ({
        id: source.id,
        score: Number(source.score.toFixed(3)),
        type: source.metadata?.type,
        difficulty: source.metadata?.difficulty,
        theme: source.metadata?.theme,
        estimatedTime: source.metadata?.estimatedTime,
      })),
    };
  }
}

Enter fullscreen mode Exit fullscreen mode

Intelligent Difficulty Balancing

The DifficultyBalancerAgent takes a puzzle and adjusts its parameters to match target difficulty and time constraints. It considers:

  • Current vs. target difficulty: Calculates the adjustment needed (increase or decrease complexity)
  • Time constraints: Adjusts puzzle elements to fit within target time
  • Hint count: Adjusts the number of hints based on difficulty level
  • Complexity analysis: Provides complexity descriptions for each difficulty level

The balancer provides detailed analysis including difficulty adjustment recommendations, time adjustment suggestions, and complexity descriptions. This helps designers create puzzles that are appropriately challenging for their target audience.

Progressive Hint System

The HintProviderAgent implements a progressive hint system that guides players without spoiling the solution. It provides:

  • Hint levels: Subtle (level 1), moderate (level 2), direct (level 3), and solution (level 4)
  • Context-aware hints: Hints are tailored to the specific puzzle and current progress
  • Hint progression: Tracks which hints have been provided and what remains
  • Remaining hints: Shows how many hints are still available

This progressive approach ensures that players get the right level of help at the right time, maintaining the challenge while preventing frustration.

Solution Verification

The SolutionTrackerAgent verifies player solutions using similarity scoring. It:

  • Verifies correctness: Compares proposed solutions against the actual solution
  • Similarity scoring: Uses edit distance to calculate similarity for partial matches
  • Performance tracking: Tracks attempts, hints used, and time taken
  • Performance analysis: Provides performance ratings based on attempts and difficulty

The agent maintains solution history for each puzzle, allowing designers to analyze which puzzles are too easy or too difficult based on player performance data.

Supervisor Routing

The PuzzleManagerAgent uses HazelJS's supervisor routing to coordinate between the specialist agents. When a designer makes a request, the supervisor analyzes the request and routes it to the appropriate specialist:

  • Puzzle design requests go to PuzzleDesignerAgent
  • Difficulty balancing requests go to DifficultyBalancerAgent
  • Hint requests go to HintProviderAgent
  • Solution tracking requests go to SolutionTrackerAgent

The supervisor continues delegating until it has gathered enough information to provide a comprehensive puzzle package, then synthesizes the results into a cohesive puzzle design.

Production-Ready Features

Despite being a demo, the agent includes production-ready features:

  • Observability: OpenTelemetry integration for monitoring agent performance
  • Resilience: Retry logic and circuit breaker patterns for reliability
  • Rate limiting: Prevents abuse and ensures fair resource usage
  • Guardrails: PII redaction and content safety for secure operation
  • Metrics: Built-in metrics for tracking agent performance

Running the Agent

The agent can be run with:

npm install
npm run build
npm run dev

Enter fullscreen mode Exit fullscreen mode

The app runs on http://localhost:3000 with the HazelJS Inspector available at /__hazel for real-time monitoring and debugging.

Try It Out

You can test the agent with a curl request:

curl -s -X POST http://localhost:3000/puzzle/supervisor \
  -H 'content-type: application/json' \
  -d '{"message":"Design a logic puzzle with detective theme, medium difficulty, 10 minutes. Balance the difficulty and provide hints.","userId":"puzzle-designer-1"}'

Enter fullscreen mode Exit fullscreen mode

The agent will analyze your request, design a puzzle, balance its difficulty, provide progressive hints, and set up solution tracking—all coordinated through the supervisor routing system.

Complete Project: Escape Room Puzzle Designer
HazelJS Documentation: Docs

Key Takeaways

The Escape Room Puzzle Designer demonstrates several key HazelJS capabilities:

  • Multi-agent architecture: Each agent specializes in a specific aspect of puzzle design
  • RAG integration: Semantic search over puzzle database
  • Supervisor routing: Intelligent delegation to specialist agents
  • Production-ready patterns: Observability, resilience, and guardrails
  • Local LLM provider: Deterministic behavior without requiring API keys

This agent shows how HazelJS can be used to build fun, engaging applications that solve complex creative challenges while maintaining production-grade quality and reliability. The multi-agent approach makes it easy to extend the system with additional specialists (like theme generators or narrative designers) as needed.