Skip to content

Studio tools

The multi-agent studio: roster, board, feedback, decisions, loops, messages and playtests.

26 tools in the studio category. Badges: read-only tools never change the project; mutating tools are undoable and attributed; open-world tools reach outside the engine and MCP clients ask before running them.

Tool Summary
studio_overview Start here when working with the studio (a team of AI agents making this game).
studio_agent_define Create a studio agent or update one (by id or name; only the fields you pass change).
studio_agent_list The studio roster: each agent's id (use it for assignees and @mentions), name, role, discipline, focus, live status, open tasks and usage.
studio_agent_brief Everything needed to be a roster member: its system prompt (role mission, focus, persona, standing instructions, memory, the team, studio etiquette) and the engine tools it may use with their access (allow | ask).
studio_agent_remove Remove an agent from the studio (deletes agents/<id>.agent.json; its open tasks become unassigned).
studio_team_template Spawn a whole team of specialists from a template (agents that already exist by id are updated): starter_crew (5 generalists), indie_trio (3), aaa_strike_team (22: director, producer, five designers, four programmers, five artists, audio, writing, QA, two playtester personas, critic), narrative_team, qa_squad (QA lead, three playtester personas, critic, fixer), art_team, audio_team.
studio_memory Your long-term memory as a studio agent (kept in your profile and shown at the start of every task): note a fact worth remembering (conventions, decisions, the human's preferences, unfinished work), forget an outdated note by number, or list notes.
studio_usage_report Record tokens an agent spent with its own model, for studio budgets and cost tracking (runners that call models outside the engine — the editor crew, custom scripts — report each request here).
studio_presence Show what a roster member is doing right now in the editor's Studio panel (live status and activity next to its avatar): working with a one-line activity when you start something, idle when you finish.
studio_task_create Put a task on the studio board.
studio_task_update Move a task across the board (backlog → todo → doing → review → done, or dropped), reassign it, edit it, or add a comment.
studio_task_list The studio board.
studio_task_claim Claim a task and start it (assignee = you, status = doing).
studio_feedback_submit File feedback about the game as a playtester, critic, agent or human: category (fun, difficulty, clarity, visuals, audio, performance, bug, narrative, accessibility), severity, a one-line summary, details, what it's about (target), and evidence {playtest: "P-3", captures: [...], metrics: {...}, positions: [[x,y,z]], repro: [steps]}.
studio_feedback_list Feedback with each item's director verdict (act / drop / defer / merge_into), rationale and measured effect (metrics before/after).
studio_feedback_update Change a feedback item: status (e.g.
studio_decide The director's (or producer's) verdict on a feedback item, visible to everyone with its rationale: act (creates tasks — give each a title, acceptance criteria and an assignee — or links existing task_ids), drop (won't do, say why), defer (later), or merge_into a duplicate.
studio_loop_define Define a studio loop: a repeatable cycle of stages with stop conditions, stored in studio/loops/<name>.loop.json.
studio_loop_start Start a run of a loop.
studio_loop_advance Report the results of a loop stage's assignments and move the loop on: reports [{agent, report, signoff?, usage?}].
studio_loop_status A loop's state: status, iteration, current stage, pending assignments (with prompts), per-iteration history (stage reports, playtests, filed feedback, verified effects) and metric trends.
studio_loop_stop Stop a running loop (pending assignments are dropped).
studio_message_send Talk to the team so the back-and-forth is visible: post in a channel (#general by default; any name creates a channel), address agents with to or @mentions in the text (@id, @role, @discipline, @all), reply in a thread with reply_to, and reference a task/feedback.
studio_inbox Messages for you (addressed to you, mentioning you, or broadcast in #general), oldest first; unread only by default, and reading marks them read.
playtest_run Play the game with a bot in a sandbox copy of the scene (the scene you edit is untouched) and get a report: completion rate, time-to-goal, deaths and their causes, fails, damage, stuck periods, objectives, coverage, frame cost, screenshots at notable moments and a top-down heatmap (returned as an image).
playtest_compare Before/after comparison of two playtests (ids like P-3): every metric with its delta and whether it got better or worse (direction-aware: fewer deaths is better, higher completion is better).

studio_overview

Studio overview read-only

Start here when working with the studio (a team of AI agents making this game). Returns the roster with live status, the task board counts, feedback waiting for a decision, recent director decisions with measured effects, loops and their state, the latest playtest metrics, and token/cost usage. include_catalog=true also lists roles, disciplines, team templates and loop templates.

Argument Type Required Description Values
include_catalog boolean Also return roles, team templates and loop templates
studio_overview {"include_catalog": true}
skywalker call studio_overview '{"include_catalog": true}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_overview",
    "arguments": {
      "include_catalog": true
    }
  }
}

studio_agent_define

Define agent mutating

Create a studio agent or update one (by id or name; only the fields you pass change). An agent is a specialist: a role (e.g. level_designer, gameplay_programmer, lighting_artist, playtester, critic — see studio_overview include_catalog), a focus (what exactly it owns: "enemy AI", "onboarding"), a persona, standing instructions, a model, an autonomy level (observe = read-only, ask = changes need human approval, autonomous), per-tool-category permissions (allow|ask|off), and who it reports to. Saved as agents/.agent.json (shareable, git-friendly). Playtesters take persona knobs in playtest {policy, reaction_time, skill, curiosity, patience}. Example: {name:"Mira", role:"level_designer", focus:"secret areas", focus_tags:["secrets"], reports_to:"nimbus"}.

Argument Type Required Description Values
id string Agent id to update (default: derived from name)
name string Display name
role string Role creative_director art_director producer systems_designer level_designer narrative_designer economy_designer ux_designer gameplay_programmer ai_programmer graphics_programmer tools_programmer environment_artist lighting_artist character_artist vfx_artist technical_artist ui_artist sound_designer composer writer qa_lead playtester critic
discipline string Discipline (default: from the role) direction production design engineering art audio writing qa
focus string What this agent specializes in
focus_tags string[] Short focus tags
persona string Personality / voice
mission string Replaces the role's built-in mission
instructions string Standing instructions: style guides, constraints, conventions
provider string anthropic | openai | mock | an editor provider name
model string Model id (empty = provider default, e.g. claude-opus-5-5)
autonomy string How freely it may change the game observe ask autonomous
permissions object Per tool category:
reports_to string Agent id of its lead
color string Avatar color #rrggbb
face string Avatar face happy focused dreamy wink determined curious
max_rounds integer Max tool rounds per task (default 40)
memory string[] Replace its long-term memory notes
playtest object Playtester persona:
studio_agent_define {"id": "level_designer", "name": "Mira", "role": "level_designer", "focus": "layout and pacing", "reports_to": "creative_director"}
skywalker call studio_agent_define '{"id": "level_designer", "name": "Mira", "role": "level_designer", "focus": "layout and pacing", "reports_to": "creative_director"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_agent_define",
    "arguments": {
      "id": "level_designer",
      "name": "Mira",
      "role": "level_designer",
      "focus": "layout and pacing",
      "reports_to": "creative_director"
    }
  }
}

studio_agent_list

List agents read-only

The studio roster: each agent's id (use it for assignees and @mentions), name, role, discipline, focus, live status, open tasks and usage. Filter by discipline or role; include_profiles returns full profiles (persona, instructions, permissions, memory).

Argument Type Required Description Values
discipline string Only this discipline
role string Only this role
include_profiles boolean Full profiles
studio_agent_list {"include_profiles": true}
skywalker call studio_agent_list '{"include_profiles": true}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_agent_list",
    "arguments": {
      "include_profiles": true
    }
  }
}

studio_agent_brief

Agent brief read-only

Everything needed to be a roster member: its system prompt (role mission, focus, persona, standing instructions, memory, the team, studio etiquette) and the engine tools it may use with their access (allow | ask). Use it to run a studio agent in any harness: e.g. give a Claude Code / Codex subagent this system prompt, let it call only the listed tools, and connect it as "/" (or pass as: "") so its work is attributed. loop_member=true withholds loop and roster control tools.

Argument Type Required Description Values
agent string yes Agent id or name
loop_member boolean Running inside a loop stage
studio_agent_brief {"agent": "{{STUDIO_ID}}", "loop_member": true}
skywalker call studio_agent_brief '{"agent": "{{STUDIO_ID}}", "loop_member": true}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_agent_brief",
    "arguments": {
      "agent": "{{STUDIO_ID}}",
      "loop_member": true
    }
  }
}

studio_agent_remove

Remove agent mutating destructive

Remove an agent from the studio (deletes agents/.agent.json; its open tasks become unassigned).

Argument Type Required Description Values
agent string yes Agent id or name
studio_agent_remove {"agent": "aurora"}
skywalker call studio_agent_remove '{"agent": "aurora"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_agent_remove",
    "arguments": {
      "agent": "aurora"
    }
  }
}

studio_team_template

Spawn a team mutating

Spawn a whole team of specialists from a template (agents that already exist by id are updated): starter_crew (5 generalists), indie_trio (3), aaa_strike_team (22: director, producer, five designers, four programmers, five artists, audio, writing, QA, two playtester personas, critic), narrative_team, qa_squad (QA lead, three playtester personas, critic, fixer), art_team, audio_team. Override provider/model/autonomy for everyone with defaults.

Argument Type Required Description Values
template string yes Team template starter_crew indie_trio aaa_strike_team narrative_team qa_squad art_team audio_team
defaults object Fields applied to every member, e.g.
studio_team_template {"template": "aaa_strike_team"}
skywalker call studio_team_template '{"template": "aaa_strike_team"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_team_template",
    "arguments": {
      "template": "aaa_strike_team"
    }
  }
}

studio_memory

Agent memory mutating

Your long-term memory as a studio agent (kept in your profile and shown at the start of every task): note a fact worth remembering (conventions, decisions, the human's preferences, unfinished work), forget an outdated note by number, or list notes.

Argument Type Required Description Values
action string yes What to do note forget list
text string The note (for note)
number integer Note number, 1-based (for forget)
agent string Whose memory (default: you)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_memory {"action": "note", "agent": "nimbus", "text": "The art director prefers warm rim light on hero props."}
skywalker call studio_memory '{"action": "note", "agent": "nimbus", "text": "The art director prefers warm rim light on hero props."}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_memory",
    "arguments": {
      "action": "note",
      "agent": "nimbus",
      "text": "The art director prefers warm rim light on hero props."
    }
  }
}

studio_usage_report

Report usage mutating

Record tokens an agent spent with its own model, for studio budgets and cost tracking (runners that call models outside the engine — the editor crew, custom scripts — report each request here). Tool calls are counted automatically.

Argument Type Required Description Values
agent string Agent id (default: you)
model string Model id (prices the tokens)
input_tokens integer Uncached input tokens
output_tokens integer Output tokens
cache_read_tokens integer Cached input tokens read
cache_write_tokens integer Input tokens written to the cache
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_usage_report {"agent": "level_designer", "model": "claude-sonnet-5-5", "input_tokens": 12000, "output_tokens": 3400, "cache_read_tokens": 80000}
skywalker call studio_usage_report '{"agent": "level_designer", "model": "claude-sonnet-5-5", "input_tokens": 12000, "output_tokens": 3400, "cache_read_tokens": 80000}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_usage_report",
    "arguments": {
      "agent": "level_designer",
      "model": "claude-sonnet-5-5",
      "input_tokens": 12000,
      "output_tokens": 3400,
      "cache_read_tokens": 80000
    }
  }
}

studio_presence

Set presence mutating

Show what a roster member is doing right now in the editor's Studio panel (live status and activity next to its avatar): working with a one-line activity when you start something, idle when you finish. External harnesses (the Python agent layer, scripts, Claude Code subagents) call it so their agents appear live like the editor's crew. Example: {status: "working", activity: "T-4 widen the lava bridge", as: "mira"}.

Argument Type Required Description Values
status string yes Status working idle waiting blocked
activity string One line: what you are doing (empty when idle)
agent string Whose presence (default: you)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_presence {"status": "working", "activity": "T-4 widen the bridge", "as": "level_designer"}
skywalker call studio_presence '{"status": "working", "activity": "T-4 widen the bridge", "as": "level_designer"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_presence",
    "arguments": {
      "status": "working",
      "activity": "T-4 widen the bridge",
      "as": "level_designer"
    }
  }
}

studio_task_create

Create task mutating

Put a task on the studio board. Good tasks are small and checkable: a clear title, acceptance criteria (how we know it's done), a discipline, and an assignee (agent id, or "@role" to pick the least busy agent with that role). Link the feedback it addresses so the effect can be measured. Example: {title:"Widen the lava bridge", acceptance:["bridge 3 m wide","deaths ≤ 1 per run"], assignee:"@level_designer", feedback:["F-2"]}.

Argument Type Required Description Values
title string yes Short imperative title
description string Context and details
acceptance string[] Acceptance criteria, one per item
discipline string Discipline direction production design engineering art audio writing qa
assignee string Agent id or @role
priority string Priority (default normal) low normal high critical
status string Initial status (default todo) backlog todo doing review done dropped
depends_on string[] Task ids that must be done first
feedback string[] Feedback ids this task addresses
links object Other links:
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_task_create {"title": "Widen the second canyon gap's landing", "discipline": "design", "priority": "high", "acceptance": ["Bots clear the gap in 3 of 3 runs"]}
skywalker call studio_task_create '{"title": "Widen the second canyon gap'\''s landing", "discipline": "design", "priority": "high", "acceptance": ["Bots clear the gap in 3 of 3 runs"]}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_task_create",
    "arguments": {
      "title": "Widen the second canyon gap's landing",
      "discipline": "design",
      "priority": "high",
      "acceptance": [
        "Bots clear the gap in 3 of 3 runs"
      ]
    }
  }
}

studio_task_update

Update task mutating

Move a task across the board (backlog → todo → doing → review → done, or dropped), reassign it, edit it, or add a comment. Marking the last task of a feedback item done moves that feedback to "fixed" (the next verification playtest then measures the effect). Moving to doing/done checks dependencies.

Argument Type Required Description Values
task string yes Task id, e.g. T-4
status string New status backlog todo doing review done dropped
assignee string Agent id (empty string unassigns)
priority string Priority low normal high critical
title string Title
description string Description
acceptance string[] Acceptance criteria (replaces the list)
discipline string Discipline
depends_on string[] Replace dependencies
links object Links to add
comment string Comment for the thread (what changed, what's left)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_task_update {"task": "T-12", "status": "review", "comment": "Landing widened by 1.5 m; playtest attached."}
skywalker call studio_task_update '{"task": "T-12", "status": "review", "comment": "Landing widened by 1.5 m; playtest attached."}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_task_update",
    "arguments": {
      "task": "T-12",
      "status": "review",
      "comment": "Landing widened by 1.5 m; playtest attached."
    }
  }
}

studio_task_list

Task board read-only

The studio board. Filter by status (or "open" = backlog/todo/doing/review), assignee, discipline, or mine=true for your own tasks. Returns tasks with acceptance criteria, links and comment counts; the text is a compact kanban.

Argument Type Required Description Values
status string A status, or "open" / "all" (default all)
assignee string Agent id
discipline string Discipline
mine boolean Only tasks assigned to you
limit integer Max tasks (default 100)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_task_list {"status": "open", "assignee": "level_designer"}
skywalker call studio_task_list '{"status": "open", "assignee": "level_designer"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_task_list",
    "arguments": {
      "status": "open",
      "assignee": "level_designer"
    }
  }
}

studio_task_claim

Claim task mutating

Claim a task and start it (assignee = you, status = doing). Without task, claims your highest-priority todo task, or else an unassigned todo task in your discipline. External agents identify with as or a client name ending in /.

Argument Type Required Description Values
task string Task id (default: pick the next one for you)
agent string Claim for this agent (default: you)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_task_claim {"as": "level_designer"}
skywalker call studio_task_claim '{"as": "level_designer"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_task_claim",
    "arguments": {
      "as": "level_designer"
    }
  }
}

studio_feedback_submit

Submit feedback mutating

File feedback about the game as a playtester, critic, agent or human: category (fun, difficulty, clarity, visuals, audio, performance, bug, narrative, accessibility), severity, a one-line summary, details, what it's about (target), and evidence {playtest: "P-3", captures: [...], metrics: {...}, positions: [[x,y,z]], repro: [steps]}. The director triages it with studio_decide. Pass a fingerprint to deduplicate recurring findings (a repeat bumps occurrences instead of filing a duplicate).

Argument Type Required Description Values
category string yes Category fun difficulty clarity visuals audio performance bug narrative accessibility
severity string Severity (default medium) low medium high critical
summary string yes One line: what's wrong or great
details string What happened, where, why it matters
target string Entity, area, system or asset it is about
evidence object {playtest, captures, metrics, positions, repro, trace}
fingerprint string Dedup key for recurring issues
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_feedback_submit {"category": "difficulty", "severity": "high", "summary": "Players fall at the second canyon gap", "target": "Canyon Gap 2", "as": "playtester"}
skywalker call studio_feedback_submit '{"category": "difficulty", "severity": "high", "summary": "Players fall at the second canyon gap", "target": "Canyon Gap 2", "as": "playtester"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_feedback_submit",
    "arguments": {
      "category": "difficulty",
      "severity": "high",
      "summary": "Players fall at the second canyon gap",
      "target": "Canyon Gap 2",
      "as": "playtester"
    }
  }
}

studio_feedback_list

Feedback read-only

Feedback with each item's director verdict (act / drop / defer / merge_into), rationale and measured effect (metrics before/after). status: open, needs_decision (open + regressed), active (accepted, in_progress, fixed), a single status, or all (default).

Argument Type Required Description Values
status string Filter (default all)
category string Category fun difficulty clarity visuals audio performance bug narrative accessibility
limit integer Max items, newest first (default 50)
studio_feedback_list {"status": "open", "category": "bug"}
skywalker call studio_feedback_list '{"status": "open", "category": "bug"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_feedback_list",
    "arguments": {
      "status": "open",
      "category": "bug"
    }
  }
}

studio_feedback_update

Update feedback mutating

Change a feedback item: status (e.g. verified after a critic's re-review, regressed to reopen its tasks), severity, category, summary, target, more evidence, or a comment for its history. Decisions themselves go through studio_decide.

Argument Type Required Description Values
feedback string yes Feedback id, e.g. F-3
status string New status open accepted dropped deferred in_progress fixed verified regressed
severity string Severity low medium high critical
category string Category fun difficulty clarity visuals audio performance bug narrative accessibility
summary string Summary
details string Details
target string Target
evidence object Evidence to merge in
comment string Note for the history
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_feedback_update {"feedback": "F-7", "status": "verified", "comment": "Deaths at the gap went from 4 to 0."}
skywalker call studio_feedback_update '{"feedback": "F-7", "status": "verified", "comment": "Deaths at the gap went from 4 to 0."}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_feedback_update",
    "arguments": {
      "feedback": "F-7",
      "status": "verified",
      "comment": "Deaths at the gap went from 4 to 0."
    }
  }
}

studio_decide

Decide on feedback mutating

The director's (or producer's) verdict on a feedback item, visible to everyone with its rationale: act (creates tasks — give each a title, acceptance criteria and an assignee — or links existing task_ids), drop (won't do, say why), defer (later), or merge_into a duplicate. The current playtest metrics are stored as the baseline, so the next verification playtest measures the effect (optionally against explicit targets like {"deaths":{"max":1}}); a regression reopens the tasks. Only direction/production agents (or humans) may decide. Example: {feedback:"F-2", verdict:"act", rationale:"Unfair spike", tasks:[{title:"Telegraph the lava", assignee:"@lighting_artist", acceptance:["glow visible from 10 m"]}]}.

Argument Type Required Description Values
feedback string yes Feedback id
verdict string yes Verdict act drop defer merge_into
rationale string yes Why — shown next to the feedback
tasks object[] Tasks to create (act)
task_ids string[] Existing tasks that address it (act)
merge_into string Feedback id it duplicates (merge_into)
targets object What success means: {metric: {min, max}}
metrics_before object Baseline metrics (default: latest playtest)
redecide boolean Override an earlier decision
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_decide {"feedback": "F-7", "verdict": "act", "rationale": "Unfair difficulty spike early in the level.", "targets": {"deaths": {"max": 1}}}
skywalker call studio_decide '{"feedback": "F-7", "verdict": "act", "rationale": "Unfair difficulty spike early in the level.", "targets": {"deaths": {"max": 1}}}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_decide",
    "arguments": {
      "feedback": "F-7",
      "verdict": "act",
      "rationale": "Unfair difficulty spike early in the level.",
      "targets": {
        "deaths": {
          "max": 1
        }
      }
    }
  }
}

studio_loop_define

Define loop mutating

Define a studio loop: a repeatable cycle of stages with stop conditions, stored in studio/loops/.loop.json. Start from a template (playtest_fix_verify, art_pass_with_critic, balance_tuning, vertical_slice_sprint, bug_bash) and override goal/stop, or write stages yourself. A stage is either kind "playtest" (the engine plays the game with bots: playtest {policy, runs, seconds}, file_feedback, verify_fixed) or kind "agents" (assignees: ["@role", "@discipline", "agent-id", "@a|@b" fallback], instruction template with {{goal}} {{inputs}} {{open_feedback}} {{my_tasks}} {{metrics}} {{roster}} {{iteration}}, parallel, only_with_tasks, gate {skip_if: no_open_feedback | no_todo_tasks | not_first_iteration | ..., approval: "human"}). stop: {max_iterations, metric_targets {completion_rate:{min:0.8}}, director_signoff, token_budget, time_budget_minutes}. delete=true removes it.

Argument Type Required Description Values
name string Loop name (default: the template's)
template string Start from this template playtest_fix_verify art_pass_with_critic balance_tuning vertical_slice_sprint bug_bash
goal string What the loop is trying to achieve
description string Description
stages object[] Stages (replace the template's)
stop object Stop conditions (merged over the template's)
delete boolean Remove the loop
studio_loop_define {"template": "playtest_fix_verify", "goal": "Players finish the canyon run without unfair deaths"}
skywalker call studio_loop_define '{"template": "playtest_fix_verify", "goal": "Players finish the canyon run without unfair deaths"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_loop_define",
    "arguments": {
      "template": "playtest_fix_verify",
      "goal": "Players finish the canyon run without unfair deaths"
    }
  }
}

studio_loop_start

Start loop mutating

Start a run of a loop. The engine runs playtest stages itself and returns the first agent stage's assignments: [{agent, stage, prompt, tasks}]. Execute each assignment as that agent (in-editor crew, the headless runner skywalker studio run, or your own subagents with actor "/"; parallel=true means they may run at the same time), then report back with studio_loop_advance. Override goal or max_iterations for this run.

Argument Type Required Description Values
loop string yes Loop name
goal string Goal for this run
max_iterations integer Iteration limit for this run
studio_loop_start {"loop": "playtest_fix_verify", "goal": "Players finish the canyon run without unfair deaths", "max_iterations": 3}
skywalker call studio_loop_start '{"loop": "playtest_fix_verify", "goal": "Players finish the canyon run without unfair deaths", "max_iterations": 3}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_loop_start",
    "arguments": {
      "loop": "playtest_fix_verify",
      "goal": "Players finish the canyon run without unfair deaths",
      "max_iterations": 3
    }
  }
}

studio_loop_advance

Advance loop mutating

Report the results of a loop stage's assignments and move the loop on: reports [{agent, report, signoff?, usage?}]. When every pending assignment has reported (or complete_stage=true), the loop runs the following stages — playtests, verification, effect measurement — until it needs agents again, waits for approval, or ends on its stop conditions. Returns the new status with the next assignments. Directors sign off with signoff=true (or a report starting with SIGNOFF). approve=true/false answers a human approval gate.

Argument Type Required Description Values
loop string yes Loop name
reports object[] Reports from the stage's agents
approve boolean Answer an approval gate
signoff boolean Director/producer sign-off for this iteration
complete_stage boolean Finish the stage even if some agents did not report
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_loop_advance {"loop": "playtest_fix_verify", "reports": [{"agent": "nimbus", "report": "…"}]}
skywalker call studio_loop_advance '{"loop": "playtest_fix_verify", "reports": [{"agent": "nimbus", "report": "…"}]}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_loop_advance",
    "arguments": {
      "loop": "playtest_fix_verify",
      "reports": [
        {
          "agent": "nimbus",
          "report": "…"
        }
      ]
    }
  }
}

studio_loop_status

Loop status read-only

A loop's state: status, iteration, current stage, pending assignments (with prompts), per-iteration history (stage reports, playtests, filed feedback, verified effects) and metric trends. Without a loop name, lists every loop and the available templates.

Argument Type Required Description Values
loop string Loop name (omit to list)
history boolean Include iteration history (default true)
studio_loop_status {"loop": "playtest_fix_verify", "history": true}
skywalker call studio_loop_status '{"loop": "playtest_fix_verify", "history": true}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_loop_status",
    "arguments": {
      "loop": "playtest_fix_verify",
      "history": true
    }
  }
}

studio_loop_stop

Stop loop mutating

Stop a running loop (pending assignments are dropped).

Argument Type Required Description Values
loop string yes Loop name
reason string Why
studio_loop_stop {"loop": "playtest_fix_verify"}
skywalker call studio_loop_stop '{"loop": "playtest_fix_verify"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_loop_stop",
    "arguments": {
      "loop": "playtest_fix_verify"
    }
  }
}

studio_message_send

Send message mutating

Talk to the team so the back-and-forth is visible: post in a channel (#general by default; any name creates a channel), address agents with to or @mentions in the text (@id, @role, @discipline, @all), reply in a thread with reply_to, and reference a task/feedback. Example: {text:"@lighting_artist the lava needs a stronger glow, see F-2", feedback:"F-2"}.

Argument Type Required Description Values
text string yes Message (supports @mentions)
to string[] Recipients: agent ids or @roles
channel string Channel (default general)
reply_to string Message id to reply to (threads)
task string Related task id
feedback string Related feedback id
kind string Structured message kind for agent harnesses (default chat): request, inform, handoff, result, approval_request, approval_answer, ...
data object Structured payload for agent harnesses (the text stays the human-readable summary)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_message_send {"text": "@nimbus the canyon fix is ready for review", "channel": "level", "task": "T-12"}
skywalker call studio_message_send '{"text": "@nimbus the canyon fix is ready for review", "channel": "level", "task": "T-12"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_message_send",
    "arguments": {
      "text": "@nimbus the canyon fix is ready for review",
      "channel": "level",
      "task": "T-12"
    }
  }
}

studio_inbox

Inbox read-only

Messages for you (addressed to you, mentioning you, or broadcast in #general), oldest first; unread only by default, and reading marks them read. Check it when you start a task. channel reads a whole channel; agent reads someone else's inbox without marking.

Argument Type Required Description Values
agent string Whose inbox (default: you)
unread_only boolean Only unread (default true)
channel string Read this channel instead ("*" = every channel)
thread string Read a whole thread instead (root message id); never marks read
after string With channel or thread: only messages newer than this id
limit integer Max messages (default 30)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
studio_inbox {"unread_only": true}
skywalker call studio_inbox '{"unread_only": true}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "studio_inbox",
    "arguments": {
      "unread_only": true
    }
  }
}

playtest_run

Playtest mutating

Play the game with a bot in a sandbox copy of the scene (the scene you edit is untouched) and get a report: completion rate, time-to-goal, deaths and their causes, fails, damage, stuck periods, objectives, coverage, frame cost, screenshots at notable moments and a top-down heatmap (returned as an image). Policies: goal_seeker (walks to entities tagged "goal"/"objective", avoids "hazard"/"enemy"), explorer (covers unexplored space), random, scripted (script: [{t: seconds, hold|release|press|click|event: ...}] — the same arguments as sim_input). persona {reaction_time, skill, curiosity, patience} shapes the bot; playtester agents use their own persona by default. runs>1 aggregates several seeds. Games should tag the player "player" and emit "death" / "fail" / "damage" / "objective" events. Saved under studio/playtests//; findings are returned for filing as feedback.

Argument Type Required Description Values
policy string Bot policy (default goal_seeker) goal_seeker explorer random scripted
seconds number Simulated seconds per run (default 30, max 600)
runs integer Runs with consecutive seeds (default 1, max 20)
seed integer First seed (default 1)
persona object {reaction_time: s, skill: 0..1, curiosity: 0..1, patience: s}
controls object Key mapping {up, down, left, right, jump} (default w/s/a/d/space)
script object[] Input timeline (scripted policy)
player integer | string Player entity (default: tagged "player")
goal_radius number Meters from a goal that count as reaching it (default 1)
screenshots boolean Capture screenshots (default true)
screenshot_interval number Also capture every N seconds
max_screenshots integer Screenshot cap (default 8)
label string Label for the report
agent string Use this playtester's persona
include_heatmap boolean Return the heatmap image (default true)
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
playtest_run {"policy": "goal_seeker", "runs": 3, "seconds": 45, "label": "before"}
skywalker call playtest_run '{"policy": "goal_seeker", "runs": 3, "seconds": 45, "label": "before"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "playtest_run",
    "arguments": {
      "policy": "goal_seeker",
      "runs": 3,
      "seconds": 45,
      "label": "before"
    }
  }
}

playtest_compare

Compare playtests mutating

Before/after comparison of two playtests (ids like P-3): every metric with its delta and whether it got better or worse (direction-aware: fewer deaths is better, higher completion is better). Pass feedback to record the result as that feedback's measured effect: improved → verified, regressed → regressed (its tasks reopen). Timing metrics (*_ms, est_fps) depend on the machine's load, so they only decide the verdict for performance feedback or when a target names them; they are always listed.

Argument Type Required Description Values
before string yes Earlier playtest id
after string yes Later playtest id
feedback string Record the effect for this feedback item
as string Act as this roster member (agent id). For external agents whose MCP client name isn't "<client>/<agent id>" (e.g. Claude Code subagents playing a role). Ignored when you already are one.
playtest_compare {"before": "P-3", "after": "P-4", "feedback": "F-2"}
skywalker call playtest_compare '{"before": "P-3", "after": "P-4", "feedback": "F-2"}' --project my_game
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "playtest_compare",
    "arguments": {
      "before": "P-3",
      "after": "P-4",
      "feedback": "F-2"
    }
  }
}