---
name: unity-gamedev
description: >-
  Ecossistema COMPLETO de desenvolvimento de jogos Unity 3D em Linux
  (referência: Arch/CachyOS). É o ROUTER da suíte: instala Unity Hub
  e Editor, resolve licença, cria projetos novos JÁ com TDD/PlayMode/E2E verdes,
  liga o Editor a agentes de IA por MCP, roda testes headless e monta CI. Use
  para QUALQUER pedido sobre Unity, jogo, game dev, C# de jogo, cena, prefab,
  GameObject, MonoBehaviour, Play Mode, build de jogo, teste de jogo. Traduz
  tudo para quem vem de MERN (Jest→NUnit, Playwright→PlayMode/AltTester,
  npm→UPM, node_modules→Library). Gatilhos "quero fazer um jogo", "criar
  projeto Unity", "instalar Unity", "testar meu jogo", "TDD em Unity", "E2E em
  Unity", "conectar o Claude ao Unity", "CI do Unity".
when_to_use: >-
  Qualquer tarefa que envolva Unity ou desenvolvimento de jogos —
  desde "instale o Unity" até "escreva o teste dessa mecânica". NÃO use para
  jogos em outras engines (Godot, Unreal, web) nem para C# que não seja de jogo.
argument-hint: "[setup|new|tdd|e2e|mcp|ci|doctor] <o que você quer>"
disable-model-invocation: false
user-invocable: true
allowed-tools:
  - Bash
  - Read
  - Grep
  - Glob
  - Edit
  - Write
  - Skill
  - WebFetch
metadata:
  version: "1.2.0"
  created: "2026-08-23"
  suite-home: "~/Agent-Skills/unity-gamedev-agent-skill (default; a resolução real é dinâmica na FASE 0)"
  based-on: "deep-orchestrator-agent-skill (padrão de casa-da-skill + sync global)"
  license: "MIT"
  homepage: "https://github.com/frederico-kluser/unity-gamedev-agent-skill"
---

# unity-gamedev — router da suíte Unity desta máquina

Você é o ponto de entrada para **tudo** que envolve Unity aqui. Nunca improvise
comando de Unity: esta suíte tem script para cada operação, e cada script já
resolve as armadilhas que fazem o Unity falhar em silêncio no Linux.

---

## FASE 0 — resolva a casa da suíte e o contexto (SEMPRE, antes de tudo)

```bash
# `cd -P` é obrigatório: a skill quase sempre é alcançada por SYMLINK, e um
# `cd ..` comum sobe pelo caminho LÓGICO — de ~/.claude/skills/unity-gamedev
# três níveis acima dariam $HOME, não a casa da suíte. E o candidato só é
# aceito depois de provar que carrega scripts/ugd-context.sh.
# Os candidatos vão dos escopos global do Claude (CLAUDE_CONFIG_DIR/skills) e
# do projeto (./.claude/skills) aos agentes locais e à cópia da suíte. Se a
# env `UGD_HOME` já apontar para uma suíte válida, vale direto e a busca é
# pulada — serve para instalações não-Claude ou customizadas.
UGD_HOME=""
if [ -n "${UGD_HOME:-}" ] && [ -x "$UGD_HOME/scripts/ugd-context.sh" ]; then
  : # UGD_HOME veio do ambiente — use-o direto
else
  UGD_HOME=""
  for d in "$HOME"/.claude*/skills/unity-gamedev \
           "$HOME"/.agents/skills/unity-gamedev \
           "$HOME"/.jcode/skills/unity-gamedev \
           "$HOME"/.pi/agent/skills/unity-gamedev \
           "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/unity-gamedev" \
           "./.claude/skills/unity-gamedev" \
           "$HOME"/Agent-Skills/unity-gamedev-agent-skill/.claude/skills/unity-gamedev; do
    [ -e "$d/SKILL.md" ] || continue
    cand=$(cd -P "$d" 2>/dev/null && cd ../../.. 2>/dev/null && pwd -P) || continue
    [ -x "$cand/scripts/ugd-context.sh" ] && { UGD_HOME="$cand"; break; }
  done
fi
[ -n "$UGD_HOME" ] || { echo "PARE: não achei a casa da suíte unity-gamedev (defina UGD_HOME para ela)"; exit 1; }
. "$("$UGD_HOME/scripts/ugd-context.sh" --quiet)"
```

Depois disso você tem, no ambiente: `SKILL_HOME`, `UNITY_HUB`, `UNITY_EDITOR`,
`UNITY_EDITORS`, `UNITY_PROJECT`, `UNITY_PROJECT_VERSION`, `UNITY_LICENSE`,
`UNITY_EDITOR_MATCH` e os `HAS_*`.

Se `UNITY_EDITOR` estiver vazio ou `UNITY_LICENSE` vazio, **o pedido do usuário
provavelmente não pode ser atendido ainda** — vá para `unity-setup` primeiro.

---

## FASE 0.5 — PRE-FLIGHT: verifique (e instale) as dependências ANTES de qualquer tarefa

Depois da FASE 0, **roda SEMPRE** a pre-flight, antes de QUALQUER execução — não
pule para "classificar o pedido" antes dela (nem para a tabela de roteamento).
Ela é o portão que impede começar um trabalho que vai quebrar no meio por falta
de ferramenta. Resolve primeiro se a suite é alcançada por symlink (a pre-flight
está em `$UGD_HOME/scripts/ugd-preflight.sh`):

```bash
"$UGD_HOME/scripts/ugd-preflight.sh"            # tabela humana; exit 0 = OK
"$UGD_HOME/scripts/ugd-preflight.sh" --json     # para parsear required_missing/optional_missing
```

### Se houver dependência REQUERIDA faltando

1. **Mostre a lista** ao usuário: `id`, `label`, o que falta e o comando de
   instalação (o `--json` traz `id`/`label`/`action`/`command`). Destaque o
   aviso de **tamanho** do Editor (vários GB de download).
2. **PERGUNTE** — esta é a ÚNICA pergunta sancionada da skill. Dependência é
   cara (sudo, vários GB) e **nunca** entra sem consentimento explícito
   (vibe-guardrails). Pergunta exata:
   > **"quer que eu instale agora? (s/N)"**
   E **espere** a resposta. Não assuma "sim", não assuma "não".
3. **Usuário disse sim** → rode:
   ```bash
   "$UGD_HOME/scripts/ugd-preflight.sh" --install-all
   ```
   Editor/Hub podem demorar e pedir `sudo` — **explique o progresso** enquanto
   roda e avise o usuário se a senha for solicitada. Depois de terminar,
   **re-rode a pre-flight** para CONFIRMAR que ficou tudo verde, e só então
   continue a tarefa:
   ```bash
   "$UGD_HOME/scripts/ugd-preflight.sh"
   ```
4. **Usuário disse não** → **diga com honestidade** o que ainda dá para fazer
   sem a dependência em falta (ex.: sem Editor/licença **não dá para compilar
   nem testar**; dê para criar o projeto só se a rota sem bootstrap for
   aceitável) e prossiga **apenas no que for possível** — **nunca** finja que o
   ambiente está pronto quando não está.

### Pré-requisito que não se instala: a licença

`license` **não se instala por script** — a ação é o **login pela GUI do Unity
Hub** (a pre-flight exibe o guia). Se for o único pendente, **oriente o
usuário** no fluxo do Hub e **re-confirme** com:

```bash
"$SKILL_HOME/scripts/unity-license.sh" --status
```

> A pre-flight é sinalizada como **green** só quando todas as deps REQUERIDAS
> existem. As **opcionais** (`uv`, `node`, `shellcheck`) não bloqueiam — anote
> as que faltam, mas não interrompa a tarefa por causa delas nem pergunte por
> elas se o usuário já definiu o fluxo.

---

## Tabela de roteamento

| O que o usuário quer | Skill companheira | Script principal |
|---|---|---|
| instalar Unity / Hub / licença / "não abre" | `unity-setup` | `install-unity-hub.sh`, `install-unity-editor.sh`, `unity-license.sh` |
| criar um projeto novo | `unity-new-project` | `new-unity-project.sh` |
| escrever teste, TDD, "testa isso" | `unity-tdd` | `unity-run-tests.sh` |
| teste E2E / "o jogador consegue?" | `unity-e2e` | `unity-run-tests.sh --category E2E` |
| conectar agente ao Editor aberto | `unity-mcp` | `setup-mcp.sh` |
| CI, build headless, GitHub Actions | `unity-ci` | `templates/ci/` |
| "não está funcionando" / diagnóstico | (aqui mesmo) | `doctor.sh` |

**Leia o SKILL.md da companheira antes de agir.** Não reimplemente o que ela
já descreve.

---

## Protocolo do router

1. **Rode a FASE 0** e olhe o que existe de verdade na máquina — nunca afirme
   que o Unity está instalado sem ter olhado.
2. **Rode a pre-flight** (`"$UGD_HOME/scripts/ugd-preflight.sh"`) — a FASE 0.5.
   Se faltar dep **requerida**, mostre a lista, **pergunte** antes de instalar
   ("quer que eu instale agora? (s/N)") e só prossiga após o consentimento.
3. **Classifique** o pedido pela tabela acima. Em ambiguidade, prefira a skill
   mais específica; para "não sei por onde começar", rode `doctor.sh`.
4. **Carregue a skill companheira** (leia o arquivo dela por inteiro).
5. **Execute** pelos scripts da suíte, nunca por comandos inventados.
6. **Prove**: toda entrega que toca código termina com `unity-run-tests.sh`
   verde, e o resumo real colado na resposta.

---

## Mapa mental para quem vem de MERN

| MERN | Unity |
|---|---|
| `package.json` | `Packages/manifest.json` |
| `node_modules/` | `Library/` (derivado, nunca versionar) |
| `npm run dev` | botão ▶ Play — o Editor É o runtime |
| módulos ESM | **Assembly Definitions** (`.asmdef`) |
| Jest / Vitest | Unity Test Framework, testes **EditMode** |
| Supertest | testes **PlayMode** (`[UnityTest]`) |
| Playwright / Cypress | PlayMode + `InputTestFixture`, ou AltTester no build |
| GitHub Actions + setup-node | **GameCI** |

Mapa completo: `$SKILL_HOME/docs/mern-para-unity.md`. Leia-o antes de explicar
qualquer coisa de Unity para este usuário — ele é dev MERN.

Conhecimento de referência (docs da suíte):
- `$SKILL_HOME/docs/erros-comuns-unity.md` — armadilhas clássicas (estado
  `static`, eventos não-desassinados, `PlayerPrefs`/segredo, `Find*` em `Update`).
- `$SKILL_HOME/docs/arquitetura-referencia.md` — arquitetura (portas no domínio
  puro, SO-events sem lógica, DI/VContainer, Assembly Definitions).
- `$SKILL_HOME/docs/dicas-unity.md` — boas práticas (pool nativo, referência
  direta, Force Text + UnityYAMLMerge, Profiler).

---

## Regras invioláveis da suíte

1. **Regra de jogo nunca nasce em `MonoBehaviour`.** Nasce em `Game.Domain`
   (C# puro, o compilador proíbe `UnityEngine` lá) ou `Game.UseCases`.
   Fundamento: `$SKILL_HOME/docs/arquitetura-testavel.md`.
2. **Comportamento novo chega com teste** — EditMode por padrão.
   Procedimento: `$SKILL_HOME/prompts/tdd-loop.md`.
3. **Nunca abra um projeto com editor de versão diferente** sem dizer ao
   usuário que isso faz upgrade irreversível. `unity-cli.sh` já barra isso.
4. **Nunca apague assets, cenas ou `.meta`** por conta própria.
5. **Nunca reporte teste verde sem ter rodado.** Cole `Passed: N, Failed: M`.
6. **Nunca commite** `Library/`, `Temp/`, `.ulf`, `.alf`.
7. Ao dirigir o Editor por MCP: **ler → declarar → mutar → verificar**.
   Guardrails: `$SKILL_HOME/prompts/vibe-guardrails.md`.
8. **Sem estado `static` mutável** — cruza cenas e sobrevive a Domain Reload off;
   é fonte de bug e de teste frágil. Ver `docs/erros-comuns-unity.md`.
9. **Todo `+=` de evento tem seu `-=`** (`OnEnable`/`OnDisable` ou `OnDestroy`) —
   senão o delegate vaza entre cenas e o "objeto destruído ainda reage".
   Ver `docs/erros-comuns-unity.md`.
10. **Domínio puro não chama engine nem relógio/mundo**: `Game.Domain`/
    `Game.UseCases` não usam `Time`, `Random`, `Instantiate`, `PlayerPrefs` —
    passam por portas (`IClock`/`IRandom`/`ISpawner`/`ISaveStore`). Ver
    `docs/arquitetura-referencia.md`.

---

## Ambiente (verifique ao vivo, NUNCA presuma)

A FASE 0 já diz o que existe de fato. O que segue é o ambiente de **referência**
onde a suíte foi construída e verificada — não uma exigência:

- **Arch Linux / CachyOS**, KDE Plasma **Wayland**, GPU híbrida Intel + NVIDIA
  com PRIME offload. A Unity declara Wayland **experimental** e testa em
  GNOME/Ubuntu — se o Editor der problema de janela, force XWayland
  (ver `unity-setup`).
- A Unity **não dá suporte oficial a Arch** — só Ubuntu. Funciona, mas o
  suporte é da comunidade.
- Sem `yay`/`paru`, pacotes AUR são construídos com `makepkg -si` (é o que
  `install-unity-hub.sh` faz); fora de Arch, use a rota `--method deb`.
- Onde houver `sudo` com senha, o passo do Hub vai pedir a senha — rode-o você
  mesmo em vez de esperar que o agente resolva.

---

## Comandos de uma linha

```bash
"$SKILL_HOME/scripts/doctor.sh"                       # diagnóstico completo
"$SKILL_HOME/scripts/install-unity-hub.sh"            # Hub via AUR
"$SKILL_HOME/scripts/install-unity-editor.sh"         # última LTS com build Linux
"$SKILL_HOME/scripts/unity-license.sh" --status       # licença
"$SKILL_HOME/scripts/new-unity-project.sh" --name MeuJogo
"$SKILL_HOME/scripts/unity-run-tests.sh" --platform EditMode
"$SKILL_HOME/scripts/setup-mcp.sh" --scope all        # liga o agente ao Editor
"$SKILL_HOME/scripts/sync-global-skill.sh"            # republica a suíte
```
