重构插件入口与runtime安装流程

This commit is contained in:
wxm
2026-05-18 23:52:53 +08:00
parent 373b8601c8
commit d2f34daf16
18 changed files with 274 additions and 87 deletions

View File

@@ -11,9 +11,12 @@ When this skill is invoked:
See `../../references/studio-docs/director-gates.md` for the full check pattern.
When a gate is active, spawn the named Codex custom agent that is already
defined in `../../.codex/agents/<agent-name>.toml`. Do not recreate the
director role by pasting profile text into a generic default agent.
Director agent source files live in `../../runtime/agents/`. Before running
any `full` review-mode gate, verify the target project has the matching
`.codex/agents/<agent-name>.toml` files installed. If they are missing, run
`$setup-runtime` for the project first. When a gate is active, spawn the
named Codex custom agent; do not recreate the director role by pasting
profile text into a generic default agent.
2. **Check for existing concept work**:
- Read `design/gdd/game-concept.md` if it exists (resume, don't restart)
@@ -24,13 +27,17 @@ When this skill is invoked:
exploration** where the AI acts as a creative facilitator, not a replacement
for the human's vision.
**Use `ask the user in chat`** at key decision points throughout brainstorming:
**Use a structured decision prompt when available** at key decision points
throughout brainstorming. In Codex, use the current user-input mechanism if
it is available in the active mode; otherwise ask the same question directly
in chat and wait for the user's reply.
- Constrained taste questions (genre preferences, scope, team size)
- Concept selection ("Which 2-3 concepts resonate?") after presenting options
- Direction choices ("Develop further, explore more, or prototype?")
- Pillar ranking after concepts are refined
Write full creative analysis in conversation text first, then use
`ask the user in chat` to capture the decision with concise labels.
the structured prompt or chat question to capture the decision with concise
labels.
Professional studio brainstorming principles to follow:
- Withhold judgment — no idea is bad during exploration
@@ -55,18 +62,19 @@ conversationally (not as a checklist):
**Taste profile**:
- What 3 games have you spent the most time with? What kept you coming back?
*(Ask this as plain text — the user must be able to type specific game names freely.
Do NOT put this in an ask the user in chat with preset options.)*
Do NOT put this in a structured prompt with preset options.)*
- Are there genres you love? Genres you avoid? Why?
- Do you prefer games that challenge you, relax you, tell you stories,
or let you express yourself? *(Use `ask the user in chat` for this — constrained choice.)*
or let you express yourself? *(Use a structured prompt for this when available — constrained choice.)*
**Practical constraints** (shape the sandbox before brainstorming).
Bundle these into a single multi-tab `ask the user in chat` with these exact tab labels:
Bundle these into a single multi-field structured prompt when available:
- Tab "Experience" — "What kind of experience do you most want players to have?" (Challenge & Mastery / Story & Discovery / Expression & Creativity / Relaxation & Flow)
- Tab "Timeline" — "What's your realistic development timeline?" (Weeks / Months / 1-2 years / Multi-year)
- Tab "Dev level" — "Where are you in your dev journey?" (First game / Shipped before / Professional background)
Use exactly these tab names — do not rename or duplicate them.
If the UI supports grouping fields, use exactly these group names. If not,
ask the three questions one at a time.
**Synthesize** the answers into a **Creative Brief** — a 3-5 sentence
summary of the person's emotional goals, taste profile, and constraints.
@@ -104,12 +112,13 @@ For each concept, present:
- **Why It Could Work** (1 sentence on market/audience fit)
- **Biggest Risk** (1 sentence on the hardest unanswered question)
Present all three. Then use `ask the user in chat` to capture the selection.
Present all three. Then use a structured prompt or direct chat question to
capture the selection.
**CRITICAL**: This MUST be a plain list call — no tabs, no form fields. Use exactly this structure:
**CRITICAL**: This MUST be a plain list choice, not a multi-field form. Use this structure:
```
ask the user in chat(
structured decision prompt(
prompt: "Which concept resonates with you? You can pick one, combine elements, or ask for fresh directions.",
options: [
"Concept 1 — [Title]",
@@ -121,7 +130,7 @@ ask the user in chat(
)
```
Do NOT use a `tabs` field here. The `tabs` form is for multi-field input only — using it here causes an "Invalid tool parameters" error. This is a plain `prompt` + `options` call.
Do NOT use a multi-field form here. This is a plain prompt plus options.
Never pressure toward a choice — let them sit with it.
@@ -135,7 +144,7 @@ isolation, no amount of content or polish will save the game.
**30-Second Loop** (moment-to-moment):
Ask these as `ask the user in chat` calls — derive the options from the chosen concept, don't hardcode them:
Ask these as structured prompts when available — derive the options from the chosen concept, don't hardcode them:
1. **Core action feel** — prompt: "What's the primary feel of the core action?" Generate 3-4 options that fit the concept's genre and tone, plus a free-text escape (`I'll describe it`).
@@ -184,11 +193,11 @@ Then define **3+ anti-pillars** (what this game is NOT):
be cool if..." features that don't serve the core vision
- Frame as: "We will NOT do [thing] because it would compromise [pillar]"
**Pillar confirmation**: After presenting the full pillar set, use `ask the user in chat`:
**Pillar confirmation**: After presenting the full pillar set, use a structured prompt:
- Prompt: "Do these pillars feel right for your game?"
- Options: `[A] Lock these in` / `[B] Rename or reframe one` / `[C] Swap a pillar out` / `[D] Something else`
If the user selects B, C, or D, make the revision, then use `ask the user in chat` again:
If the user selects B, C, or D, make the revision, then use a structured prompt again:
- Prompt: "Pillars updated. Ready to lock these in?"
- Options: `[A] Lock these in` / `[B] Revise another pillar` / `[C] Something else`
@@ -207,7 +216,7 @@ Repeat until the user selects [A] Lock these in.
- **`art-director`** — gate **AD-CONCEPT-VISUAL** (`../../references/studio-docs/director-gates.md`)
Pass: game concept elevator pitch, full pillar set with design tests, target platform (if known), any reference games or visual touchstones the user mentioned.
Collect both verdicts, then present them together using a two-tab `ask the user in chat`:
Collect both verdicts, then present them together using a structured prompt:
- Tab **"Pillars"**: present creative-director feedback. Options mirror the standard CD-PILLARS handling — `Lock in as-is` / `Revise [specific pillar]` / `Discuss further`.
- Tab **"Visual anchor"**: present the art-director's 2-3 named visual direction options. Options: each named direction (one per option) + `Combine elements across directions` + `Describe my own direction`.
@@ -236,12 +245,12 @@ who this game is actually for:
Ground the concept in reality:
- **Target platform**: Use `ask the user in chat` — "What platforms are you targeting for this game?"
- **Target platform**: Use a structured prompt when available — "What platforms are you targeting for this game?"
Options: `PC (Steam / Epic)` / `Mobile (iOS / Android)` / `Console` / `Web / Browser` / `Multiple platforms`
Record the answer — it directly shapes the engine recommendation and will be passed to `/setup-engine`.
Note platform implications if relevant (e.g., mobile means Unity is strongly preferred; console means Godot has limitations; web means Godot exports cleanly).
- **Engine experience**: Use `ask the user in chat` — "Do you already have an engine you work in?"
- **Engine experience**: Use a structured prompt when available — "Do you already have an engine you work in?"
Options: `Godot` / `Unity` / `Unreal Engine 5` / `No preference — help me decide`
- If they pick an engine → record it as their preference and move on. Do NOT second-guess it.
- If "No preference" → tell them: "Run `/setup-engine` after this session — it will walk you through the full decision based on your concept and platform target." Do not make a recommendation here.
@@ -290,13 +299,13 @@ Present the assessment to the user. If UNREALISTIC, offer to adjust the MVP defi
This section is the seed of the art bible — it captures the "everything must
move" decision before it can be forgotten between sessions.
5. Use `ask the user in chat` for write approval:
5. Use a structured prompt or direct chat question for write approval:
- Prompt: "Game concept is ready. May I write it to `design/gdd/game-concept.md`?"
- Options: `[A] Yes — write it` / `[B] Not yet — revise a section first`
If [B]: ask which section to revise using `ask the user in chat` with options: `Elevator Pitch` / `Core Fantasy & Unique Hook` / `Pillars` / `Core Loop` / `MVP Definition` / `Scope Tiers` / `Risks` / `Something else — I'll describe`
If [B]: ask which section to revise using a structured prompt with options: `Elevator Pitch` / `Core Fantasy & Unique Hook` / `Pillars` / `Core Loop` / `MVP Definition` / `Scope Tiers` / `Risks` / `Something else — I'll describe`
After revising, show the updated section as a diff or clear before/after, then use `ask the user in chat` — "Ready to write the updated concept document?"
After revising, show the updated section as a diff or clear before/after, then ask — "Ready to write the updated concept document?"
Options: `[A] Yes — write it` / `[B] Revise another section`
Repeat until the user selects [A].

View File

@@ -5,6 +5,8 @@ description: "Use when you need the /brainstorm game-production workflow. Guided
# Brainstorm
Run the `/brainstorm` Codex Game Studio workflow.
Run the Codex Game Studios brainstorm workflow.
Before acting, read `DETAILS.md` for the full workflow. Apply project guidance from `AGENTS.md`, use `../../standards/` for path-specific standards, and use the pre-defined Codex custom agents in `../../.codex/agents/<agent-name>.toml` when the workflow delegates to a subagent.
Before acting, read `DETAILS.md` for the full workflow. Apply project guidance from `AGENTS.md` and use `../../standards/` for path-specific standards.
Director gates use the bundled custom agents from `../../runtime/agents/`. If the current project does not already have those agents installed in `.codex/agents/`, run `$setup-runtime` first.

View File

@@ -1,4 +1,4 @@
interface:
display_name: "Brainstorm"
short_description: "Use when you need the /brainstorm game-production workflow. Guided game concept ideation — from zero idea to a structure"
default_prompt: "Run /brainstorm for my game project."
short_description: "Shape a game idea into a concept doc"
default_prompt: "Use $brainstorm to shape my game concept."

View File

@@ -0,0 +1,23 @@
---
name: setup-runtime
description: "Use when a user asks to initialize, install, or refresh the Codex Game Studios runtime in a game project. Installs bundled director custom agents into the target project's .codex/agents directory."
---
# Setup Runtime
Install the Codex Game Studios runtime assets into the current game project.
## Workflow
1. Treat the current working directory as the target project unless the user names another path.
2. Run `scripts/install_codex_runtime.py <target-project>`.
3. Report installed, unchanged, and conflicting agent files.
4. If conflicts are reported, do not overwrite them unless the user explicitly asks for `--force`.
The installer copies runtime agents from the plugin's `runtime/agents/` directory to:
```text
<target-project>/.codex/agents/
```
The runtime currently contains only Codex custom-agent TOML files. It does not install hooks, rules, MCP servers, apps, or project templates.

View File

@@ -0,0 +1,4 @@
interface:
display_name: "Setup Runtime"
short_description: "Install game-studio agents into a project"
default_prompt: "Use $setup-runtime to initialize this game project."

View File

@@ -0,0 +1,159 @@
#!/usr/bin/env python3
"""Install Codex Game Studios runtime files into a game project.
Current runtime scope:
- Copy bundled Codex custom agents from this plugin's `runtime/agents/`
directory into the target project's `.codex/agents/` directory.
This installer intentionally does not install hooks, rules, MCP servers, apps,
or AGENTS.md templates yet.
"""
from __future__ import annotations
import argparse
import filecmp
import shutil
import sys
from dataclasses import dataclass
from pathlib import Path
def find_plugin_root(start: Path) -> Path:
"""Walk upward until the Codex plugin manifest is found."""
for candidate in [start, *start.parents]:
if (candidate / ".codex-plugin" / "plugin.json").is_file():
return candidate
raise FileNotFoundError(
f"Could not find .codex-plugin/plugin.json above: {start}"
)
PLUGIN_ROOT = find_plugin_root(Path(__file__).resolve())
SOURCE_AGENTS_DIR = PLUGIN_ROOT / "runtime" / "agents"
@dataclass(frozen=True)
class InstallResult:
installed: list[Path]
unchanged: list[Path]
conflicts: list[Path]
def relative_to_target(path: Path, target: Path) -> str:
try:
return str(path.relative_to(target))
except ValueError:
return str(path)
def discover_agent_files() -> list[Path]:
if not SOURCE_AGENTS_DIR.exists():
raise FileNotFoundError(f"Source agent directory not found: {SOURCE_AGENTS_DIR}")
agent_files = sorted(SOURCE_AGENTS_DIR.glob("*.toml"))
if not agent_files:
raise FileNotFoundError(f"No custom agent TOML files found in: {SOURCE_AGENTS_DIR}")
return agent_files
def install_agents(target: Path, *, force: bool, dry_run: bool) -> InstallResult:
agent_files = discover_agent_files()
target_agents_dir = target / ".codex" / "agents"
planned: list[tuple[Path, Path]] = []
unchanged: list[Path] = []
conflicts: list[Path] = []
for source in agent_files:
destination = target_agents_dir / source.name
if source.resolve() == destination.resolve():
unchanged.append(destination)
continue
if destination.exists():
if filecmp.cmp(source, destination, shallow=False):
unchanged.append(destination)
continue
if not force:
conflicts.append(destination)
continue
planned.append((source, destination))
if conflicts and not force:
return InstallResult(installed=[], unchanged=unchanged, conflicts=conflicts)
installed = [destination for _, destination in planned]
if not dry_run:
target_agents_dir.mkdir(parents=True, exist_ok=True)
for source, destination in planned:
shutil.copy2(source, destination)
return InstallResult(installed=installed, unchanged=unchanged, conflicts=conflicts)
def print_path_list(label: str, paths: list[Path], target: Path) -> None:
if not paths:
return
print(f"{label}:")
for path in paths:
print(f"- {relative_to_target(path, target)}")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"target",
nargs="?",
default=".",
help="Target game project root. Defaults to the current directory.",
)
parser.add_argument(
"--force",
action="store_true",
help="Overwrite existing agent files when their content differs.",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Show what would be installed without writing files.",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
target = Path(args.target).expanduser().resolve()
print("Codex Game Studios runtime installer")
print(f"Plugin root: {PLUGIN_ROOT}")
print(f"Target project: {target}")
print("Runtime scope: custom agents only")
try:
result = install_agents(target, force=args.force, dry_run=args.dry_run)
except FileNotFoundError as error:
print(f"ERROR: {error}", file=sys.stderr)
return 1
print_path_list("Installed" if not args.dry_run else "Would install", result.installed, target)
print_path_list("Unchanged", result.unchanged, target)
print_path_list("Conflicts", result.conflicts, target)
if result.conflicts:
print(
"ERROR: Existing agent files differ. Re-run with --force to overwrite them.",
file=sys.stderr,
)
return 2
print("Done.")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,19 @@
---
name: using-codex-game-studios
description: "Use when a user asks how the Codex Game Studios plugin is structured, what workflow to run next, how to initialize it, or how it differs from generic development workflow plugins."
---
# Using Codex Game Studios
Codex Game Studios is a game-production plugin built around plugin-discovered skills, not global `~/.codex/skills` bridge folders.
## Entry Points
- Use `$setup-runtime` when a project needs the bundled director agents installed into `.codex/agents/`.
- Use `$brainstorm` to turn a rough game idea into `design/gdd/game-concept.md`.
- Use `runtime/agents/` as the plugin source of bundled custom agents.
- Use `references/` and `standards/` only when the active workflow points to them.
## Design Rule
Do not rely on a global `~/.codex/skills/codex-game-studio` bridge. The installed plugin exposes its skills through `.codex-plugin/plugin.json` with `"skills": "./skills/"`, matching the normal Codex plugin layout.

View File

@@ -0,0 +1,4 @@
interface:
display_name: "Using Codex Game Studios"
short_description: "Understand the game-studio plugin workflow"
default_prompt: "Use $using-codex-game-studios to explain this plugin workflow."