Skip to content

chore(repo): replace the legacy plugin with Scenario for Unity 0.2 - #200

Open
edemaistre wants to merge 52 commits into
mainfrom
chore/scenario-labs-home
Open

edemaistre wants to merge 52 commits into
mainfrom
chore/scenario-labs-home

Conversation

@edemaistre

@edemaistre edemaistre commented Oct 19, 2026 •

Copy link
Copy Markdown

Replaces the earlier Scenario plugin for Unity (com.scenarioinc.scenario, v0.11.0 and before, no longer maintained) with Scenario for Unity (com.scenario.unity 0.2.0), developed until now at edemaistre/unity-plugin.

What changes on main

  • The tree becomes the new plugin: a Unity 6.3 dev project hosting the embedded package Packages/com.scenario.unity, its tests, docs and CI.
  • Install URL: https://github.com/scenario-labs/unity-plugin.git?path=/Packages/com.scenario.unity
  • Links, package metadata, issue templates, the release workflow guard and the changelog now point to scenario-labs/unity-plugin.
  • commitlint skips merge commits, so this PR's history passes the commits check.
  • The agent bridge checks the bearer token before the path (CodeQL cs/user-controlled-bypass on the scenario-labs scan): a request without the token gets 401 on any path.

What is kept

  • The full history of both plugins: the new history merges on top of the old main, with no force push.
  • The old code on the legacy branch and under its v0.x tags and releases. An old install pinned with ?path=/package#v0.11.0 still resolves.
  • Tags unity-plugin-v0.1.0 and unity-plugin-v0.2.0 and the 0.2.0 release are already here.

Merge with "Create a merge commit", not squash: the release tags point to commits in this history, and release-please finds 0.2.0 through them.

Tested: EditMode 157/157 before and after the bridge fix (Unity 6000.3.21f1, macOS); commitlint passes on the full range.

🤖 Generated with Claude Code

edemaistre and others added 30 commits October 18, 2026 21:27
Scenario MCP client with price checks kept apart from paid runs, single-use
quotes, a durable job ledger, OAuth (PKCE, loopback) and API key sign-in with
OS secret storage, model catalog cache, schema forms, import, placement,
PBR materials, skyboxes and reference uploads. 54 EditMode tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d C# API

Window with Create, Library, Jobs, Workflows, Agent and Settings views, model
browser and command palette; local Streamable HTTP MCP server for agents with
spending approvals; provenance header in the Inspector; Project and Hierarchy
context menus; ScenarioApi for editor scripts. Dev-only batch screenshot tool
in Assets/ScenarioDev.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…able init order

The agent tool table was built in a static initializer before the output-type
list it reads, so every agent tool call failed with a type initializer error.
It is now built on first use. New tests cover API-key sign-in, workflow pricing
and runs, Prompt Spark in the ledger, max_cu refusals, scene edits with Undo,
JSON-RPC dispatch, and the HTTP checks (token, path, method, origin, host).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Real PNG, WAV and GLB files made by the tests plus a tiny MP4 fixture go
through the importer and the placer: provenance, PBR import settings and
material, skybox, model with collider, audio source, video player, Undo.
The window tests open every view and overlay on the fake service, fail on
any console error and check that browsing never sends a paid call. They
skip when Unity runs without a graphics device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
workflow_get lists a workflow's inputs under inputs_definition, which the
form parser never read: workflows with a required image showed an empty
form and their price check failed. Also reads promptSpark in camel case.
Adds the free live contract check (dev only), which prices every quick
pick, typed step and a set of workflows with the plugin's own code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…inks

Found by the live acceptance run:
- Results now land on their target when it sits in an unsaved scene: the
  job keeps the target's hierarchy path next to its GlobalObjectId, which
  does not resolve there.
- Each material is named after its result and packs its own metallic and
  smoothness map; a second material from the same prompt overwrote the
  first one's map.
- A workflow job reports 0 CU on its own row; the ledger keeps the quote
  instead of recording a free run.
- Scenario's search has no audio, so the Library's Audio filter lists the
  project's assets by type.
- Web links go through Core/Links and carry the team and project, so an
  asset opens in its own workspace; the API key link points at the API
  keys page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Acceptance.Run makes one generation per output type through the plugin's
own path, a typed step on an uploaded texture, a workflow and Prompt Spark,
and records each paid call in tests/live/LEDGER.md. SCENARIO_ACCEPT_CASES
re-runs chosen cases; SCENARIO_ACCEPT_RESUME checks jobs left running by an
earlier run after the restart, without resending them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README and package docs, a user guide for every view, the agent skill
shipped in Documentation~, AGENTS.md for coding agents, community files,
and the CI: house-style checks, versions in sync, .meta files present,
EditMode tests with GameCI when a Unity license secret is set,
Conventional Commit and PR title checks, and release-please.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eal 3D results

- 3D steps in four groups (texture, shape, rig and animate, parts and style), each with a
  default model and its alternatives; Motion output type and a searchable picker for
  Meshy's 656 library motions; motions_find agent tool
- Inputs Scenario needs beyond the schema are asked for before pricing (a character for
  Cartwheel motions, a reference image for YVO3D); GLB inputs go as an FBX copy to models
  that refuse GLB
- Rig sets get one Animator controller with every clip, played on the rigged model; clips
  from files with another root are remapped; rigs in centimeters are placed at meter scale
- Models stored as FBX, .blend or .vox are converted to GLB on download; real GLBs are not
- glTFast fixes: the default material cache is cleared in every generator (URP and
  Built-in), and Scenario files get a plain scene root so previews show models standing
- Thumbnails cached on disk show on the first Library visit; result cards wait up to a
  minute for Unity's preview; the motion picker scrolls into view
- capture_view falls back to an overview of the open scenes when there is no camera

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Accept3D.Import imports one real result of every 3D operation and renders it;
  Accept3D.Paid runs generate, rig, animate and an agent texture edit
- E2E.OAuth (browser sign-in, a person signs in) and E2E.Agent with tools/e2e_agent.py
  (Claude Code drives the editor through the bridge)
- Contract check fills the inputs a model needs and pins an FBX source
- Screenshot steps for Motion, the 3D steps, the motion picker and a model's Inspector
- Ledger: discovery batches and the 3D acceptance run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gent checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Turntables and animation loops of real Scenario results rendered by Unity
(ScenarioDev.Media.Run, tools/build_media.py), light and dark screenshots
per view, a feature section for each part of the window, and a new
run-and-jump motion made for it. The QA renders now bake each pose:
Unity's skinning pass does not run between renders in a batch loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…laytests

New agent tools:
- terrain_create: a Unity Terrain with a collider from a heightmap image or
  noise, flat areas for buildings, edge falloff, ground layers painted by
  height and slope from generated materials or textures.
- scatter: copies of a model on the ground in one call, with a height range,
  random turn, slope and keep-clear limits, colliders, repeatable seeds.
- make_playable: a rigged, animated character becomes a third-person player
  (CharacterController, an Animator Controller blending idle, walk and run on
  speed plus a jump, speeds taken from the clips so feet do not slide, a
  follow camera).
- play: start, stop, status, walk (waypoints with run, jump and wait; reports
  points reached, falls, jumps) and record (PNG frames at a fixed frame rate).
  Play mode starts without a domain reload so the bridge keeps serving, and the
  user's Enter Play Mode setting comes back when it ends.
- object_create and object_set take height (meters) and ground.

Runtime assembly Scenario.Runtime: ScenarioPlayer, ScenarioFollowCamera,
ScenarioAutopilot, ScenarioFrameRecorder, ScenarioInput (Input System or
legacy input).

Dev: E2E.Agent takes a run length, limits and a fresh scene from the
environment; tools/world_rehearsal.py has Claude Code build a world from one
prompt and records a timeline of its tool calls.

Tests: 118 of 118 EditMode tests pass, 8 new (terrain, layers, scatter,
sizing and grounding, make_playable, and a Play mode walk with a run, a jump
and a recording).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
make_playable takes a footstep sound; ScenarioPlayer plays it at each step,
faster when running, and slices a longer recording into single steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1 in the ledger

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…g, steps that move at any frame rate

MCP clients give up on a tool call after 60 s. generate, workflow_run and jobs now
wait at most 45 s and say which call follows a job that is still running; play walk
and record keep going in Unity and play status (wait_seconds) returns the result.
make_playable sets the character controller's minimum move to 0: at high frame
rates each step was under 1 mm and the player did not move. A drop longer than
4 m counts as a fall in playtests. The dev harness mutes Unity for agent sessions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d Cancel always resets

After registering, the sign-in resumed on a worker thread and asked Unity to open
the browser there; Unity opens URLs only from the main thread, so nothing opened
and the panel stayed on "Finish signing in in your browser" with Cancel unable to
clear it. The browser now opens through the main thread, any failure ends the
sign-in with a message, and Cancel brings the panel back at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A single 3D generation is often above 100 CU, so the dialog came up on routine work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r session by default (was 20 and 300)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s under 45 s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…long a path, atmosphere and four-angle views

- ground_height: height, slope and surface at points, or a profile along a line with its steepest slope and biggest step.
- make_walkable: invisible walkway on a generated bridge or platform (holes bridged, bumps smoothed), side rails, ramps to the ground beyond each end, own colliders off; reports how each end meets the ground.
- place_along: copies at even spacing beside or on a path, facing it, sitting on the ground, with optional point lights.
- atmosphere: presets (golden_hour, midday, overcast, misty_morning, sunset, night) for sun, fog and ambient light, and in URP a post-processing volume; any value can be set alone.
- capture_view: around (four three-quarter views in one image) and from/at (one view from any point, lifted above the terrain when given under it).
- models_find: sort newest, with the date each model was added.
- Skill: the walkable-world order from rehearsal 1, with fixes for what failed in playtests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bridge

Ask runs claude -p with a temporary MCP config that points at this editor's bridge (turned on if needed), only the scenario-unity tools allowed and dontAsk permissions, from a temp working folder. The request goes on stdin, followed by the selected paths. stream-json is parsed on a worker thread; tool calls, text, the result and one-line errors reach the main thread as they arrive. Stop kills the run, a script reload stops it and keeps the log.

Claude Code is found from the new Claude Code path setting, then PATH and the usual install folders, and the child gets an augmented PATH. Client setup uses the same lookup. Tests cover the arguments, quoting, MCP config shape, PATH and the parser on a recorded run; the real claude is never launched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d Make Playable

SceneActions reads the selection as a 3D object (its outermost prefab or character root), a terrain, an image or sprite, another asset or nothing, and groups the catalog steps for it. Make playable, Put on the ground, Set height and Scatter each run as one Undo step and revert on failure; Make playable says what is missing first (a skeleton, a walk, a unique path).

The Hierarchy gets Scenario/Next Step... built from the object's kind, and Scenario/Make Playable when the object is ready for it. The panel and palette that use these actions, their tests and the docs come in the next commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… actions, Claude Code path setting

A dockable, collapsible Scenario overlay in the Scene view follows the selection: grouped steps and scene actions (Make playable, Put on the ground, Set height) for a 3D object, Scatter here for a terrain, the image steps for an image, and Generate shortcuts with nothing selected. The Ask box sits at its top and at the top of Agent, with the live log, inline approvals, Stop and Clear.

The command palette adds the selection's actions, Set height from a typed number, Show the Scenario panel, and Ask Claude: <typed text>. Settings gets Claude Code path, empty to find it automatically. Tests cover what the panel offers for each selection and the scene actions with Undo. USER_GUIDE, README and ROADMAP describe the new entry points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
edemaistre and others added 21 commits October 19, 2026 04:10
…ette and GameObject menu

The two world tools agents use are now one click away in Unity: Make walkable on a selected
3D object (panel, command palette, GameObject > Scenario > Make Walkable), and a mood preset
with Apply in the panel and palette. Each runs as one undo step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in the Scene view

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ows it

model_schema_get flags Prompt Spark on the prompt field and in prompting.prompt_spark_fields,
never at the top level, so the Create view hid the Improve button for every model and the
agent's model_schema reported prompt_spark false. Both now read the field. A free price reads
"Improve · free".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…m the model shoot-out

From text alone, Meshy 7.1 and T2.5 kept shapes but lost the colours asked for on every subject; from a concept image every model kept both. Character concepts: A-pose, loose cloth hanging down.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rt, and stops the editor if the bridge fails

SCENARIO_REHEARSAL_SKILL adds SKILL.md to the system prompt as an installed skill; SCENARIO_E2E_PORT serves the bridge on another port when an open editor holds the default; a stale endpoint file from an earlier run is ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both settings classes sat in ScenarioSettings.cs, and Unity links a saved settings object to its class only through a file of the same name. The files were written with no script reference, so each start read the defaults: the chosen project, the bridge port, the model per type, favorites and recent models. Each class now has its own file (ScenarioProjectSettings.cs keeps the old file's id).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…liff faces with min_slope

Rehearsal 2 found the explorer walking through the generated temple and
terrain textures stretched on sheer walls.

- object_set collider: mesh or box, added once to a piece with no collider
- scatter min_slope: skips flatter ground, reported as too_flat
- skill: set pieces get collider mesh; cliff faces get a rock scatter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ressing

- settings load back after a restart (project and model choices persist)
- object_set collider (mesh or box), scatter min_slope
- agent skill: concept image first, shoot-out picks, collision and cliff dressing
- rehearsal harness: agent skill, bridge port, stop on bridge failure
- ledger for the 3D model shoot-out

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… release

0.1.0 was never tagged, so release-please read the whole history into the
0.2.0 notes. bootstrap-sha points it at the 0.1.0 commit. The badge line
carries two versions; a start and end marker updates both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The updater read 0.1.0-black as one version and dropped the colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Links, install URLs, package metadata, the release workflow guard and the
changelog now point to scenario-labs/unity-plugin. The README tells users
of the earlier plugin (com.scenarioinc.scenario, v0.11.0 and before) where
its code stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-labs-home

Keeps the history of the earlier plugin (com.scenarioinc.scenario, v0.11.0 and before) under the new code, so scenario-labs/unity-plugin main moves forward without a force push. The tree is the new plugin's; the old code stays on the legacy branch and the v0.x tags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge commits from git merge --no-ff ("Merge feat/x: ...") carry no type,
so a pull request that brings them in failed the commits check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A request without the token now gets 401 on any path, so no caller reaches
routing unauthenticated. Clears CodeQL cs/user-controlled-bypass on the
path check that came before the token check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@edemaistre

Copy link
Copy Markdown
Author

@hervenivon ready to merge, all checks are green. Please use "Create a merge commit", not squash: the unity-plugin-v0.1.0 and v0.2.0 tags point to commits in this history, and release-please finds 0.2.0 through them.

@edemaistre
edemaistre requested a review from hervenivon October 20, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants