Um tick a cada 15 minutos (beta) ou 1h (prod). O que o engine faz, como persiste, e por que é idempotente.
O Trambique não é um jogo turn-based onde você decide quando avançar. O ciclo é global, temporal, e inevitável.
A fórmula é simples: cycleNumber = floor((agora - epoch) / intervalo). Epoch é 1 de janeiro de 2026, intervalo é 15 minutos no beta (60 minutos em produção). Cada ciclo tem um número global único.
Você não pode "pular ciclo". Você não pode "rodar ciclo manualmente". O servidor processa quando o relógio bate. Você fica online ou não — o mundo continua.
Multiplayer real. Se cada jogador rodasse ciclo sob demanda, ranking ficaria sem sentido (compara estados em momentos diferentes). Ciclo global = mesma régua pra todo mundo.
Pra cada unidade ativa no jogo:
A constraint @@unique([businessUnitId, cycleNumber]) na tabela GameCycle garante: um tick processado duas vezes não duplica o resultado.
Se o cron bate dobrado ou atrasa, a segunda tentativa é noop. Você nunca perde nem ganha por bug de infraestrutura.
accruedSalary).O tick é disparado por GitHub Action a cada hora cheia (produção). Em dev, pnpm cycle:tick força um. Nunca processa lazy ao abrir página — engine precisa rodar pra todos, sempre, pra ranking ter sentido.