# Replicando o Fable com o Opus: um experimento de criação de jogos

- Author: Foad Kesheh
- Published: 2026-06-17
- Reading time: 14 min
- Tags: IA, Agentes de Codificação, Multiagente, Orquestração, Three.js, Claude
- URL: https://www.fmktech.com.br/pt-BR/blog/replicating-fable-with-opus.md (HTML: https://www.fmktech.com.br/pt-BR/blog/replicating-fable-with-opus)

Um jogo 3D construído por agentes em paralelo, o contrato e o processo de revisão por trás dele e comparações jogáveis do que mudou com uma direção de arte explícita.

---

*Revisado em 4 de setembro de 2026. Este é o relato do autor sobre execuções individuais, não um benchmark auditado de forma independente. Tempos e contagens de código se referem a essas execuções; os nomes dos modelos foram mantidos conforme registrados no experimento.*

**▶ Video: A versão curta — o experimento original de criação de jogos e o papel do contrato compartilhado.:** [watch video](/blog/medieval/fable-findings-explainer.mp4)

## O prompt de uma linha que construiu um jogo

Começou como um experimento, não como um projeto. Em uma conta pessoal do Claude, com o esforço máximo de raciocínio ativado, eu digitei uma única frase:

> "Crie um jogo de sobrevivência medieval, formato RTS, muitos recursos, fazendas, comidas, tudo muito detalhado, 3D."

Esse foi o briefing inteiro. Sem documento de design, sem lista de arquivos, sem arquitetura. Eu saí de perto.

Noventa minutos depois eu voltei e encontrei um RTS de sobrevivência medieval 3D completo, jogável, rodando no navegador. Era muito mais que uma cena vazia, embora ainda fosse um build experimental. Um jogo com terreno ondulado, ciclo de dia e noite com estrelas visíveis, florestas em aglomerados, uma economia funcional — colher madeira e pedra, transformar trigo em farinha e em pão, caçar veados, formar um exército — e dez invasões noturnas cada vez mais difíceis que você precisa sobreviver, sob pena de perder sua prefeitura.

O resultado final: **38 arquivos TypeScript, 11.826 linhas de código** (10.591 TS, 1.085 CSS, 150 HTML). Uma única tentativa. Nenhuma lógica de jogo escrita por humanos.

**▶ Video: O build original do Fable 5, gravado no desktop.:** [watch video](/blog/medieval/fable.mp4)

Não é apenas um vídeo — o build original é jogável aqui mesmo no seu navegador:

**▶ Jogue o build original do Fable:** [play demo](/games/fable-medieval-survivors/index.html)

Minha primeira reação foi a óbvia: "O Fable 5 é incrível." Mas então fiz algo que mudou toda a conclusão. Abri o repositório e li *como* ele havia sido construído.

## A surpresa: 94% disso foi o Sonnet, não o Fable

Quando você vê um agente autônomo produzir um jogo em 90 minutos, a suposição natural é que o modelo principal fez todo o trabalho pesado. Não fez.

Lendo o histórico do git e os artefatos de orquestração, eis o que o Fable 5 de fato escreveu com seus próprios tokens:

- **Três arquivos-fonte** — um contrato de tipos congelado, um arquivo de dados de balanceamento e uma biblioteca de primitivas de mesh.
- **Um script de workflow** — a orquestração que constrói todo o resto.
- Alguns documentos de planejamento.

Isso dá aproximadamente **754 linhas de código nos três arquivos de contrato** — cerca de **6% da base de código final**. Os **94%** restantes — cada entidade, cada sistema, cada mesh de construção, a UI, o loop do jogo — foram escritos por **subagentes Sonnet 4.6** que o Fable iniciou e coordenou.

Ele **não usou git worktrees**. O build concorrente aconteceu em uma árvore compartilhada, com arquivos atribuídos a responsáveis distintos e um contrato comum. Isso reduziu conflitos de edição, mas a integração ainda exigiu compilação, revisão e verificações de execução.

Isso reformula completamente a conquista. A pergunta deixa de ser "quão bom o Fable é em escrever jogos?" e passa a ser a muito mais útil: **"quão bom o Fable é em fazer prompting do Sonnet para escrever jogos?"** Porque essa habilidade é transferível. Você pode copiar um prompt. Você não pode copiar os pesos de um modelo.

## Registre decisões compartilhadas em um contrato de código

Uma decisão útil foi commitar três arquivos compartilhados antes da implementação e mantê-los estáveis durante o build paralelo. O workflow também incluía documentos de planejamento; o contrato de código deixava decisões importantes de interface e aparência diretamente disponíveis a cada implementador. Ele complementava o planejamento, não o substituía.

| Arquivo | Linhas | Papel no plano |
| --- | --- | --- |
| `src/types.ts` | 366 | O contrato de tipos inteiro — `IGameCtx`, `IUnit`, `IBuilding`, `IResourceNode`, `IEnemy`, cada interface de serviço, e um único mapa tipado `EventPayloads` indexado por uma união de nomes de evento. Um nome de evento digitado errado ou inventado simplesmente não compila. **Imutável.** |
| `src/config/gameData.ts` | 266 | Dados compartilhados de balanceamento: atributos de construções/unidades/inimigos, cronograma de 10 ondas, melhorias, trocas e constantes do mundo. Congelados durante o build. Centralizar esses valores permitia ajustá-los sem alterar cada módulo consumidor. |
| `src/meshes/common.ts` | 122 | O vocabulário low-poly compartilhado — `box()`, `cyl()`, `cone()`, `sphere()`, `place()`, uma `PALETTE` de cores, um agrupador de draw-calls `bakeGroup()` e um `rng()` com seed. Para que toda a arte parecesse vir de uma só mão. |

Essas 754 linhas impunham restrições ao restante do build. Interfaces tipadas ajudavam a encontrar nomes e assinaturas incompatíveis na compilação; dados e helpers compartilhados reduziam escolhas inconsistentes. Isso não tornava impossível a divergência de interfaces ou os bugs de integração: agentes ainda podiam interpretar os mesmos tipos de formas diferentes ou implementar o comportamento errado.

## Oito módulos sem sobreposição

A base de código foi cortada em oito grupos de arquivos, desenhados de modo que dois agentes jamais tocassem no mesmo arquivo. Toda referência entre módulos era resolvida via `types.ts`; importações de classes concretas só eram permitidas onde o contrato as nomeava explicitamente.

- **core** — eventBus, input, cameraController, sound
- **world** — noise, terrain, water, grid, dayNight, worldGen
- **meshes-buildings** — props, buildings
- **meshes-units** — units, fx
- **entities** — entity, resourceNode, building, unit, enemy, animal
- **systems** — pathfinding, combat, waves, production
- **ui** — index.html, styles, hud, buildMenu, selectionPanel, minimap, messages, overlays
- **game** — o integrador: game, selection, commands, placement, main

Cada grupo foi para um agente implementador. Todo agente recebeu os mesmos dois preâmbulos — um bloco de `RULES` (regras) e uma especificação `CONTRACT` completa — e depois seu próprio briefing de módulo. Eis o bloco de RULES, na íntegra:

```markdown
# Project rules (apply to every file you write)
- Repo root: /Users/fkesheh/medieval. All paths below are relative to it.
- TypeScript STRICT mode. Never use "any" (use precise types or "unknown" +
  narrowing). Named exports only. No default exports.
- Import three as: import * as THREE from 'three'. Relative imports between
  src files (e.g. import type { IGameCtx } from '../types').
- FIRST read these three contract files. They are FINAL — never modify them:
  src/types.ts, src/config/gameData.ts, src/meshes/common.ts.
- Implement interfaces from src/types.ts EXACTLY (names, signatures, semantics).
- Create ONLY your assigned files. Other modules are being written in parallel
  by other agents against the same contract — import from their documented
  paths and trust the documented exports.
- Do NOT run npm, tsc, vite or any dev server (node_modules may be mid-install;
  a later phase compiles). Write careful, complete, production-quality code with
  zero TODOs and zero placeholder stubs.
- Code comments: only where a constraint is non-obvious. No narration comments.
- This is a real, finished game, not a demo: handle edge cases (empty selection,
  depleted nodes, dead targets, no path found, unaffordable costs).
```

As regras davam limites explícitos a cada agente e pediam tratamento dos casos extremos. Descreviam o resultado desejado, não garantiam que todos os exports existissem ou que o jogo estivesse finalizado. Isso ainda precisava ser verificado depois de reunir os módulos.

## O workflow de build: seis fases, um script

O plano não parou em "escreva o código". Um único script de orquestração codificou seis fases — um fan-out para construir, seguido por um teste adversarial para endurecer:

1. **Implementar** — oito agentes de módulo (Sonnet) constroem simultaneamente contra o contrato congelado. Zero arquivos compartilhados.
2. **Compilar** — rodar `tsc --noEmit`; um relator Haiku barato agrupa os erros por arquivo; até oito corretores Sonnet os reparam em paralelo. Loop de ≤ 6 rodadas até o verificador de tipos ficar em silêncio.
3. **Revisar** — cinco revisores (Sonnet), cada um com uma lente distinta, caçam bugs de integração e de runtime.
4. **Verificar** — cada achado sério vai para um cético independente cujo *veredito padrão é "não é um bug real".* O ônus da prova recai sobre o achado; o verificador precisa citar o caminho exato de código que se comporta mal para afirmar que ele é real. Isso buscava reduzir falsos positivos, não eliminá-los.
5. **Corrigir** — bugs confirmados agrupados por arquivo, um corretor por arquivo para que as edições nunca colidam. **15 bugs reais** reparados.
6. **Portão (Gate)** — `tsc --noEmit && vite build` precisam passar os dois. Passou na primeira tentativa (~647 kB JS, ~168 kB gzip).

As cinco lentes de revisão foram deliberadamente diversas — **lifecycle** (loop do jogo e ciclo de vida das entidades), **economy** (colher → construir → cultivar → comida), **combat** (dano, torres, timing das ondas), **ui-wiring** (ids do DOM e argumentos de construtor) e **visual** (meshes, sombras, alocações em caminhos quentes). Revisar e Verificar foram *pipelinados*, não sequenciais: os achados de cada lente eram verificados no momento em que aquela lente terminava, então o revisor mais lento nunca travava a verificação do mais rápido.

Um detalhe sutil mas importante: todo o pipeline rodou em **Sonnet, com um único relator Haiku** — seis papéis Sonnet mais um passo Haiku barato. O custo foi escalonado conforme a dificuldade da tarefa, não nivelado pelo modelo mais caro.

## O que mudou com uma direção de arte explícita

Eis o achado que mais importa, e ele só surgiu quando refiz o experimento com seeds diferentes para comparar.

Construí mais duas versões da mesma ideia com a mesma abordagem de orquestração, mas com **contratos diferentes**, e as comparei à original. As três usavam **agentes Sonnet** na implementação. As diferenças visuais sugeriam que a quantidade e a localização da direção de arte importavam. Eram execuções individuais, não um experimento controlado que isolasse todas as fontes de variação.

O seed da original deu ao Sonnet um *vocabulário* — uma paleta, primitivas, um `bakeGroup()`. Mas o seed **não continha nenhuma** das ~3.900 linhas de código visual. O Sonnet escreveu todas elas, guiado pelo **prompt do CONTRACT**, que especificava à mão a aparência de quase todos os arquivos. Leia esses trechos na íntegra e você verá a diferença:

> "DETAILED and distinctive, **15-40 primitives each**… townhall = grand two-story timber-framed hall, stone base, banners, torch posts; house = cottage w/ thatched roof + chimney…"

> "warm dawn, golden dusk, **deep blue night with visible stars**… a Points starfield only visible at night… small glowing sun & moon sphere meshes orbiting the sky."

> "VERTEX COLORS: sandy near water level, grass greens with noise-driven dirt patches, gray rock on steep slopes…"

E o briefing de módulo do agente de mesh das construções literalmente enquadrou o trabalho como um ofício:

> "Focus: **this is the art department.** Every building must be instantly recognizable at RTS camera distance and charming up close — generous primitive counts, color variation via PALETTE, small storytelling details (barrels, sacks, fences, banners)."

Agora contraste isso com um dos meus seeds refeitos, cuja *inteira* direção de arte do renderizador era uma única frase: "Implement the Three.js renderer… It must be visually nonblank and detailed without external binary assets." Sem paleta, sem "260 árvores em aglomerados", sem clima de iluminação, sem silhuetas por construção, sem "departamento de arte". O resultado? Um renderizador competente, genérico, em arquivo único, com cores improvisadas sobre um plano quase vazio. O mesmo padrão se manteve quando tentei replicar o jogo com o **Opus** e com o **GPT-5.5** como arquiteto: deixados para escrever seus próprios contratos, ambos produziram apenas uma direção de arte rasa — estruturalmente sólida, mas nada parecida com a prosa do Fable, por construção e por clima. Os jogos saíram corretos e sem graça.

Nessas execuções, briefings de implementação mais ricos vieram acompanhados de visuais mais ricos. A revisão visual procurava defeitos e não acrescentou depois a direção de arte ausente. Isso torna o briefing uma variável útil para melhorar e testar; não demonstra que a capacidade do modelo ou a variação entre execuções seja irrelevante.

## Replicando por conta própria, com o Sonnet

Para testar se a abordagem podia ser reutilizada, preservamos o script de orquestração — incluindo os prompts de subagentes e o modelo de cada papel — e refizemos o build a partir do scaffold congelado de 3 arquivos.

Funcionou. O mesmo seed contract-first, conduzido pelo mesmo workflow Sonnet de seis fases, produziu a mesma classe de resultado: um RTS 3D detalhado e jogável, construído quase inteiramente por agentes Sonnet.

**▶ Video: Agentes Sonnet executando o workflow preservado, criado pelo Fable.:** [watch video](/blog/medieval/fable-replication-sonnet.mp4)

Os artefatos reutilizáveis não eram apenas o código gerado, mas também **o workflow e o contrato que o produziram**. Preservá-los permitiu novos testes. Reexecutar o workflow não garante uma saída idêntica; cada resultado ainda precisa ser inspecionado.

## Opus vs. Opus: mais modelo não é mais jogo

A próxima questão que testei foi o que aconteceria se o Opus cuidasse da implementação e da arquitetura.

Rodei a mesma ideia com **Opus 4.8 no esforço máximo**, usando o Opus também para o trabalho de implementação. O build levou **2 horas e 52 minutos** e produziu **~12.500 linhas de código** — um pouco mais de código, muito mais computação, muito mais tempo de relógio.

Foi **pior como jogo.** Sem animações. Jogabilidade inferior — por exemplo, escolher a função de um camponês exigia selecionar uma opção em uma combo box em vez do fluido clicar-com-o-botão-direito-para-atribuir do build Sonnet. A capacidade extra do modelo não se traduziu em um jogo melhor de se *jogar* nem melhor de se *ver*.

**▶ Video: A execução toda em Opus: resultado registrado nesse teste.:** [watch video](/blog/medieval/opus-opus.mp4)

Minha avaliação foi que o resultado todo em Opus era menos divertido e visualmente menos desenvolvido. Os testes diferiam nos briefings e na execução, então a comparação não isola a qualidade do modelo nem estabelece uma classificação geral de custo. Ela me deu um motivo concreto para melhorar a direção de arte e interação antes da próxima rodada.

## Testando um workflow Opus-planeja / Sonnet-constrói

A próxima configuração que testei separava arquitetura de implementação:

- **Opus como arquiteto.** Escrever o contrato compartilhado, distribuir módulos separados e descrever o design visual e de interação desejado.
- **Sonnet como implementador.** Construir os módulos conforme o contrato e depois executar integração e revisão. É uma configuração dos nossos testes, não uma escolha comprovadamente superior para todo projeto.

Para testar, peguei os achados acima e construí um workflow deliberadamente *com direção de arte* no estilo Opus-planeja / Sonnet-constrói — o "prompt especial" — antecipando silhuetas por construção, um clima de iluminação, densidade de mundo, ganchos de animação e uma linha de trabalho dedicada de departamento de arte, exatamente como o CONTRACT original fazia. A qualidade visual e de jogabilidade subiu na mesma proporção. O prompt exato que conduziu essa regeneração está em código aberto aqui: [contract-first-game-build.md](https://github.com/fkesheh/fmk-plugins/blob/main/plugins/single-shot-game-generation/prompts/contract-first-game-build.md).

**▶ Video: O teste Opus-planeja / Sonnet-constrói com direção de arte mais explícita.:** [watch video](/blog/medieval/opus-sonnet-special-prompt.mp4)

Quer ver como um desses builds realmente joga? Aqui está um jogo ao vivo, no navegador — **Hearthwatch** — gerado de ponta a ponta exatamente por este workflow contract-first com direção de arte. Não exige instalação manual; o navegador carrega o jogo e seus recursos:

**▶ Jogue Hearthwatch (Opus → Sonnet):** [play demo](/games/opus-sonnet-hearthwatch/index.html)

A conclusão que um colega tirou quando compartilhei isso internamente foi o resumo mais limpo que já ouvi: *"Então o Sonnet em si é bom — a gente só não sabia como usá-lo?"* Sim. É exatamente isso.

## O mesmo prompt, modelos diferentes — jogue todos

Depois executei o mesmo [prompt em código aberto](https://github.com/fkesheh/fmk-plugins/blob/main/plugins/single-shot-game-generation/prompts/contract-first-game-build.md) com outras configurações de modelos, cada uma responsável por arquitetura e implementação. Os jogos resultantes tinham estilos visuais e escolhas de interação diferentes. Os artefatos permitem comparar diretamente as saídas; não constituem um benchmark estatisticamente controlado de modelos.

### Opus → Opus, com o prompt dirigido em arte — *Hearthhold*

Lembra da rodada anterior, toda em Opus, que saiu sem graça e sem animações? Aquilo era o Opus apontado para um briefing *raso*. Dê a essa mesma dupla Opus-constrói-tudo o contrato com direção de arte, e ela entrega isto:

**▶ Video: O teste todo em Opus usando o prompt ampliado com direção de arte.:** [watch video](/blog/medieval/opus-opus-newprompt.mp4)

**▶ Jogue Hearthhold (Opus → Opus):** [play demo](/games/opus-opus-hearthhold/index.html)

### GLM-5.2 como arquiteto e executor — *Hamlet*

**▶ Video: O teste com GLM-5.2 usando o prompt compartilhado.:** [watch video](/blog/medieval/glm-newprompt.mp4)

**▶ Jogue Hamlet (GLM-5.2):** [play demo](/games/glm-hamlet/index.html)

### GPT-5.5 como arquiteto e executor

**▶ Video: O teste com GPT-5.5 usando o prompt compartilhado.:** [watch video](/blog/medieval/gpt5-newprompt.mp4)

**▶ Jogue o build do GPT-5.5:** [play demo](/games/gpt-medieval-survivor/index.html)

Os jogos acima mostram o que essas execuções produziram. Uma comparação mais ampla exigiria repetições, orçamentos comparáveis e critérios explícitos para jogabilidade, qualidade visual, correção e custo. A escolha do modelo continua sendo algo a avaliar conforme esses requisitos.

## O que isso significa para construir software de verdade com IA

Estas são as práticas que eu levaria para um próximo projeto de software:

1. **Explicite as interfaces compartilhadas.** Coloque tipos e formatos de dados estáveis em código, junto ao registro escrito de requisitos e decisões. A verificação de tipos valida apenas as restrições que os tipos expressam.
2. **Defina responsáveis e integre deliberadamente.** Arquivos separados reduzem colisões de edição. Não garantem interpretações compatíveis, comportamento correto ou execução segura.
3. **Descreva qualidade de forma concreta.** Especifique expectativas visuais, de interação, acessibilidade e tratamento de erros. Depois inspecione a saída; pedir essas qualidades não prova que foram entregues.
4. **Exija evidência dos achados e execute o sistema.** Um revisor independente deve demonstrar um defeito suspeito ou marcá-lo como não confirmado. Revisão estática não substitui um playtest ou teste de ponta a ponta.
5. **Compare configurações na tarefa real.** Meça resultados aceitos, latência e custo total, incluindo revisão e novas tentativas, antes de decidir quais papéis justificam modelos mais capazes.
6. **Preserve o workflow e suas evidências.** Guarde contrato, prompts, configuração das ferramentas, verificações e falhas observadas para avaliar outra execução conforme os mesmos objetivos.

Na FMKTech, esse experimento orienta nossa abordagem de entrega assistida por agentes: limites explícitos, verificações de integração e revisão do resultado em uso. Um protótipo de jogo não é um sistema empresarial de produção; este também exige controles operacionais, segurança, manutenção e um plano de migração quando há dados existentes.

Se você está considerando trabalho assistido por agentes em um produto existente, comece pelo [guia de modernização de software legado](/pt-BR/blog/ai-coding-brownfield-projects) ou [converse conosco sobre seu projeto](/pt-BR#contact).

---

## Onde procurar depois

- [Índice do blog](https://www.fmktech.com.br/pt-BR/blog.md)
- [Homepage](https://www.fmktech.com.br/pt-BR.md)
- [llms.txt](https://www.fmktech.com.br/llms.txt)
