📡 API Reference

Complete reference for the GameplayGen REST API, custom validators, and quality metrics.

POST /generate

The core endpoint. Generates verified content for your game.

Request Body

typescript
interface GenerateRequest {
  /** Game type — determines which generator + validator to use */
  gameType: GameType;

  /** Game-type-specific parameters */
  params: Record<string, unknown>;

  /** How many content pieces to generate */
  count: number;

  /** Target difficulty (0.0 = trivial, 1.0 = extreme) */
  difficulty?: {
    min?: number;     // default 0.0
    max?: number;     // default 1.0
    target?: number;  // aim for this difficulty
    curve?: "flat" | "ascending" | "descending" | "bell";
  };

  /** Variety constraints */
  variety?: {
    minDiversity?: number;     // Min difference between pieces (0-1)
    exclude?: ContentPiece[];  // Avoid similarity to these
  };

  /** Custom validator endpoint (overrides built-in) */
  validatorUrl?: string;

  timeoutSeconds?: number;  // Max generation time
  seed?: number;            // Reproducible generation
}

Supported Game Types

ValueStatusDescription
grid-stealth✅ AvailableGrid stealth puzzles — patrol avoidance, pathfinding
word-puzzle✅ AvailableWordle variants, word games, anagram puzzles
sokoban✅ AvailablePush-box puzzles with optimal move validation
sudoku✅ AvailableClassic number puzzles with difficulty grading
nonogram✅ AvailablePicross / pixel art logic puzzles (unique solution guarantee)
dungeon-layout🔜 ComingRoguelike room/map generation
tower-defense🔜 ComingWave spawn composition and timing
platformer-chunk🔜 ComingDifficulty-calibrated platformer segments
tcg-balance📋 RoadmapTCG card stat balancing
quest-encounter📋 RoadmapRPG quest/encounter templates
custom✅ AvailableBring your own rules + validator

Response

typescript
interface GenerateResult {
  content: ContentPiece[];
  requested: number;
  delivered: number;

  stats: {
    totalCandidates: number;
    totalValidated: number;
    totalRejected: number;
    totalTime: number;        // ms
    avgDifficulty: number;
    difficultyRange: [number, number];
  };
}

interface ContentPiece {
  id: string;
  gameType: string;
  content: Record<string, unknown>;  // Game-type specific data

  metrics: {
    verified: boolean;
    difficulty: number;   // 0.0–1.0
    balance: number;      // 0.0–1.0
    novelty: number;      // 0.0–1.0
    quality: number;      // weighted combination
    solution?: unknown;
    notes?: string[];
  };

  meta: {
    generatedAt: string;
    generatorVersion: string;
    attempts: number;
    validationTime: number;  // ms
  };
}

Example Response

json
{
  "content": [
    {
      "id": "pf_abc123",
      "gameType": "sokoban",
      "content": {
        "grid": [
          ["#","#","#","#","#","#","#","#"],
          ["#",".",".",".",".",".",".","#"],
          ["#",".",".","$",".",".","#","#"],
          ["#",".","#",".",".","$",".","#"],
          ["#",".",".",".",".","#",".","#"],
          ["#",".",".","$",".",".","@","#"],
          ["#",".",".",".",".",".",".","#"],
          ["#","#","#","#","#","#","#","#"]
        ],
        "goals": [[2,4],[4,2],[6,5]],
        "playerStart": [5,6]
      },
      "metrics": {
        "verified": true,
        "difficulty": 0.58,
        "balance": 0.92,
        "novelty": 1.0,
        "quality": 0.83,
        "solution": ["L","L","U","U","L","D","L","L","U","R","U","U"],
        "notes": ["3 boxes, optimal 12 moves, no deadlock states"]
      },
      "meta": {
        "generatedAt": "2025-07-15T10:30:00Z",
        "generatorVersion": "0.2.0",
        "attempts": 3,
        "validationTime": 42
      }
    }
  ],
  "requested": 1,
  "delivered": 1,
  "stats": {
    "totalCandidates": 3,
    "totalValidated": 1,
    "totalRejected": 2,
    "totalTime": 1250,
    "avgDifficulty": 0.58,
    "difficultyRange": [0.58, 0.58]
  }
}

Error Responses

StatusCodeDescription
400invalid_paramsParameters are malformed or missing required fields
400invalid_game_typeUnsupported game type
401unauthorizedMissing or invalid API key
408timeoutGeneration exceeded timeoutSeconds
422generation_failedCould not generate enough valid content
429rate_limitedToo many requests — check your rate limit

Custom Validators

GameplayGen has built-in validators for all standard game types. For custom game types — or to add extra validation on top of built-in checks — you can provide your own validator endpoint.

How It Works

Set validatorUrl in your request. GameplayGen will POST each generated content candidate to your endpoint. Your validator returns whether the content is valid and optional quality metrics.

Request (from GameplayGen to your validator)

typescript
// GameplayGen sends:
POST https://your-game.com/validate
Content-Type: application/json

{
  "content": { /* the generated content piece */ },
  "gameType": "custom",
  "params": { /* your full params object */ }
}

Expected Response

typescript
interface CustomValidatorResponse {
  /** Is this content valid for your game? */
  valid: boolean;

  /** Optional: difficulty score (0.0–1.0) */
  difficulty?: number;

  /** Optional: balance score (0.0–1.0) */
  balance?: number;

  /** Optional: the solution/walkthrough */
  solution?: unknown;

  /** Optional: human-readable notes */
  notes?: string[];
}

Example: Custom Validator for a Tower Defense Game

typescript
// your-validator.ts
app.post("/validate", async (c) => {
  const { content, params } = await c.req.json();

  const wave = content.wave;
  const totalHP = wave.enemies.reduce((sum, e) => sum + e.hp, 0);
  const maxDPS = params.maxPlayerDPS;

  // Check if wave is survivable but challenging
  const timeToKill = totalHP / maxDPS;
  const difficulty = Math.min(timeToKill / params.waveTimeLimit, 1.0);
  const balanced = difficulty >= 0.3 && difficulty <= 0.95;

  return c.json({
    valid: balanced,
    difficulty,
    balance: balanced ? 0.9 : 0.3,
    notes: [
      `Total enemy HP: ${totalHP}`,
      `Estimated time to kill: ${timeToKill.toFixed(1)}s`,
    ]
  });
});

Timeout & Retry

Your validator must respond within 5 seconds. If it times out, the content candidate is rejected. GameplayGen retries validators up to 3 times on network errors (not on 4xx/5xx responses).

Quality Metrics

Every content piece returned by GameplayGen includes a metrics object. Here's what each score means and how they're calculated.

verified

Boolean. Has this content passed formal verification? For Sokoban, this means a solver confirmed the puzzle has an optimal solution. For Sudoku, it means exactly one valid solution exists. Content with verified: false is never returned — it's filtered out during generation.

difficulty (0.0–1.0)

How hard is this content? Scoring varies by game type:

Game TypeDifficulty Signal
grid-stealthOptimal path length, guard density, vision cone coverage
word-puzzleWord frequency, letter pattern rarity, obscurity score
sokobanOptimal move count, deadlock risk, branching factor
sudokuRequired solving techniques (naked singles → X-wing → chains)
nonogramLine solving complexity, required backtracking depth
customProvided by your validator endpoint

balance (0.0–1.0)

How fair/balanced is this content? A score of 1.0 means perfectly balanced — no degenerate strategies, no impossible scenarios. A score below 0.5 indicates potential design issues.

novelty (0.0–1.0)

How different is this piece from other generated content in the same batch (and from any exclude list you provided)? Uses feature hashing and cosine similarity. A score of 1.0 means completely unique; below 0.3 is very similar to existing content.

quality (0.0–1.0)

The weighted overall score, combining difficulty accuracy (how close to your target), balance, and novelty:

text
quality = 0.3 × difficulty_accuracy + 0.35 × balance + 0.35 × novelty

Where difficulty_accuracy = 1.0 - |actual_difficulty - target_difficulty|

solution

Optional. The verified solution or walkthrough. For Sokoban, this is the optimal move sequence. For Sudoku, the completed grid. Useful for debugging, hint systems, and walkthroughs.

notes

Human-readable quality notes from the validator. Describes what the validator found interesting or notable about this piece.