Como é feito
Um desenvolvedor, um assistente de programação com IA e muitas regras verificadas por máquina.
Por Nick
Prison Life é escrito por mim junto com o Claude Code (o agente de programação da Anthropic). Eu decido o que é o jogo e quais caminhos seguimos; o assistente faz a maior parte da digitação. Como ninguém revisa o código além de mim e de um agente de IA de revisão, eu me apoio na automação: as regras são impostas por verificações automáticas e pelo build, não por boas intenções.
Delegação
A sessão principal do Claude Code planeja o trabalho e mantém o gerenciador de tarefas, o registro escrito das decisões de design e o histórico de mudanças. Ela não escreve código: entrega toda mudança, até a menor, a um agente de IA especializado. Cada um tem sua própria definição escrita, que fixa seu papel e seu modelo.
| Papel | Nível de modelo | Tarefa |
|---|---|---|
| Arquitetura | Opus | modelo de dados, tick, threads, busca de caminho, decisões |
| Código de simulação | Opus | sistemas de simulação, IA dos personagens, laços críticos |
| Desempenho | Opus | profiling, regressões de benchmark |
| Revisão (somente leitura) | Opus | revisa um diff; não pode editar arquivos |
| Cliente e ferramentas | Sonnet | cliente em Godot, interface, ferramentas |
| Testes | Sonnet | testes a partir de critérios de aceitação |
| Dados de conteúdo | Sonnet | definições JSON a partir de um esquema |
| Busca, execução de verificações | Haiku | busca no código; executar verificações e resumir as falhas |
O trabalho difícil vai para o modelo mais forte, o de rotina para os mais baratos. Se um agente de IA mais barato falha nas verificações duas vezes, a tarefa sobe um nível; se o nível mais alto falha duas vezes, ele para e me pergunta.
Hooks que dizem não
Os hooks do Claude Code são scripts que rodam em volta das ações do assistente. Os meus impõem três regras:
- Nada de terminar no vermelho. Quando uma sessão ou um agente de IA tenta parar depois de mudar código, um hook roda a verificação rápida (build mais os testes rápidos). Se ela falha, a parada é recusada.
- A sessão principal não edita código. Um hook rejeita gravações em código-fonte, testes, conteúdo e ferramentas vindas da sessão principal.
- O revisor é somente leitura. As ferramentas de edição dele são removidas e um hook rejeita comandos que alterem arquivos ou o histórico do projeto.
Isso protege contra erros, não contra burla deliberada: um truque de shell bem determinado consegue contornar, e um dos hooks vê uma verificação vermelha num agente de IA, mas não consegue segurá-lo (o hook de parada da sessão principal ainda o pega). Prefiro dizer isso com clareza.
Decisões e verificações por escrito
- Toda escolha não trivial fica registrada. Tarefas, marcos e decisões de design são mantidos como texto simples junto ao código, em um gerenciador de tarefas. Quando escolhemos entre opções que afetam mais de uma tarefa, a escolha é registrada com o contexto e as consequências.
- As verificações rodam na minha máquina. Sem CI na nuvem. Um script local tem quatro modos:
fast,test,benchefull. Scripts e hooks são PowerShell 7 tanto no Windows quanto no macOS. - Verificações a cada mudança. A automação local rejeita uma mudança mal descrita ou mal formatada. Para mudanças de código, ela também roda a verificação rápida; mudanças que só tocam em anotações ou no site pulam o build.
- Os arquivos de referência são protegidos. Hashes de determinismo fixados, arquivos de save de referência e a linha de base do benchmark só mudam com a minha aprovação explícita, nunca em silêncio.
- O próprio projeto é a fonte da verdade. Uma ferramenta de memória local indexa o projeto e as conversas passadas para busca, mas tudo que importa também vira uma tarefa, uma decisão registrada ou um documento.
O núcleo determinístico
A simulação vive em uma biblioteca .NET sem nenhuma referência a Godot; o cliente em Godot só lê o estado dela e envia comandos. O núcleo segue regras fixas: o mundo muda apenas por comandos, o tempo é medido em ticks inteiros, a aleatoriedade vem somente dos geradores com semente do mundo. A mesma semente e o mesmo registro de comandos devem dar o mesmo mundo. Essas regras são verificadas pelo compilador e pelos testes, não só pela revisão; veja o devlog #1 para saber como, e o devlog #2 para o mundo, os saves e os replays.
- Os comandos são a única porta de entrada. Cada um tem um identificador de tipo estável e uma codificação binária, e todos são registrados com seu resultado, inclusive os rejeitados.
- O tick tem três fases em ordem fixa. A ordem dos sistemas é definida em um só lugar no código, e mudá-la muda todos os hashes.
- A aleatoriedade usa geradores próprios (SplitMix64 e xoshiro256**). Os fluxos nomeados são derivados da semente do mundo e guardados no estado do mundo. Um gerador com chave e sem estado, guiado por um domínio, uma chave e o tick, atende o trabalho independente de ordem.
- O hash do estado é um hash de 64 bits sensível à ordem, para as verificações de determinismo. Não é criptográfico.
- O mundo é uma grade de blocos de 1×1 m em níveis discretos; paredes, portas e pisos só mudam por comandos de construção.
- Saves e replays compartilham um único contêiner de arquivo verificado. Um replay é a semente mais o registro de comandos, com hashes de controle ao longo do caminho, e é conferido passo a passo na reprodução.
- Os benchmarks vêm de um executor de cenários sem interface, com uma linha de base por máquina e um critério de zero alocações por tick.
A meta de projeto é até 1.000 detentos e funcionários a 20 ticks por segundo. É uma meta: ainda não há personagens, então o executor de benchmark existe, mas nada foi medido nessa escala.