Skip to main content
skill CX Codex

use-template — Claude Code skill: clone a game template

Copies a ready game template from the gallery into a new project. You get runnable code right away, no AI pipeline involved.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add PlayableIntelligence/game-creator --skill use-template -a claude-code
Open on GitHub

What use-template does

The skill reads the local site/manifest.json registry and copies the chosen template into a new folder. With no arguments it prints a numbered list of every template with its engine and complexity, then asks you to pick. A template ID is required; the project name falls back to that ID.

The copy skips node_modules/, dist/, output/, .herenow/, progress.md, test-results/ and playwright-report/. After that the skill rewrites name in package.json and the <title> in index.html, then runs npm install. Project names are checked against path traversal and special characters, and the resolved target path is verified to stay inside the expected parent directory.

One thing to know before you run it: the skill sends anonymous telemetry about which template was cloned. Only the event type, template ID, source and schema version go out. Turn it off with DO_NOT_TRACK=1 or DISABLE_TELEMETRY=1. If your game is meant to grow over many sessions, this is the wrong tool — it hands you a one-off copy, not a milestone workflow.

What it helps with

  • scaffold a working game template into a new folder
  • list available templates with engine and complexity
  • clone an example and run it locally right away
  • rename the project in package.json and the page title
  • start from existing code instead of generating from scratch

Example prompts for the agent

  • /use-template flappy-bird my-game
  • /use-template threejs-3d-starter space-shooter
  • /use-template castle-siege

How to install use-template

1Skills CLI (Vercel)

npx skills add PlayableIntelligence/game-creator --skill use-template -a claude-code

2Manually: put the files in place

~/.claude/skills/use-template/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/use-template/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about use-template

How do I install use-template in Claude?

Run npx skills add PlayableIntelligence/game-creator --skill use-template -a claude-code. The skill lands at ~/.claude/skills/use-template/SKILL.md.

What does use-template do?

It copies a chosen game template from the gallery into a new project, strips build and test artifacts, updates project metadata and installs dependencies with npm install.

How is use-template different from /viral-game and /make-game?

It is a fast copy: runnable code now, manual customisation after. /viral-game is a one-shot AI pipeline from prompt to deploy, and /make-game runs a multi-session workflow with ADRs and docs/STATE.md.

Source text

SKILL.md · MIT
---
name: use-template
description: Clone a game template from the gallery as a starting point. Use when the user says "use a template", "start from a template", "clone flappy-bird", "use the platformer template", or wants to quickly bootstrap a game from an existing example. Do NOT use for creating a game from scratch (use viral-game for one-shot builds or make-game for milestone-driven projects).
argument-hint: "[template-id] [project-name]"
license: MIT
metadata:
  author: OpusGameLabs
  version: 1.3.0
  tags: [game, template, scaffold, clone, gallery]
---

# Use Template

Clone a game template from the gallery into a new project. This is a fast copy — working code in seconds, not an AI pipeline.

## Behavior

1. **Parse arguments**: `<template-id> [project-name]`
   - If no arguments provided, read `site/manifest.json`, display a numbered list of all templates with their engine/complexity/description, and ask the user to pick one.
   - `template-id` is required. `project-name` defaults to `template-id`.

2. **Look up template** in `site/manifest.json` by `id`. If not found, show available IDs and abort.

3. **Determine target directory**:
   - If current working directory is inside the `game-creator` repository → `examples/<project-name>/`
   - Otherwise → `./<project-name>/`
   - If target already exists, abort with error.

4. **Copy the template source directory** to the target, **excluding**:
   - `node_modules/`
   - `dist/`
   - `output/`
   - `.herenow/`
   - `progress.md`
   - `test-results/`
   - `playwright-report/`

5. **Update project metadata**:
   - In `package.json`: set `"name"` to the project name
   - In `index.html` (if exists): update `<title>` to a formatted version of the project name

6. **Install dependencies**: Run `npm install` in the target directory.

7. **Print next steps**:
   ```
   Template cloned successfully!

   cd <project-name>
   npm run dev
   ```

## Implementation

```javascript
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

// Find game-creator root (contains site/manifest.json)
function findRoot(dir) {
  let d = dir;
  while (d !== path.dirname(d)) {
    if (fs.existsSync(path.join(d, 'gallery', 'manifest.json'))) return d;
    d = path.dirname(d);
  }
  return null;
}

const root = findRoot(process.cwd());
const manifest = JSON.parse(fs.readFileSync(path.join(root, 'gallery', 'manifest.json'), 'utf-8'));

// Parse args
const [templateId, projectName] = args; // provided by the agent
const template = manifest.find(t => t.id === templateId);
const name = projectName || templateId;

// Validate project name — reject path traversal and special characters
if (/[\/\\]|^\.\.?$|\.\./.test(name)) {
  throw new Error(`Invalid project name: "${name}". Must not contain path separators or ".." sequences.`);
}
if (!/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(name)) {
  throw new Error(`Invalid project name: "${name}". Use only alphanumeric characters, hyphens, underscores, and dots.`);
}

// Determine target
const inGameCreator = process.cwd().startsWith(root);
const target = inGameCreator
  ? path.join(root, 'examples', name)
  : path.join(process.cwd(), name);

// Verify resolved path stays within expected parent directory
const expectedParent = inGameCreator ? path.join(root, 'examples') : process.cwd();
if (!path.resolve(target).startsWith(path.resolve(expectedParent))) {
  throw new Error('Target directory resolved outside expected parent. Aborting.');
}

// Copy with exclusions
const EXCLUDE = ['node_modules', 'dist', 'output', '.herenow', 'progress.md', 'test-results', 'playwright-report'];

function copyDir(src, dst) {
  fs.mkdirSync(dst, { recursive: true });
  for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
    if (EXCLUDE.includes(entry.name)) continue;
    const s = path.join(src, entry.name);
    const d = path.join(dst, entry.name);
    if (entry.isDirectory()) copyDir(s, d);
    else fs.copyFileSync(s, d);
  }
}

copyDir(path.join(root, template.source), target);

// Update package.json
const pkgPath = path.join(target, 'package.json');
if (fs.existsSync(pkgPath)) {
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
  pkg.name = name;
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
}

// Update index.html title
const indexPath = path.join(target, 'index.html');
if (fs.existsSync(indexPath)) {
  let html = fs.readFileSync(indexPath, 'utf-8');
  const prettyName = name.replace(/[-_]/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
  html = html.replace(/<title>[^<]*<\/title>/, `<title>${prettyName}</title>`);
  fs.writeFileSync(indexPath, html);
}

// Install
execSync('npm install', { cwd: target, stdio: 'inherit' });

// Optional anonymous telemetry — tracks which templates are popular
// Data sent: event type ("clone"), template ID, source ("skill"), schema version
// No PII, IP addresses, file paths, or user-identifiable data is transmitted
// Opt out: set DO_NOT_TRACK=1 or DISABLE_TELEMETRY=1 in your environment
if (!process.env.DO_NOT_TRACK && !process.env.DISABLE_TELEMETRY) {
  const https = require('https');
  const telemetryUrl = process.env.TELEMETRY_URL || 'https://gallery-telemetry.up.railway.app';
  https.get(`${telemetryUrl}/t?event=clone&template=${encodeURIComponent(templateId)}&source=skill&v=1`)
    .on('error', () => {});
}
```

## Example Usage

```
/use-template flappy-bird my-game
/use-template threejs-3d-starter space-shooter
/use-template castle-siege
```

## Security Notes

- **Path validation**: Project names are validated to reject path traversal (`..`), path separators, and special characters. The resolved target path is verified to stay within the expected parent directory.
- **npm install**: Runs `npm install` from the copied template's `package.json`, which contains only pinned dependencies from the template (Phaser/Three.js, Vite). No arbitrary packages are installed.
- **Telemetry**: Anonymous, opt-out usage telemetry sends only the template ID and event type (no PII, paths, or user data). Disable with `DO_NOT_TRACK=1` or `DISABLE_TELEMETRY=1` environment variables.
- **Template source**: Templates are copied from the local `site/manifest.json` registry within the plugin — no external templates are fetched at clone time.

## Key Difference from /viral-game and /make-game

`/use-template` is a **10-second copy**. You get working, runnable code instantly and customize it manually. `/viral-game` is a **10-minute AI pipeline** that scaffolds, designs, adds audio, tests, deploys, and monetizes from a text prompt or tweet URL — opinionated and one-shot. `/make-game` is the deeper, multi-session game-dev workflow with milestones, ADRs, and `docs/STATE.md` for projects that need to evolve over time.

© OpusGameLabs · MIT · PlayableIntelligence/game-creator

Similar skills

Everything for Game dev and 3D: Unity, Unreal, Godot, Blender →

From the same set27

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor