Reino do Ritmo
Seis comarcas, cada uma com um estilo de música, onde se coletam notas, se criam criaturas que tocam junto e se abre a próxima comarca. Feito para uma criança de sete anos jogar.
A decisão central
A regra do jogo não conhece o Roblox. O núcleo é Luau puro, sem uma linha de game,
workspace, Instance ou task, e é onde vivem economia, sorteio de raridade, renda offline,
streak e validação de coleta. O que roda dentro do Roblox é uma camada fina que aplica esse núcleo e
desenha o resultado.
A consequência prática é a mesma de Onde está o Gato: a maior parte do jogo é testável sem abrir o Studio, com a suíte rodando headless em milissegundos. A alternativa seria abrir o editor para conferir se a renda offline respeita o teto de horas, o que é lento o bastante para que na prática ninguém confira.
Manter o núcleo puro exigiu três camadas
Foi a parte mais interessante do projeto, e a que eu não teria previsto:
| Camada | O que ela pega |
|---|---|
| Linter configurado com a biblioteca padrão da linguagem, não a do Roblox | game, workspace, Instance, task |
| Guard no CI | os.time, os.clock, tick, math.random — Luau legítimo, mas que quebra determinismo |
| A suíte rodando fora do Roblox | tudo: um módulo que toca no runtime simplesmente não executa |
A terceira é a que prova. As duas primeiras existem para a falha chegar cedo e apontar para o lugar certo, em vez de aparecer como teste vermelho sem explicação.
Uma armadilha que custou descoberta: o linter não cascateia configuração por diretório. Rodar apontando para a pasta do núcleo ignora a configuração restrita dali e usa a da raiz, que carrega a biblioteca do Roblox e aprova exatamente o que deveria barrar. Só a forma explícita pega, e é a que o CI usa.
O que atravessou de stack para stack
Este projeto é a tradução dos meus padrões de .NET para Luau: arquitetura em camadas com a dependência apontando para dentro, notificação em vez de exceção, relógio e sorteio injetados em vez de acessados direto.
O que não atravessou está documentado com a mesma honestidade, porque é onde a tradução de padrão costuma virar cargo cult: nem tudo que faz sentido num domínio corporativo com persistência relacional faz sentido num save de agregado único. Identidade, repositório e evento de domínio, por exemplo, não ganham nada aqui.
Sobre as pessoas no jogo
Dois NPCs são homenagem a crianças reais, com primeiro nome e aparência estilizada. Nada que identifique ninguém.
Ver também
Onde está o Gato · Modelagem de domínio, DDD e CQRS · Padrão que a máquina consome