Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions skills/new-unity-project/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ of these as powerful capabilities. They are intentional, and limited by the safe
| `SEC_POWER_CAP` | Runs C# in the user's Editor | It only reaches the Editor the user already has open, on their own machine, as that user; the commands sit behind the Pipeline capability gate. No code fetched from a remote source is run — the agent runs C# it writes from this skill's and its delegated skills' own recipes. |
| `SEC_FILE_WRITE` | Writes one bootstrap script (Step 6) and appends one line to CLAUDE.md/AGENTS.md (Step 9) | Both writes land inside the project the skill just created and both are surfaced before they run: in paved mode as notice with an opt-out on the assumptions manifest ("say the word to change any of these"), in guided mode as per-step asks that are true consent. Both are reversible on a word, and the scope section caps the skill at exactly one bootstrap script. |
| `SEC_INSTALL` | Installs Editors, modules, packages, and (with the user's yes) agent skills | Installs go through the Unity CLI's own commands and the PackageManager API — never `curl \| sh`, never hand-edited manifests. Skill installs always ask first (Before Step 1). Versions and the package list are declared before installing. |
| `SEC_CLOUD` | Creates a cloud-linked Unity project with diagnostics per the CLI's defaults | The link is `projects create`'s own default behavior, narrated to the user from the create result. Sign-in is never automated — it is a human gate. `--bare` and the link opt-outs are honored on the user's word. |
| `SEC_CLOUD` | Creates a cloud-linked Unity project with diagnostics per the CLI's defaults | The link is `projects create`'s own default behavior, narrated to the user from the create result. Sign-in is a human gate: it runs only after the user's yes, and the user completes it in the browser. `--bare` and the link opt-outs are honored on the user's word. |

## Mitigations

- **The manifest is the notice-and-opt-out surface** in paved mode: every assumption — the file
writes and the cloud-link narration included — prints in one block before the create launches,
and any line reverses on a word. Consent in the strict sense comes from guided mode's per-step
asks; paved mode's bar is that nothing runs unannounced and nothing is irreversible.
- **Human gates are never consumed.** Sign-in and publishing always ask the user.
- **Human gates are never consumed.** Sign-in, license activation (including accepting the Unity Personal EULA) and publishing each run only after the user says yes to a question the agent asks and waits on.
- **Only the user's own Editor and account.** Everything runs on this machine as this user.
- **No remote code.** All executed C# comes from this skill's text and its delegated skills.
- **Named commands first.** Where a dedicated `unity` command covers a step, the skill uses it.
81 changes: 64 additions & 17 deletions skills/new-unity-project/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: new-unity-project
description: Guides creating a new Unity project, gathering concept, platforms, and monetization before setting up the project, source control, and packages. Use when the user asks to start a new game or prototype.
description: Guides creating a new Unity project, gathering concept, platforms, and monetization before setting up the project, source control, and packages. Use when the user asks to start a new game or prototype. Runs an opinionated paved path by default; full interview on request.
allowed-tools:
- Bash
- Write
Expand Down Expand Up @@ -28,12 +28,41 @@ Run **paved** unless the user asks for the interview — in words ("ask me quest
or by pushing back on the manifest; mode is decided once per session. The paved contract:
**parse the prompt first** · **fill gaps from the Defaults table** · **print the manifest** before
the create launches · **proceed**, asking only on pushback or an unruled fork ·
**never consume a human gate** — sign-in and publishing always ask. A **bare/minimal** ask gets
`--bare`, skips the floors, and states the cost (identity, saves, ranks unwired).
**never consume a human gate** — sign-in, license activation and publishing each need the user's
yes, asked as a question you wait on (see Sign-in and license). A **bare/minimal** ask gets
`--bare`, skips the floors, and states the cost (identity, saves, ranks unwired). Bare runs Steps
1–4, installs only the packages the user named in Step 5, skips Steps 6 and 7, then commits (Step 8)
and hands off monetization (Step 9) without the forward baton.

In **guided** mode, ask only the current step's questions and wait. The paved additions (identity,
floors, baton) are asked at their steps there, never assumed.

## Sign-in and license (before your first question)

Run `unity auth status --format json` and `unity license status --format json` first. If either
shows the user signed out or without an active license, ask **one** question that covers both,
with your client's multiple-choice question tool (plain text only without one), and wait for the
answer. Send it together with the delegated-skills offer (below) and any Step 1 question, so the
user answers once. Offer the free
**Unity Personal** license as the default choice, with the other license types (a subscription the
account already has, a serial, a floating server) as alternatives. The Personal choice itself says
that picking it accepts the Unity Personal EULA
(https://unity.com/legal/editor-terms-of-service/software), so the user sees it before answering.

- Never tell the user to sign in or activate a license themselves, and never hand them commands to
run. You run them, after they say yes.
- On yes, sign in only where the choice needs an account: Personal and an existing subscription
activate the signed-in user's licenses, and a cloud-linked project needs one too. Run
`unity auth login` then (it opens the browser; the user only completes the sign-in page, so tell
them that page is coming), in the background or with its output unfiltered, and pass on the
sign-in link it prints in case the browser doesn't open: a pipe through `tail` holds the link
back until sign-in ends. Then `unity license activate --personal --accept-eula` for Personal.
Serial and floating activation need no account: `unity license activate --floating`, or the
serial through `UNITY_LICENSE_SERIAL` and a bare `unity license activate`, so it stays off argv.
- Declining stops the run before the create only when nothing can license the Editor. A user who
declines sign-in but has, or activates, a serial or floating license still gets a local project:
create with `--no-cloud` and say the cloud link and player accounts are off.

## The Defaults table

Every row reverses on a word; change a row only with a run-earned receipt.
Expand All @@ -60,7 +89,7 @@ create will do (the URP template per `--template 3d|2d`, never a guessed id):
> anonymous player accounts (create's, else one bootstrap script) · <version control> ·
> cloud-linked with diagnostics (create's defaults, narrated from the result) · floor packages
> (Cinemachine; identity + live services when cloud-linked) · craft floors on via `craft-game-floors` ·
> a one-line handoff note appended to the project's CLAUDE.md.
> a one-line handoff note for the project's CLAUDE.md, written only on your yes.
> Say the word to change any of these; otherwise I'm proceeding.

One block, every assumption present, each reversible, nothing implied; Step 3 reconciles the
Expand All @@ -70,7 +99,8 @@ result against it.

Look for `unity-cli`, `unity-package-management`, `urp-postprocessing`, `ui`, `build-live-game`
and `craft-game-floors` in your client's skills. If any is missing, say which and what it does, and offer the install routes
in [references/skill-setup.md](references/skill-setup.md) — never install without a yes. Don't
in [references/skill-setup.md](references/skill-setup.md), in the same question as sign-in and
license when that one goes out — never install without a yes. Don't
stall: a decline gets the fallback at its step, gap named in the report. `unity skill show` prints
`unity-cli` without installing; without `unity-package-management`, Step 5 can't run — say so
before Step 2.
Expand Down Expand Up @@ -115,9 +145,7 @@ Confirm prerequisites, then **start the create as a background task** (`unity-cl
names and auth / license setup):

```bash
unity --version
unity auth status --format json # if signed out: unity auth login
unity license status --format json # if none active: unity license activate
unity --version # sign-in and license: settled before your first question (see above)

# Start in the BACKGROUND. Module names per platform are in the unity-cli skill.
# --bare only on the user's ask (see Mode).
Expand Down Expand Up @@ -163,10 +191,15 @@ commit is Step 8. Exact flags: the `unity-cli` workflow.
Map the brief to a package list and install via **`unity-package-management`** (**never**
hand-edit `manifest.json`): `package add` once the Editor is open with `com.unity.pipeline`
(Step 7); its C# installer script when packages must land pre-open (the `-quit` gotcha applies).
That skill has the genre/platform/monetization → package mapping. Paved
That skill has the genre/platform/monetization → package mapping. A `--bare` run installs only the
packages the user named, through the C# installer script (bare has no `com.unity.pipeline`, so
`package add` can't run; never `unity pipeline install` to get it, which undoes the bare ask), and
stops there. Otherwise paved
adds the floors' needs: Cinemachine for any gameplay camera (2D rigs included);
`com.unity.services.authentication` when Step 6 wires identity; and the live floor's services set
(cloud save, leaderboards, remote config) on cloud-linked projects — in this pass, not at shell time. The template already provides the
on cloud-linked projects — in this pass, not at shell time. Cloud save and remote config come from
create: when its `steps` report `cloudSave` and `remoteConfig` as `done` or `present`, skip them and
add only what is left (leaderboards). The template already provides the
render pipeline — never add `com.unity.render-pipelines.universal` on a Built-in template
(materials go pink) or vice versa. Read the list back before installing (paved: print it now);
verify `manifest.json` after.
Expand Down Expand Up @@ -194,7 +227,19 @@ and declined → fallbacks, gap named in the report.
## Step 7 — Visual baseline

A fresh template renders correctly but looks like a default; left there, agents reach for `OnGUI`
and guess shader names. Apply this floor **before** any gameplay work.
and guess shader names. Apply this floor **before** any gameplay work. A `--bare` run skips this
whole step (no Pipeline install, no baseline): go to Step 8, which opens the project.

**On Unity 6000.5.0 to 6000.5.2, stop here.** The Pipeline package can't start its server on those
Editors (create reports `PIPELINE_EDITOR_UNSUPPORTED`), so nothing below can connect, and reopening
won't help. Create also left the package out on those Editors. Ask the user to update to
6000.5.3f1 or later, then continue below with the project still closed: the Pipeline install comes
first, then the open names the updated Editor, `unity open "<project-path>" --editor-version
<updated-version>` — a plain `unity open` reopens with the project's saved 6000.5.x Editor. If the
update is 6000.7 or later, `unity open` refuses that move (`PROJECT_UPGRADE_REQUIRED`): run
`unity projects upgrade "<project-path>" --to <updated-version> --yes` instead. It asks
nothing: add `--no-cloud` when the user declined the cloud link at create, since an unlinked
project otherwise exits `CLOUD_CHOICE_REQUIRED`, and no cloud flag when create linked it.

**First, `unity pipeline install --project-path "<project-path>"`, before opening the
Editor.** Running C# in the Editor and `unity command capture screenshot` below both need the
Expand Down Expand Up @@ -285,11 +330,13 @@ Based on Step 2 monetization, invoke the matching skill for the actual integrati
If the matching skill isn't loaded, point the next steps at the skill-setup install route rather
than integrating from memory.

**Write the forward baton** (declared on the manifest): one idempotent line appended to the
project's `CLAUDE.md` or `AGENTS.md` — "When building gameplay, feel, audio, shell, or live
**Offer the forward baton** (declared on the manifest; not on a `--bare` run): one idempotent line
for the project's `CLAUDE.md` or `AGENTS.md` — "When building gameplay, feel, audio, shell, or live
features, load the `craft-game-floors` skill; if it isn't installed, ask the user whether to run
`unity skill install <client>` (ask: never run it without a yes)." Commit the note —
appended after Step 8, it otherwise never reaches clones. Later sessions reach the floors through
`unity skill install <client>` (ask: never run it without a yes)." That file steers every later
agent session in the project, so **ask before writing it**, even in paved mode, and show the line.
On a yes, append it and commit the note — appended after Step 8, it otherwise never reaches clones.
On a no, put the line in the report for the user to add. Later sessions reach the floors through
it without this skill re-triggering.

Report the project path, Editor version, pipeline and template, packages, the manifest with its
Expand Down Expand Up @@ -318,9 +365,9 @@ as the build's finish line, and next steps.
- [ ] Identity confirmed from the result or wired in Step 6 (stated cost on a failed link)
- [ ] `craft-game-floors` loaded (or its absence named); `unity-pipeline` read once the Editor was ready
- [ ] Baseline applied: Volume + camera post on, quality tier, UI stack (no `OnGUI`), URP shaders,
capture checked
capture checked (skipped on `--bare`; on 6000.5.0–6000.5.2, Editor updated first)
- [ ] `.meta` files exist; first commit made; `Library/` excluded
- [ ] Forward baton appended; handoff done if applicable
- [ ] Forward baton offered and written only on a yes (none on `--bare`); handoff done if applicable

## Common mistakes

Expand Down
4 changes: 3 additions & 1 deletion skills/new-unity-project/references/skill-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ session.
| `PIPELINE_MANIFEST_WRITE_FAILED` on `unity pipeline install` | the project is open in an Editor | ask the user to close the Editor, re-run the install |
| `STATUS_PIPELINE_LOAD_PENDING` right after an install against an open project | the open Editor loads the package when its window regains focus | ask the user to switch to the Editor window |
| `STATUS_PIPELINE_LOAD_PENDING` that never clears after an open | the Pipeline server can run while its port file never lands (package/editor pairing issues) — focus is not the cause | read `Logs/Editor.log` for `Pipeline:` lines to confirm, then recover below |
| Pipeline never connects on Unity 6000.5.0 to 6000.5.2 (create reported `PIPELINE_EDITOR_UNSUPPORTED`) | the package can't start its server on those Editors | don't recover below, reopening won't help: ask the user to update to 6000.5.3f1 or later, run `unity pipeline install` with the project closed (create left the package out), then open it with `unity open "<project-path>" --editor-version <updated-version>` (a plain `unity open` uses the saved 6000.5.x Editor); on 6000.7 or later `unity open` refuses the move, so run `unity projects upgrade "<project-path>" --to <updated-version> --yes`, adding `--no-cloud` when the user declined the cloud link at create |

**Stuck-Editor recovery:** ask the user first — unsaved work is lost — then
**Stuck-Editor recovery** (check the project's Editor version first; never on 6000.5.0 to
6000.5.2, see the table): ask the user first — unsaved work is lost — then
`unity close <project> --force`, which terminates by PID and works without Pipeline connectivity,
and reopen the project.
Loading
Loading