Helm is an AI-powered game development pipeline for Unity 6, built on Claude Code. It coordinates multiple AI agents to take a game idea from concept to working code.
Most wanted contributions:
- New genre skills -- each genre teaches Claude how to architect a specific type of game. Adding one directly improves output quality for every user building that genre.
- New skills -- system, gameplay, or third-party skills expand what the pipeline can handle.
- New hooks -- validation scripts that catch more mistakes before they ship.
- GUI improvements -- the Tauri 2 + Svelte 5 desktop app is young and needs work.
# Clone
git clone https://github.com/XeldarAlz/helm.git
cd helm
# Install frontend dependencies
npm install
# Run the GUI in dev mode (Svelte frontend only)
npm run dev
# Run the full Tauri app in dev mode (requires Rust toolchain)
npm run tauri dev
# Run frontend tests
npm test
# Run Rust backend tests
cd src-tauri && cargo testPrerequisites: Node.js 18+, Rust toolchain (for Tauri), Claude Code CLI (for testing skills/hooks/commands).
To test .claude/ configuration changes (skills, hooks, commands, agents), you need Claude Code installed. Run claude in the repo root -- it picks up .claude/settings.json automatically.
Skills live in .claude/skills/{category}/{skill-name}/SKILL.md. They are contextual knowledge files that Claude loads automatically when working on matching files.
Categories: core, systems, gameplay, genre, third-party, platform
Time estimate: 20-30 minutes for a system/gameplay skill, 45-60 minutes for a genre.
mkdir -p .claude/skills/{category}/{skill-name}
touch .claude/skills/{category}/{skill-name}/SKILL.mdEvery skill file starts with YAML frontmatter, followed by markdown content.
---
name: my-skill-name
description: "One-line summary -- what this skill covers and when it matters."
globs: ["**/MatchingPattern*.cs", "**/OtherPattern*.cs"]
---Frontmatter fields:
| Field | Required | Description |
|---|---|---|
name |
Yes | Kebab-case identifier, must match directory name |
description |
Yes | One-line summary in quotes. Be specific about what it covers. |
globs |
Yes* | File patterns that trigger auto-loading. Array of glob strings. |
alwaysApply |
No | Set to true for core skills that should load on every task. Omit or false otherwise. |
*Core skills use alwaysApply: true instead of globs.
Required sections:
- Overview -- what this skill is, when to use it, 2-3 sentences max.
- Key Patterns -- code examples showing the correct way to implement things. This is the most important section. Use complete, compilable C# snippets following the project's architecture rules (MVS pattern, VContainer DI, MessagePipe, UniTask).
- Common Pitfalls -- mistakes Claude (or developers) commonly make. "Do this, not that" format.
- Performance Notes -- allocation concerns, caching strategies, hot path considerations.
Optional but valuable: integration notes with other skills, Unity version caveats, platform-specific behavior.
Add your skill to the skills table in .claude/CLAUDE.md:
| **Category** (N) | skill-a, skill-b, your-new-skill | Yes/No |- System/gameplay skills: 150+ lines, 2-3 code examples minimum.
- Genre skills: 300+ lines, 3-4 full system templates. See Adding a New Genre.
- All code examples must follow the project rules in
.claude/rules/-- MVS separation,sealedby default,m_field prefix, VContainer injection, no coroutines, no singletons.
---
name: navmesh
description: "Unity NavMesh navigation -- agent setup, path queries, off-mesh links, dynamic obstacles, NavMeshSurface baking."
globs: ["**/Nav*.cs", "**/Navigation*.cs", "**/Pathfind*.cs"]
---
# NavMesh Navigation
## Overview
Unity's NavMesh system handles AI pathfinding...
## Key Patterns
### Agent Movement System (pure C#, injected via VContainer)
~~~csharp
public sealed class NavigationSystem : IDisposable
{
// ...
}
~~~
## Common Pitfalls
- **Off-mesh links silently fail** if...
- **NavMeshAgent.SetDestination allocates** on first call per frame...
## Performance Notes
- Cache `NavMeshPath` instances, reuse with `CalculatePath`...Genre skills live in .claude/skills/genre/{genre-name}/SKILL.md. They are the highest-impact contribution because they directly shape how Claude architects an entire game.
- Core loop architecture -- the fundamental game loop as a system diagram. What systems exist, how they interact, what messages they send.
- 3-4 complete system code templates -- real, compilable C# classes following MVS pattern. At minimum:
- The central gameplay system (e.g.,
MatchSystemfor match-3,WaveSystemfor tower defense) - The player-facing model (e.g.,
BoardModel,RunnerModel) - One supporting system (e.g.,
ComboSystem,SpawnSystem) - VContainer
LifetimeScopewiring all pieces together
- The central gameplay system (e.g.,
- Integration notes -- which other skills this genre commonly uses (e.g., "rpg" uses
state-machine,save-system,inventory-system). - Genre-specific pitfalls -- things that go wrong in this type of game specifically.
---
name: tower-defense
description: "Tower defense architecture -- wave spawning, path-following enemies, tower placement/targeting/upgrading, economy system, build phase vs combat phase state machine."
globs: ["**/Tower*.cs", "**/Wave*.cs", "**/Enemy*.cs", "**/Path*.cs", "**/TD*.cs"]
---Target length: 300+ lines. Look at existing genres in .claude/skills/genre/ for reference.
Hooks are bash scripts in .claude/hooks/ that run before or after Claude uses the Write/Edit tools. They enforce coding standards automatically.
| Exit Code | Meaning | Effect |
|---|---|---|
0 |
Allow / warn | The operation proceeds. Stdout is shown as a warning to Claude. |
2 |
Block | The operation is rejected. Claude must fix the issue before retrying. |
Any other exit code is treated as an error (hook malfunction), not a block.
Hooks receive JSON on stdin with the tool input (including file_path). They parse it with jq:
#!/usr/bin/env bash
set -euo pipefail
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Your validation logic here...
# To block:
echo "BLOCKED: reason here" >&2
exit 2
# To warn:
echo "WARNING: suggestion here"
exit 0Add your hook to .claude/settings.json under the appropriate section:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/your-hook.sh",
"timeout": 5000,
"statusMessage": "Running your check..."
}
]
}
]
}
}- PreToolUse hooks run before the tool executes. Use exit code
2to block. - PostToolUse hooks run after. They can warn but typically don't block (use exit
0). matcheris a regex against tool names.Edit|Writematches both.timeoutis in milliseconds.
# Simulate a Write tool call
echo '{"tool_name":"Write","tool_input":{"file_path":"Assets/Scripts/Player.cs","content":"..."}}' \
| bash .claude/hooks/your-hook.sh
echo "Exit code: $?"Commands are markdown prompt files in .claude/commands/. When a user types /command-name in Claude Code, the corresponding command-name.md is loaded as the agent's system prompt.
.claude/commands/{command-name}.md
The filename (minus .md) becomes the slash command name.
Commands are plain markdown. They typically include:
- Role definition -- who the agent is and what it does.
- Process steps -- numbered workflow the agent follows.
- Prerequisites -- what documents/files must exist before this command runs.
- Output format -- what the command produces (a document, code, etc.).
- References to agents/skills -- commands can instruct Claude to behave like a specific agent template.
Look at existing commands in .claude/commands/ for the established patterns. game-idea.md is a good example of a conversational command; architect.md shows a document-generation command.
Add your command to the commands list in .claude/CLAUDE.md.
Agent templates in .claude/agents/ define how the orchestrator's sub-agents behave. Each file is a system prompt for a specific role:
| Agent | Role |
|---|---|
coder.md |
Writes pure C# implementation code following MVS pattern |
tester.md |
Writes NUnit/Unity Test Framework tests |
reviewer.md |
Reviews code for rule violations, architecture issues |
unity-setup.md |
Sets up Unity scenes and prefabs via Unity MCP |
committer.md |
Splits completed work into logical commits |
- Agent templates must not contain XML documentation or comments (enforced by existing rules).
- Keep agents focused on their single responsibility.
- Reference rules from
.claude/rules/rather than duplicating them -- agents load rules automatically. - Test changes by running
/orchestrateor/build-gameon a small game idea and checking agent behavior.
The desktop app uses Tauri 2 (Rust backend) with a Svelte 5 + TypeScript frontend and Tailwind CSS 4.
src/
App.svelte -- root component
app.css -- global styles (Tailwind)
main.ts -- entry point
lib/ -- components, stores, utilities
Conventions:
- Svelte 5 runes (
$state,$derived,$effect) -- not Svelte 4 stores. - TypeScript strict mode.
- Tailwind CSS 4 utility classes for styling.
- Components in
src/lib/, organized by feature.
# Dev server (frontend only, hot reload)
npm run dev
# Type checking
npm run check
# Tests
npm test
# Watch mode tests
npm run test:watchsrc-tauri/src/
main.rs -- Tauri app entry
lib.rs -- library root
commands/ -- Tauri IPC command handlers
models/ -- data structures
parser/ -- document parsing
process/ -- subprocess management
state/ -- app state management
watcher/ -- file system watchers
cd src-tauri
# Run tests
cargo test
# Run with logging
RUST_LOG=debug cargo run
# Full app dev mode (frontend + backend)
cd .. && npm run tauri devTauri commands are the bridge between frontend and backend. They live in src-tauri/src/commands/ and are registered in lib.rs.
Follow the rules in .claude/rules/. Key points:
sealedby default on all classes.m_prefix for private fields,s_for static,k_for const/static readonly.[SerializeField] private-- never public fields for inspector exposure.- MVS pattern: Model (pure C#), View (MonoBehaviour), System (plain C# with VContainer).
- No coroutines (use UniTask), no singletons (use VContainer), no LINQ in hot paths.
- TypeScript strict mode, no
any. - Svelte 5 runes syntax.
- Prefer
constoverlet. - Name components in PascalCase, utilities in camelCase.
set -euo pipefailat the top.- Parse stdin JSON with
jq. - Exit
0for allow/warn,2for block. - Keep hooks fast (under 5 seconds).
feat/short-description -- new feature or skill
fix/short-description -- bug fix
docs/short-description -- documentation only
refactor/short-description -- code restructuring
Use Conventional Commits:
feat(skills): add tower-defense genre skill
fix(hooks): handle missing file_path in block-scene-edit
docs: update CLAUDE.md skills table
refactor(gui): extract pipeline status component
- Summary -- 1-3 bullet points on what changed and why.
- Test plan -- how you verified the change works. For skills: "Tested by running
/build-gamewith a [genre] game idea." For hooks: "Tested with simulated tool input JSON." For GUI: "Rannpm test, verified in dev mode." - Checklist:
- CLAUDE.md updated (if adding skills, commands, or hooks)
- Existing tests pass (
npm test,cargo test) - Hook exit codes follow conventions (0=warn, 2=block)
- Skill code examples follow
.claude/rules/standards
Use GitHub Issues with the appropriate template:
- Bug Report -- something is broken. Include: steps to reproduce, expected vs actual behavior, Claude Code version.
- Feature Request -- an idea for improvement. Include: use case, proposed solution.
- New Skill Request -- a skill you'd like to see added. Include: what it covers, which category, example use cases.
- New Genre Request -- a genre you'd like the pipeline to support. Include: genre description, core loop, reference games.
Open a discussion on GitHub or file an issue. For quick questions about project architecture, run /catch-up in Claude Code from the repo root -- it generates a comprehensive codebase guide.