summer-engine 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +59 -0
- package/.codex-plugin/plugin.json +38 -0
- package/.cursor-plugin/plugin.json +42 -0
- package/.mcp.json +8 -0
- package/.opencode/plugins/summer.js +49 -0
- package/CHANGELOG.md +67 -0
- package/README.md +13 -0
- package/dist/lib/skills-registry.d.ts +80 -0
- package/dist/lib/skills-registry.js +172 -0
- package/gemini-extension.json +21 -0
- package/hooks/hooks-cursor.json +21 -0
- package/hooks/hooks.json +31 -0
- package/hooks/pre-commit-doctor.sh +123 -0
- package/hooks/run-hook.cmd +23 -0
- package/hooks/session-start.sh +120 -0
- package/marketplace.json +24 -0
- package/package.json +13 -3
- package/skills/_meta/skill-test/SKILL.md +1 -1
- package/skills/_shared/summer-folder.md +44 -0
- package/skills/_tests/specs/art-direction.md +115 -0
- package/skills/_tests/specs/audio-direction.md +123 -0
- package/skills/_tests/specs/brainstorm-game.md +99 -0
- package/skills/_tests/specs/design-level.md +113 -0
- package/skills/_tests/specs/design-mechanic.md +112 -0
- package/skills/_tests/specs/design-npc.md +112 -0
- package/skills/_tests/specs/export-and-ship.md +114 -0
- package/skills/_tests/specs/fps-controller.md +5 -5
- package/skills/_tests/specs/peer-to-peer-multiplayer.md +99 -0
- package/skills/_tests/specs/setup-multiplayer.md +106 -0
- package/skills/_tests/specs/tune-performance.md +104 -0
- package/skills/_tests/specs/vfx.md +98 -0
- package/skills/ai-and-npcs/design-npc/SKILL.md +343 -0
- package/skills/asset-pipeline/asset-strategy/SKILL.md +8 -0
- package/skills/audio/audio-direction/SKILL.md +258 -0
- package/skills/catalog.yaml +82 -0
- package/skills/character-controllers/fps-controller/SKILL.md +27 -0
- package/skills/deployment/export-and-ship/SKILL.md +300 -0
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +265 -0
- package/skills/level-design/design-level/SKILL.md +266 -0
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +378 -0
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +328 -0
- package/skills/performance/tune-performance/SKILL.md +219 -0
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +20 -0
- package/skills/rendering-and-lighting/art-direction/SKILL.md +284 -0
- package/skills/scene-and-project/brainstorm-game/SKILL.md +210 -0
- package/skills/scene-and-project/make-game/SKILL.md +10 -0
- package/skills/scene-and-project/scene-composition/SKILL.md +8 -0
- package/skills/ui-and-ux/ui-basics/SKILL.md +28 -0
- package/skills/visual-effects/vfx/SKILL.md +280 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Summer Engine — Pre-commit doctor hook (OPT-IN)
|
|
3
|
+
#
|
|
4
|
+
# Event: PreToolUse (matcher: Bash, if: "Bash(git commit*)")
|
|
5
|
+
# Purpose: Run `summer doctor` before any git commit Claude is about to make.
|
|
6
|
+
# Block the commit on FAIL. Allow with warnings on WARN.
|
|
7
|
+
#
|
|
8
|
+
# Status: OPT-IN. Not registered in the Summer plugin manifest by default.
|
|
9
|
+
#
|
|
10
|
+
# To enable, add to ~/.claude/settings.json (or .claude/settings.json):
|
|
11
|
+
#
|
|
12
|
+
# {
|
|
13
|
+
# "hooks": {
|
|
14
|
+
# "PreToolUse": [
|
|
15
|
+
# {
|
|
16
|
+
# "matcher": "Bash",
|
|
17
|
+
# "hooks": [
|
|
18
|
+
# {
|
|
19
|
+
# "type": "command",
|
|
20
|
+
# "command": "${CLAUDE_PLUGIN_ROOT}/hooks/pre-commit-doctor.sh",
|
|
21
|
+
# "if": "Bash(git commit*)",
|
|
22
|
+
# "timeout": 15
|
|
23
|
+
# }
|
|
24
|
+
# ]
|
|
25
|
+
# }
|
|
26
|
+
# ]
|
|
27
|
+
# }
|
|
28
|
+
# }
|
|
29
|
+
#
|
|
30
|
+
# Then: chmod +x ${CLAUDE_PLUGIN_ROOT}/hooks/pre-commit-doctor.sh
|
|
31
|
+
#
|
|
32
|
+
# Input: JSON on stdin: { tool_name, tool_input: { command, ... }, ... }
|
|
33
|
+
# Output: On FAIL: stderr explanation, exit 2 (blocks commit).
|
|
34
|
+
# On WARN: stderr warnings, exit 0 (allows commit).
|
|
35
|
+
# On PASS or no `summer` CLI: silent, exit 0.
|
|
36
|
+
#
|
|
37
|
+
# Portability: bash 3.2+, POSIX-friendly. jq optional.
|
|
38
|
+
|
|
39
|
+
set +e
|
|
40
|
+
|
|
41
|
+
INPUT=$(cat)
|
|
42
|
+
|
|
43
|
+
# ---------- Parse the command ----------
|
|
44
|
+
COMMAND=""
|
|
45
|
+
if command -v jq >/dev/null 2>&1; then
|
|
46
|
+
COMMAND=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
47
|
+
fi
|
|
48
|
+
if [ -z "$COMMAND" ]; then
|
|
49
|
+
COMMAND=$(printf '%s' "$INPUT" \
|
|
50
|
+
| grep -oE '"command"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
|
51
|
+
| head -1 \
|
|
52
|
+
| sed 's/^"command"[[:space:]]*:[[:space:]]*"//;s/"$//')
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# ---------- Bail early if not a git commit ----------
|
|
56
|
+
if ! printf '%s' "$COMMAND" | grep -qE '^[[:space:]]*git[[:space:]]+commit'; then
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# ---------- Bail if `summer` CLI missing ----------
|
|
61
|
+
if ! command -v summer >/dev/null 2>&1; then
|
|
62
|
+
# Don't block — user may have installed via plugin only.
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# ---------- Run doctor ----------
|
|
67
|
+
DOCTOR_OUT=$(summer doctor --json 2>/dev/null)
|
|
68
|
+
if [ -z "$DOCTOR_OUT" ]; then
|
|
69
|
+
exit 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# ---------- Parse status ----------
|
|
73
|
+
HAS_FAIL=0
|
|
74
|
+
HAS_WARN=0
|
|
75
|
+
FAIL_MSGS=""
|
|
76
|
+
WARN_MSGS=""
|
|
77
|
+
|
|
78
|
+
if command -v jq >/dev/null 2>&1; then
|
|
79
|
+
FAIL_MSGS=$(printf '%s' "$DOCTOR_OUT" \
|
|
80
|
+
| jq -r '.checks[]? | select(.status == "FAIL") | " - " + (.name // "?") + ": " + (.message // "")' 2>/dev/null)
|
|
81
|
+
WARN_MSGS=$(printf '%s' "$DOCTOR_OUT" \
|
|
82
|
+
| jq -r '.checks[]? | select(.status == "WARN") | " - " + (.name // "?") + ": " + (.message // "")' 2>/dev/null)
|
|
83
|
+
[ -n "$FAIL_MSGS" ] && HAS_FAIL=1
|
|
84
|
+
[ -n "$WARN_MSGS" ] && HAS_WARN=1
|
|
85
|
+
else
|
|
86
|
+
# Fallback: substring sniffing
|
|
87
|
+
if printf '%s' "$DOCTOR_OUT" | grep -q '"status"[[:space:]]*:[[:space:]]*"FAIL"'; then
|
|
88
|
+
HAS_FAIL=1
|
|
89
|
+
FAIL_MSGS=$(printf '%s' "$DOCTOR_OUT" \
|
|
90
|
+
| grep -oE '"status"[[:space:]]*:[[:space:]]*"FAIL"[^}]*"message"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
|
91
|
+
| sed -E 's/.*"message"[[:space:]]*:[[:space:]]*"([^"]*)"/ - \1/')
|
|
92
|
+
fi
|
|
93
|
+
if printf '%s' "$DOCTOR_OUT" | grep -q '"status"[[:space:]]*:[[:space:]]*"WARN"'; then
|
|
94
|
+
HAS_WARN=1
|
|
95
|
+
WARN_MSGS=$(printf '%s' "$DOCTOR_OUT" \
|
|
96
|
+
| grep -oE '"status"[[:space:]]*:[[:space:]]*"WARN"[^}]*"message"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
|
97
|
+
| sed -E 's/.*"message"[[:space:]]*:[[:space:]]*"([^"]*)"/ - \1/')
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# ---------- FAIL: block ----------
|
|
102
|
+
if [ "$HAS_FAIL" -eq 1 ]; then
|
|
103
|
+
{
|
|
104
|
+
echo "=== Summer doctor: FAIL — commit blocked ==="
|
|
105
|
+
echo "$FAIL_MSGS"
|
|
106
|
+
echo ""
|
|
107
|
+
echo "Fix the failures above, or run: summer doctor"
|
|
108
|
+
echo "To bypass once: disable the pre-commit-doctor hook in settings.json."
|
|
109
|
+
echo "============================================"
|
|
110
|
+
} >&2
|
|
111
|
+
exit 2
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# ---------- WARN: allow with notice ----------
|
|
115
|
+
if [ "$HAS_WARN" -eq 1 ]; then
|
|
116
|
+
{
|
|
117
|
+
echo "=== Summer doctor: WARN — commit allowed ==="
|
|
118
|
+
echo "$WARN_MSGS"
|
|
119
|
+
echo "============================================"
|
|
120
|
+
} >&2
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
exit 0
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Cross-platform hook dispatcher.
|
|
3
|
+
# Usage: run-hook.cmd <hook-name>
|
|
4
|
+
# Reads stdin, forwards to <plugin-root>/hooks/<hook-name>.sh
|
|
5
|
+
# On Windows, Claude Code / Cursor / Codex invoke this via Git-Bash.
|
|
6
|
+
|
|
7
|
+
HOOK_NAME="$1"
|
|
8
|
+
shift || true
|
|
9
|
+
|
|
10
|
+
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
HOOK_SCRIPT="$HOOK_DIR/$HOOK_NAME.sh"
|
|
12
|
+
|
|
13
|
+
if [ ! -f "$HOOK_SCRIPT" ]; then
|
|
14
|
+
# Missing hook = no-op (don't break the host).
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
if [ ! -x "$HOOK_SCRIPT" ]; then
|
|
19
|
+
# Not executable yet (likely fresh checkout). Fall back to bash invocation.
|
|
20
|
+
exec bash "$HOOK_SCRIPT" "$@"
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
exec "$HOOK_SCRIPT" "$@"
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Summer Engine — SessionStart hook
|
|
3
|
+
#
|
|
4
|
+
# Event: SessionStart (matcher: startup|clear|compact)
|
|
5
|
+
# Purpose: Orient Claude on every fresh Summer-enabled session.
|
|
6
|
+
# Detect Godot project + GameSoul + doctor health, surface a one-line
|
|
7
|
+
# Bob-style greeting as additional context.
|
|
8
|
+
#
|
|
9
|
+
# Input: JSON on stdin with { session_id, source, model, cwd, ... }
|
|
10
|
+
# Common Claude Code env vars: $CLAUDE_PROJECT_DIR, $CLAUDE_PLUGIN_ROOT
|
|
11
|
+
# Output: JSON on stdout with hookSpecificOutput.additionalContext
|
|
12
|
+
# (also emits Cursor / Copilot CLI variants based on host env vars)
|
|
13
|
+
# Exit: Always 0 — never block session start.
|
|
14
|
+
#
|
|
15
|
+
# Portability: bash 3.2+ (macOS default), POSIX-friendly, works on Git Bash.
|
|
16
|
+
# Uses `grep -E` not `grep -P`. Falls back gracefully when jq
|
|
17
|
+
# and `summer` are missing.
|
|
18
|
+
|
|
19
|
+
set +e # Hooks must never kill the session.
|
|
20
|
+
|
|
21
|
+
# ---------- Resolve project dir ----------
|
|
22
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
23
|
+
|
|
24
|
+
# ---------- Build the orientation lines (max 3) ----------
|
|
25
|
+
LINES=()
|
|
26
|
+
|
|
27
|
+
# Line 1: Summer ready + skill count
|
|
28
|
+
SKILL_COUNT=""
|
|
29
|
+
if command -v summer >/dev/null 2>&1; then
|
|
30
|
+
# `summer skills count` is best-effort; ignore failure
|
|
31
|
+
SKILL_COUNT=$(summer skills count 2>/dev/null | grep -oE '[0-9]+' | head -1)
|
|
32
|
+
fi
|
|
33
|
+
if [ -n "$SKILL_COUNT" ]; then
|
|
34
|
+
LINES+=("Summer ready. ${SKILL_COUNT} skills.")
|
|
35
|
+
else
|
|
36
|
+
LINES+=("Summer ready.")
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Line 2: Godot project + GameSoul one-liner (only if project.godot exists)
|
|
40
|
+
if [ -f "${PROJECT_DIR}/project.godot" ]; then
|
|
41
|
+
PROJECT_NAME=$(grep -E '^config/name=' "${PROJECT_DIR}/project.godot" 2>/dev/null \
|
|
42
|
+
| head -1 | sed 's/^config\/name=//;s/^"//;s/"$//')
|
|
43
|
+
[ -z "$PROJECT_NAME" ] && PROJECT_NAME=$(basename "$PROJECT_DIR")
|
|
44
|
+
|
|
45
|
+
SOUL_FILE="${PROJECT_DIR}/.summer/GameSoul.md"
|
|
46
|
+
if [ -f "$SOUL_FILE" ]; then
|
|
47
|
+
# First non-empty, non-heading paragraph (one line)
|
|
48
|
+
SOUL_LINE=$(awk 'BEGIN{p=""} /^[^#[:space:]]/ && NF>0 {p=$0; exit} END{print p}' \
|
|
49
|
+
"$SOUL_FILE" 2>/dev/null | cut -c1-120)
|
|
50
|
+
if [ -n "$SOUL_LINE" ]; then
|
|
51
|
+
LINES+=("Godot project: ${PROJECT_NAME}. GameSoul: ${SOUL_LINE}")
|
|
52
|
+
else
|
|
53
|
+
LINES+=("Godot project: ${PROJECT_NAME}.")
|
|
54
|
+
fi
|
|
55
|
+
else
|
|
56
|
+
LINES+=("Godot project: ${PROJECT_NAME}.")
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Line 3: doctor FAIL one-liner (only on FAIL — silent on PASS/WARN)
|
|
61
|
+
if command -v summer >/dev/null 2>&1; then
|
|
62
|
+
DOCTOR_OUT=$(summer doctor --json 2>/dev/null)
|
|
63
|
+
if [ -n "$DOCTOR_OUT" ]; then
|
|
64
|
+
FAIL_REASON=""
|
|
65
|
+
if command -v jq >/dev/null 2>&1; then
|
|
66
|
+
FAIL_REASON=$(printf '%s' "$DOCTOR_OUT" \
|
|
67
|
+
| jq -r 'first(.checks[]? | select(.status == "FAIL") | .message) // empty' 2>/dev/null)
|
|
68
|
+
else
|
|
69
|
+
# Crude fallback: first "message" near a "FAIL"
|
|
70
|
+
FAIL_REASON=$(printf '%s' "$DOCTOR_OUT" \
|
|
71
|
+
| grep -oE '"status"[[:space:]]*:[[:space:]]*"FAIL"[^}]*"message"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
|
72
|
+
| head -1 \
|
|
73
|
+
| grep -oE '"message"[[:space:]]*:[[:space:]]*"[^"]*"' \
|
|
74
|
+
| sed 's/.*"message"[[:space:]]*:[[:space:]]*"//;s/"$//')
|
|
75
|
+
fi
|
|
76
|
+
if [ -n "$FAIL_REASON" ]; then
|
|
77
|
+
LINES+=("Summer setup needs attention: ${FAIL_REASON}. Run: summer doctor")
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# ---------- Compose context ----------
|
|
83
|
+
CONTEXT=""
|
|
84
|
+
for line in "${LINES[@]}"; do
|
|
85
|
+
if [ -z "$CONTEXT" ]; then CONTEXT="$line"
|
|
86
|
+
else CONTEXT="${CONTEXT}"$'\n'"$line"
|
|
87
|
+
fi
|
|
88
|
+
done
|
|
89
|
+
|
|
90
|
+
# Bail with empty JSON if we somehow have no lines
|
|
91
|
+
if [ -z "$CONTEXT" ]; then
|
|
92
|
+
printf '{}\n'
|
|
93
|
+
exit 0
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# ---------- JSON-escape for embedding ----------
|
|
97
|
+
escape_for_json() {
|
|
98
|
+
local s="$1"
|
|
99
|
+
s="${s//\\/\\\\}"
|
|
100
|
+
s="${s//\"/\\\"}"
|
|
101
|
+
s="${s//$'\n'/\\n}"
|
|
102
|
+
s="${s//$'\r'/\\r}"
|
|
103
|
+
s="${s//$'\t'/\\t}"
|
|
104
|
+
printf '%s' "$s"
|
|
105
|
+
}
|
|
106
|
+
CONTEXT_ESC=$(escape_for_json "$CONTEXT")
|
|
107
|
+
|
|
108
|
+
# ---------- Emit per-host shape ----------
|
|
109
|
+
# Cursor: top-level additional_context (snake_case)
|
|
110
|
+
# Claude Code: nested hookSpecificOutput.additionalContext
|
|
111
|
+
# Copilot CLI / SDK standard: top-level additionalContext (camelCase)
|
|
112
|
+
if [ -n "${CURSOR_PLUGIN_ROOT:-}" ]; then
|
|
113
|
+
printf '{"additional_context":"%s"}\n' "$CONTEXT_ESC"
|
|
114
|
+
elif [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -z "${COPILOT_CLI:-}" ]; then
|
|
115
|
+
printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"%s"}}\n' "$CONTEXT_ESC"
|
|
116
|
+
else
|
|
117
|
+
printf '{"additionalContext":"%s"}\n' "$CONTEXT_ESC"
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
exit 0
|
package/marketplace.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
|
|
3
|
+
"name": "summer",
|
|
4
|
+
"description": "Summer Engine plugins for Claude Code",
|
|
5
|
+
"owner": { "name": "Summer Engine", "email": "founders@summerengine.com" },
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "summer",
|
|
9
|
+
"source": "./",
|
|
10
|
+
"version": "1.4.0",
|
|
11
|
+
"description": "AI game-dev studio: 19 skills under summer: namespace, MCP bridge, session-start + pre-commit hooks.",
|
|
12
|
+
"author": { "name": "Summer Engine", "email": "founders@summerengine.com" },
|
|
13
|
+
"category": "game-development",
|
|
14
|
+
"tags": ["game-dev", "godot", "ai-game-engine"],
|
|
15
|
+
"keywords": ["game-dev", "godot", "ai-game-engine", "skills"],
|
|
16
|
+
"brandColor": "#FF8F17",
|
|
17
|
+
"capabilities": ["Interactive", "Read", "Write"],
|
|
18
|
+
"defaultPrompt": [
|
|
19
|
+
"I want to make a game.",
|
|
20
|
+
"/summer:brainstorm-game"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "summer-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "CLI and MCP tools for Summer Engine — the AI-native game engine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"game-engine",
|
|
@@ -25,7 +25,17 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist/",
|
|
27
27
|
"skills/",
|
|
28
|
-
"
|
|
28
|
+
"hooks/",
|
|
29
|
+
".claude-plugin/",
|
|
30
|
+
".cursor-plugin/",
|
|
31
|
+
".codex-plugin/",
|
|
32
|
+
".opencode/",
|
|
33
|
+
"gemini-extension.json",
|
|
34
|
+
"marketplace.json",
|
|
35
|
+
".mcp.json",
|
|
36
|
+
"README.md",
|
|
37
|
+
"LICENSE",
|
|
38
|
+
"CHANGELOG.md"
|
|
29
39
|
],
|
|
30
40
|
"scripts": {
|
|
31
41
|
"build": "tsc",
|
|
@@ -33,7 +43,7 @@
|
|
|
33
43
|
"summer": "node dist/bin/summer.js",
|
|
34
44
|
"test": "vitest run",
|
|
35
45
|
"test:watch": "vitest",
|
|
36
|
-
"prepublishOnly": "npm run build"
|
|
46
|
+
"prepublishOnly": "npm run build && npm test"
|
|
37
47
|
},
|
|
38
48
|
"engines": {
|
|
39
49
|
"node": ">=18"
|
|
@@ -23,7 +23,7 @@ For a single skill at `skills/<category>/<name>/`, run these checks:
|
|
|
23
23
|
4. **Collaborative protocol.** If the skill triggers user-visible writes, body must contain at least one of: `May I`, `I'm about to`, `Continue?`, `OK?`, `Proceed?`. Skills that only inspect/read are exempt.
|
|
24
24
|
5. **Template-id resolved.** If the skill's frontmatter declares `template-id: <id>`, that id must exist in `_shared/template-registry.md`.
|
|
25
25
|
6. **Tests/spec.md present.** Every skill in a non-`_meta` category must have `tests/spec.md` with at least one `## Case` heading.
|
|
26
|
-
7. **
|
|
26
|
+
7. **Relative links resolve.** Every `](../_shared/...)`, `](../../_shared/...)`, `](./references/...)`, and `](./examples/...)` link must point at an existing file (FAIL if broken). Forward references in `## See also` to other SKILL.md files (e.g., `[design-mechanic](../../gameplay-mechanics/design-mechanic/SKILL.md)`) are allowed to dangle and only WARN if the target is missing — the catalog evolves and skills should be free to point at planned skills.
|
|
27
27
|
|
|
28
28
|
Output:
|
|
29
29
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# `.summer/` Folder Convention
|
|
2
|
+
|
|
3
|
+
> The canonical layout for project-scoped Summer state. Read this if you're authoring a skill that writes durable design output (briefs, art bible, level docs).
|
|
4
|
+
|
|
5
|
+
## Files at the root of `.summer/`
|
|
6
|
+
|
|
7
|
+
- `GameSoul.md` — the project brief. Created by `/summer:brainstorm-game`. Contains: name, one-sentence pitch, core loop, 3 mechanics max, art direction summary, scope. Updated whenever the game's high-level direction changes.
|
|
8
|
+
- `art-bible.md` — visual style reference. Created by `/summer:art-direction`. Contains: palette (6–15 hex codes), mood adjectives, lighting plan, post-processing notes, do/don't list, references.
|
|
9
|
+
- `audio-bible.md` — sonic identity. Created by `/summer:audio-direction`. Contains: music style + tempo range, SFX vocabulary (8 classes), dynamic music FSM, bus layout reference.
|
|
10
|
+
|
|
11
|
+
## Subdirectories
|
|
12
|
+
|
|
13
|
+
- `mechanics/<mechanic-name>.md` — one file per designed mechanic (e.g., `double-jump.md`, `parry.md`). Created by `/summer:design-mechanic`. Contains: input → response → feedback → failure modes → tunable parameters.
|
|
14
|
+
- `levels/<level-name>.md` — one file per designed level. Created by `/summer:design-level`. Contains: teaching goal, pacing curve (5 beats), encounters, secrets, reward gating.
|
|
15
|
+
- `npcs/<npc-name>.md` — one file per designed NPC. Created by `/summer:design-npc`. Contains: archetype, perception model, decision tree, escalation, defeat sequence.
|
|
16
|
+
|
|
17
|
+
## Conventions
|
|
18
|
+
|
|
19
|
+
- All filenames are lowercase, hyphens not underscores.
|
|
20
|
+
- Skills MUST ask "May I write/update `.summer/<file>`?" before any write to this folder.
|
|
21
|
+
- Skills MAY read existing files in `.summer/` without permission to ground their output in prior decisions.
|
|
22
|
+
- The folder lives in the project root (sibling to `project.godot`).
|
|
23
|
+
- Add `.summer/` to `.gitignore` if the user prefers it private; default is to commit it (game design lives with the game).
|
|
24
|
+
|
|
25
|
+
## Skills that write here
|
|
26
|
+
|
|
27
|
+
| Skill | Writes |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `/summer:brainstorm-game` | `.summer/GameSoul.md` |
|
|
30
|
+
| `/summer:art-direction` | `.summer/art-bible.md` |
|
|
31
|
+
| `/summer:audio-direction` | `.summer/audio-bible.md` |
|
|
32
|
+
| `/summer:design-mechanic` | `.summer/mechanics/<name>.md` |
|
|
33
|
+
| `/summer:design-level` | `.summer/levels/<name>.md` |
|
|
34
|
+
| `/summer:design-npc` | `.summer/npcs/<name>.md` |
|
|
35
|
+
| `/summer:debug` | does NOT write here |
|
|
36
|
+
| `/summer:play` | does NOT write here |
|
|
37
|
+
| `/summer:vfx` | does NOT write here (VFX edits scenes/scripts) |
|
|
38
|
+
| `/summer:tune-performance` | optionally writes `.summer/perf-notes.md` if user requests |
|
|
39
|
+
| `/summer:setup-multiplayer` | optionally writes `.summer/multiplayer-architecture.md` |
|
|
40
|
+
| `/summer:export-and-ship` | does NOT write here (writes export configs in `project.godot`) |
|
|
41
|
+
|
|
42
|
+
## Linter check (future)
|
|
43
|
+
|
|
44
|
+
Once `_meta/skill-test` gains an executable mode, it should validate that any skill writing to `.summer/` is documented in the table above.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Skill Spec: /art-direction
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, main scene with `World/WorldEnvironment` and `World/Sun` (DirectionalLight3D) present.
|
|
6
|
+
- `.summer/GameSoul.md` exists; brief: "Cozy farming sim, vertical slice scope."
|
|
7
|
+
- No `.summer/art-bible.md` yet.
|
|
8
|
+
- Summer MCP available.
|
|
9
|
+
|
|
10
|
+
## Case 1: Happy Path — define art direction for cozy farming sim
|
|
11
|
+
|
|
12
|
+
**Input:** "Help me define the art direction. References: Stardew Valley and Sable."
|
|
13
|
+
|
|
14
|
+
**Expected MCP tool sequence (in order):**
|
|
15
|
+
|
|
16
|
+
1. `Read .summer/GameSoul.md` — anchor
|
|
17
|
+
2. (Skill notes: brief says "cozy", which forbids harsh contrast / saturated reds)
|
|
18
|
+
3. (Skill walks: technique pick → palette (6-15 hex codes) → mood adjectives → lighting plan → post-processing rules → do/don't list)
|
|
19
|
+
4. (Skill shows the bible inline)
|
|
20
|
+
5. (Skill asks: "May I update `project.godot`'s default clear color to the palette primary, and enable MSAA 2x?")
|
|
21
|
+
6. `summer_project_setting(key="rendering/environment/defaults/default_clear_color", value="Color(...)")`
|
|
22
|
+
7. `summer_project_setting(key="rendering/anti_aliasing/quality/msaa_3d", value="2")`
|
|
23
|
+
8. (Skill asks: "May I dial in the WorldEnvironment + Sun to the lighting plan?")
|
|
24
|
+
9. `summer_inspect_node(path="./World/WorldEnvironment")`
|
|
25
|
+
10. `summer_set_prop(...)` — adjustments + tonemap per the plan
|
|
26
|
+
11. `summer_set_prop(path="./World/Sun", key="light_color", value="Color(...)")`
|
|
27
|
+
12. (Skill asks: "May I create `.summer/art-bible.md` with this bible?")
|
|
28
|
+
13. `Write .summer/art-bible.md`
|
|
29
|
+
|
|
30
|
+
**Assertions:**
|
|
31
|
+
|
|
32
|
+
- [ ] Skill reads `.summer/GameSoul.md` to anchor.
|
|
33
|
+
- [ ] Skill enforces 2+ references — does not proceed with single reference.
|
|
34
|
+
- [ ] Skill picks ONE rendering technique (does not allow blending without naming the conflict).
|
|
35
|
+
- [ ] Palette has 6-15 hex codes; uses off-white (e.g., #f4ecdf) and off-black (e.g., #1f1a16) — flags pure #ffffff or #000000 if user pitches them.
|
|
36
|
+
- [ ] Mood adjectives are concrete (e.g., "soft, hand-warmed, golden-hour"), not vague ("cool, atmospheric").
|
|
37
|
+
- [ ] Lighting plan names DirectionalLight3D color, energy, angle; sky colors; ambient; never-rules.
|
|
38
|
+
- [ ] Post-processing has explicit ON/OFF/value calls per item (Glow, SDFGI, SSAO, SSR, Tonemap, Vignette, Chromatic aberration, Film grain) — NOT a list of options.
|
|
39
|
+
- [ ] DO and DON'T lists each have at least 5 specific, enforceable rules.
|
|
40
|
+
- [ ] DON'T list explicitly forbids chromatic aberration, motion blur, lens flare unless mood justifies them.
|
|
41
|
+
- [ ] Skill asks "May I ..." before any `summer_project_setting` or `summer_set_prop` call.
|
|
42
|
+
- [ ] Skill writes `.summer/art-bible.md` only after asking.
|
|
43
|
+
- [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (silent-fail trap).
|
|
44
|
+
- [ ] Skill ends with routing to `/summer:audio-direction` or similar.
|
|
45
|
+
|
|
46
|
+
## Case 2: Failure Path — mixed-technique pitch
|
|
47
|
+
|
|
48
|
+
**Fixture:** Same as Case 1.
|
|
49
|
+
|
|
50
|
+
**Input:** "I want PBR realistic characters in a toon-shaded world."
|
|
51
|
+
|
|
52
|
+
**Expected behavior:**
|
|
53
|
+
|
|
54
|
+
- Skill identifies the conflict explicitly: "Toon characters in a PBR world fight. The lighting that makes PBR read realistic crushes toon shading; the flat shading that makes toon read clean strips PBR's value."
|
|
55
|
+
- Skill offers a hierarchy: "(a) PBR with toon outlines (one technique), (b) full-toon with PBR-feeling fabric (one technique), (c) accept the conflict and pick which side wins on which assets."
|
|
56
|
+
- Skill does NOT silently pick or design two parallel pipelines.
|
|
57
|
+
|
|
58
|
+
**Assertions:**
|
|
59
|
+
|
|
60
|
+
- [ ] Skill names the technique conflict out loud.
|
|
61
|
+
- [ ] Skill explains *why* the techniques fight (lighting interaction).
|
|
62
|
+
- [ ] Skill forces the user to pick one primary technique.
|
|
63
|
+
- [ ] No bible written until the technique is locked.
|
|
64
|
+
|
|
65
|
+
## Case 3: Edge Case — user pitches pure white + pure black palette
|
|
66
|
+
|
|
67
|
+
**Fixture:** Same as Case 1.
|
|
68
|
+
|
|
69
|
+
**Input:** "Black-and-white only, super high contrast. Like Limbo."
|
|
70
|
+
|
|
71
|
+
**Expected behavior:**
|
|
72
|
+
|
|
73
|
+
- Skill recognizes the intent (high-contrast monochrome) but flags pure values: "Limbo isn't actually pure black — it's #0a0a0a to #f0f0f0 with subtle warm tint. Pure #000 + #fff makes UI text vibrate and reads as unintentional."
|
|
74
|
+
- Skill offers a near-monochrome palette: e.g., #0a0a0a, #2a2a2a, #6e6e6e, #c0c0c0, #f0f0f0 with one accent color (often warm) reserved for a single mechanic-tied use.
|
|
75
|
+
- Skill writes the bible with off-pure values and documents the single-accent rule in the DO list.
|
|
76
|
+
|
|
77
|
+
**Assertions:**
|
|
78
|
+
|
|
79
|
+
- [ ] Skill flags pure #000 / #fff as a red flag and corrects to off-pure values.
|
|
80
|
+
- [ ] Bible includes at least one accent color reserved for mechanic-tied use.
|
|
81
|
+
- [ ] Skill explains *why* (UI vibration, "looks unintentional") not just "use these values".
|
|
82
|
+
|
|
83
|
+
## Case 4: No Summer MCP — file-edit fallback
|
|
84
|
+
|
|
85
|
+
**Fixture:** Same as Case 1, but Summer MCP is unavailable.
|
|
86
|
+
|
|
87
|
+
**Input:** "Define the art direction for my farming sim."
|
|
88
|
+
|
|
89
|
+
**Expected behavior:**
|
|
90
|
+
|
|
91
|
+
- Skill detects no MCP.
|
|
92
|
+
- Walks the design beats normally.
|
|
93
|
+
- Instead of `summer_project_setting`, prints the `project.godot` snippet for the user to paste:
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
[rendering]
|
|
97
|
+
environment/defaults/default_clear_color=Color(0.227, 0.290, 0.227, 1)
|
|
98
|
+
anti_aliasing/quality/msaa_3d=2
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- Instead of `summer_set_prop` on WorldEnvironment, prints the `.tscn` snippet for the user to paste into the main scene.
|
|
102
|
+
- Still writes `.summer/art-bible.md` via host `Write`.
|
|
103
|
+
- Asks "May I write ..." before each file write.
|
|
104
|
+
|
|
105
|
+
**Assertions:**
|
|
106
|
+
|
|
107
|
+
- [ ] Skill identifies that MCP is unavailable; does not blindly call `summer_*`.
|
|
108
|
+
- [ ] Generated `project.godot` snippet uses correct INI section format.
|
|
109
|
+
- [ ] Generated `.tscn` snippet for WorldEnvironment is parseable Godot 4.
|
|
110
|
+
- [ ] Skill still writes `.summer/art-bible.md`.
|
|
111
|
+
- [ ] Skill still asks "May I write ..." before each write.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
This spec runs via `/skill-test art-direction spec` (see `_meta/skill-test/SKILL.md`).
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Skill Spec: /audio-direction
|
|
2
|
+
|
|
3
|
+
## Fixture
|
|
4
|
+
|
|
5
|
+
- Godot 4.5 / Summer Engine project, default audio bus layout (Master only).
|
|
6
|
+
- `.summer/GameSoul.md` exists; brief: "Cozy farming sim, vertical slice scope."
|
|
7
|
+
- `.summer/art-bible.md` exists; mood: "soft, hand-warmed, golden-hour, painterly".
|
|
8
|
+
- No `.summer/audio-bible.md` yet.
|
|
9
|
+
- No `audio/` folder yet.
|
|
10
|
+
- Summer MCP available.
|
|
11
|
+
|
|
12
|
+
## Case 1: Happy Path — define audio direction for cozy farming sim
|
|
13
|
+
|
|
14
|
+
**Input:** "Define the audio direction. References: Stardew Valley OST, Studio Ghibli scores, and Outer Wilds. Acoustic, organic SFX."
|
|
15
|
+
|
|
16
|
+
**Expected MCP tool sequence (in order):**
|
|
17
|
+
|
|
18
|
+
1. `Read .summer/GameSoul.md` — anchor to brief
|
|
19
|
+
2. `Read .summer/art-bible.md` — anchor to visual mood
|
|
20
|
+
3. (Skill notes the rhyme: "soft, hand-warmed, golden-hour" + acoustic references = acoustic / folk style as primary)
|
|
21
|
+
4. (Skill walks: music style → tempo + key → SFX vocabulary (8 classes) → dynamic music plan with state machine → spatial + mix rules)
|
|
22
|
+
5. (Skill shows the bible inline)
|
|
23
|
+
6. (Skill asks: "May I create `audio/default_bus_layout.tres` with these buses: Master / Music / SFX / UI / Voice / Ambient / Reverb_Small / Reverb_Large / Reverb_Outdoor?")
|
|
24
|
+
7. `Write audio/default_bus_layout.tres`
|
|
25
|
+
8. `summer_project_setting(key="audio/buses/default_bus_layout", value="res://audio/default_bus_layout.tres")`
|
|
26
|
+
9. (Skill asks: "May I create `.summer/audio-bible.md` with this bible?")
|
|
27
|
+
10. `Write .summer/audio-bible.md`
|
|
28
|
+
11. (Skill optionally asks: "May I generate first-pass SFX seeds for UI, pickup, damage?")
|
|
29
|
+
12. (On yes) `summer_generate_audio(prompt="soft woody UI click, 80ms, no reverb", duration=0.1)` etc.
|
|
30
|
+
|
|
31
|
+
**Assertions:**
|
|
32
|
+
|
|
33
|
+
- [ ] Skill reads BOTH `.summer/GameSoul.md` AND `.summer/art-bible.md` to anchor.
|
|
34
|
+
- [ ] Skill enforces 3+ references — does not proceed with one or two.
|
|
35
|
+
- [ ] Skill picks ONE primary music style; if user pitches multiple, names the conflict.
|
|
36
|
+
- [ ] Music section has explicit tempo range (BPM), key center, time signature — not "varies".
|
|
37
|
+
- [ ] SFX vocabulary has 8 classes, each with character + examples + a DON'T rule.
|
|
38
|
+
- [ ] DON'T rules include things like "no pure sine ding for pickup" and "no same footstep for all surfaces".
|
|
39
|
+
- [ ] Dynamic music plan picks ONE model (layered / vertical / horizontal / procedural) — not a list.
|
|
40
|
+
- [ ] Dynamic music plan defines a state machine with named states + transitions + crossfade times.
|
|
41
|
+
- [ ] Spatial + mix section has concrete dB values, attenuation curve, max distance, master ceiling -1 dBTP.
|
|
42
|
+
- [ ] Mix defaults to SFX 0 dB / Music -8 dB / UI -3 dB (SFX loudest).
|
|
43
|
+
- [ ] Bus layout has at least Music, SFX, UI, Voice, Ambient + 1+ Reverb send buses.
|
|
44
|
+
- [ ] Skill asks "May I ..." before any `Write`, `summer_project_setting`, or `summer_generate_audio` call.
|
|
45
|
+
- [ ] Skill writes `.summer/audio-bible.md` only after asking.
|
|
46
|
+
- [ ] Skill never calls `summer_set_resource_property` on an inline sub_resource (silent-fail trap).
|
|
47
|
+
- [ ] Skill ends with routing to `/summer:design-mechanic` or implementation skill.
|
|
48
|
+
|
|
49
|
+
## Case 2: Failure Path — references contradict the brief
|
|
50
|
+
|
|
51
|
+
**Fixture:** Same as Case 1, but brief says "horror walking sim".
|
|
52
|
+
|
|
53
|
+
**Input:** "References: Mario 64 OST, A Hat in Time, Banjo-Kazooie. Bouncy chiptune."
|
|
54
|
+
|
|
55
|
+
**Expected behavior:**
|
|
56
|
+
|
|
57
|
+
- Skill identifies the conflict: "Brief says horror; references are bright N64 platformer scores. Those want opposite shapes — horror wants ambient drone or industrial; bouncy chiptune undercuts dread."
|
|
58
|
+
- Skill asks the user to resolve: "(a) keep horror brief, change references to ambient/industrial, (b) keep bouncy references, change brief away from horror, or (c) intentional juxtaposition (rare; works in 1 in 50 games — Undertale, Buckshot Roulette)."
|
|
59
|
+
- Skill does NOT silently pick or design a "horror chiptune" hybrid without flagging the friction.
|
|
60
|
+
|
|
61
|
+
**Assertions:**
|
|
62
|
+
|
|
63
|
+
- [ ] Skill names the brief vs. references conflict explicitly.
|
|
64
|
+
- [ ] Skill explains *why* the shapes oppose.
|
|
65
|
+
- [ ] Skill offers (c) intentional juxtaposition as a valid but rare path.
|
|
66
|
+
- [ ] No bible written until the user resolves.
|
|
67
|
+
|
|
68
|
+
## Case 3: Edge Case — user wants no music
|
|
69
|
+
|
|
70
|
+
**Fixture:** Same as Case 1.
|
|
71
|
+
|
|
72
|
+
**Input:** "Reference: Inside, Limbo. No music — just diegetic sound and ambience."
|
|
73
|
+
|
|
74
|
+
**Expected behavior:**
|
|
75
|
+
|
|
76
|
+
- Skill accepts "no music" as a valid direction (those references genuinely use it).
|
|
77
|
+
- Skill replaces the dynamic music plan section with a "Diegetic-only ambience plan":
|
|
78
|
+
- Named ambience layers (room tone / wind / distant water / heart-rate-tied sub-bass when tense)
|
|
79
|
+
- Rules for when sub-bass enters (proximity to threat) and exits
|
|
80
|
+
- SFX still gets all 8 vocabulary classes (with extra weight on the "Ambient layer" class)
|
|
81
|
+
- Skill keeps the bus layout but removes the Music bus or marks it "reserved (unused in v1)".
|
|
82
|
+
- Skill notes the trade-off: "Diegetic-only is harder to make feel paced — every level needs an ambient arc that does what music would normally do."
|
|
83
|
+
|
|
84
|
+
**Assertions:**
|
|
85
|
+
|
|
86
|
+
- [ ] Skill does NOT force a music style on a no-music game.
|
|
87
|
+
- [ ] Bible has a Diegetic / ambience plan section instead of (or supplementing) Dynamic music plan.
|
|
88
|
+
- [ ] Bus layout reflects the choice (no Music bus or marked reserved).
|
|
89
|
+
- [ ] Skill flags the trade-off: pacing is now ambience's job.
|
|
90
|
+
|
|
91
|
+
## Case 4: No Summer MCP — file-edit fallback
|
|
92
|
+
|
|
93
|
+
**Fixture:** Same as Case 1, but Summer MCP is unavailable.
|
|
94
|
+
|
|
95
|
+
**Input:** "Define the audio direction for my cozy farming sim."
|
|
96
|
+
|
|
97
|
+
**Expected behavior:**
|
|
98
|
+
|
|
99
|
+
- Skill detects no MCP.
|
|
100
|
+
- Walks the design beats normally.
|
|
101
|
+
- Instead of `summer_project_setting`, prints the `project.godot` snippet for the user to paste:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
[audio]
|
|
105
|
+
buses/default_bus_layout="res://audio/default_bus_layout.tres"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- Generates `audio/default_bus_layout.tres` content as plain text for the user to save (Godot's `.tres` resource format with bus entries).
|
|
109
|
+
- Writes `.summer/audio-bible.md` via host `Write`.
|
|
110
|
+
- Does NOT call `summer_generate_audio` — instead suggests external SFX library searches or asks the user to handle generation later.
|
|
111
|
+
- Asks "May I write ..." before each file write.
|
|
112
|
+
|
|
113
|
+
**Assertions:**
|
|
114
|
+
|
|
115
|
+
- [ ] Skill identifies that MCP is unavailable; does not blindly call `summer_*`.
|
|
116
|
+
- [ ] Generated `project.godot` snippet uses correct INI section format.
|
|
117
|
+
- [ ] Generated `default_bus_layout.tres` is valid Godot 4 resource format.
|
|
118
|
+
- [ ] Skill still writes `.summer/audio-bible.md`.
|
|
119
|
+
- [ ] Skill does not attempt audio generation when generation tools are unavailable.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
This spec runs via `/skill-test audio-direction spec` (see `_meta/skill-test/SKILL.md`).
|