wasteland_operations
Contratos e recompensa · Lua
A conclusão de uma operação é a remoção da própria linha — e só quem apaga recebe.
- Lua
- 1.277 linhas
- Tabelas
- 3
aditivas e idempotentes, verificadas no banco real
- Mecânicas
- 2
entrega e varredura, orientadas a dados
- Achados da revisão adversarial
- 3
todos corrigidos no mesmo ciclo
Fonte verificada no repositório interno em 08/09/2026
O que faz
Em uso
Operações são a ponte entre os outros quatro sistemas: o objetivo é físico (entregar material num ponto, ou permanecer numa área durante uma varredura) e a recompensa é física (item no inventário, e no chão se não couber).
Os requisitos de cada operação leem clã, cargo, posse de território e tecnologia — e são revalidados na conclusão, porque o mundo pode ter mudado no meio do caminho. A aba onde tudo isso aparece vive dentro do tablet de clã.
Este foi o ciclo que passou por revisão adversarial em cinco lentes. Três achados, todos de severidade baixa depois de verificados, todos corrigidos antes do fechamento.
Evidência
Como o sistema aparece
Capturas da interface real, renderizada com payload de demonstração derivado dos contratos do resource — organizações, cargos, pessoas e identificadores são sintéticos. Onde não existe interface, entra visualização técnica, rotulada como tal.
Visualização técnica Conclusão atômica pela remoção da operação ativa: quem apaga, recebe. A segunda requisição vê zero e sai em silêncio.
Interface do sistema A aba de Operações dentro do tablet de clã: motivo do bloqueio sempre visível, em vez de um botão que recusa.
Por dentro da engenharia
Decisões de implementação
Um bloco por decisão de implementação. Abra o que interessa.
Conclusão atômica pela remoção da operação ativa
Problema
Uma operação concluída precisa pagar exatamente uma vez. Dois cliques, uma corrida entre abandonar e concluir, ou um reinício no meio do caminho pagam duas — e recompensa duplicada em economia de survival não se corrige depois, se propaga.
Solução
A conclusão é a remoção atômica da linha de operação ativa. Quem apaga, recebe. Quem chegou depois vê zero linhas afetadas e não recebe nada. Não existe verificar-e-depois-agir: existe uma operação só.
Por que foi feito assim
A dupla recompensa deixa de ser impossível por vigilância e passa a ser impossível por construção. É a diferença entre uma checagem que alguém pode esquecer de repetir e uma propriedade do banco.
Uma operação por jogador é restrição de esquema
Problema
Limitar a uma operação ativa com uma consulta antes da inserção é uma corrida consigo mesmo: duas requisições simultâneas leem "nenhuma ativa" e ambas inserem.
Solução
Índice único sobre o jogador. A segunda inserção é recusada pelo banco, não pelo código. Validado por SQL contra o banco real: segunda inserção rejeitada, remoção de reivindicação retornando uma linha e depois zero.
Por que foi feito assim
Regra que precisa valer sempre pertence ao esquema. Código pode ser contornado por um caminho que ninguém lembrou de proteger; um índice único, não.
Falhar fechado
Problema
A revisão adversarial encontrou uma verificação de proximidade que passava aberta quando a coordenada chegava nula. Numa base com cliente hostil, "não consegui verificar" tratado como "pode" é o começo de toda conclusão remota especulativa.
Solução
A verificação passou a falhar fechada: sem coordenada válida, a conclusão é negada. O mesmo ciclo acrescentou limite de frequência às ações que ainda não tinham, para que não amplificassem carga de banco por chamada.
Por que foi feito assim
O padrão de uma verificação que não conseguiu concluir é negar. Qualquer outro padrão transforma erro de leitura em permissão.
Migração aditiva contra banco vivo
Problema
Alterar esquema de servidor em operação é onde perda de dado acontece. E a versão do banco nem sempre é a que a documentação da comunidade assume.
Solução
Todas as migrações são aditivas e idempotentes, nenhuma destrutiva, aplicadas e conferidas no banco real. Descobrir que o servidor rodava MySQL 8.0, e não MariaDB, mudou a forma de declarar índice — que passou a ser inline na criação da tabela.
Por que foi feito assim
Conferir a versão do banco antes de escrever a migração é mais barato do que descobrir pelo erro em produção.
Decisões
Decisões e trade-offs
Cada decisão registra a justificativa e o trade-off aceito.
Sistemas conversam por contratos de leitura protegidos, nunca lendo a tabela do vizinho.
Um sistema que lê direto o banco do outro fica preso ao esquema dele para sempre, e uma migração inocente quebra o vizinho.
Custo aceito · Mais indireção e uma chamada a mais por consulta — aceito porque nenhum sistema consegue corromper o estado do outro.
Toda recompensa é item que já existe no jogo, conferido no catálogo antes de entrar no código.
Recompensa que aponta para item inexistente falha em silêncio, e o jogador conclui a operação sem receber nada.
Custo aceito · Cada operação nova depende de o catálogo estar atualizado, o que acopla o desenho da mecânica ao inventário.
Escopo
Implementado e pendente
Estado atual do projeto.
Concluído
- Motor de operações orientado a dados, cobrindo entrega e varredura
- Três tabelas criadas e conferidas no banco real, nenhuma migração destrutiva
- Recompensa física com conferência de peso e queda no chão quando não cabe
- Aba de operações integrada ao tablet de clã, por contrato de leitura
Pendente
- Coordenadas dos pontos físicos, ainda em posição provisória
- Homologação com jogadores no servidor
O ciclo fechou com verificação estática, conferência de esquema no banco real e revisão adversarial. O que ainda não aconteceu é o teste com jogadores em partida — e nada aqui declara que aconteceu.
Stack
O que foi usado
Servidor
- Lua
- FiveM
- vRP
Dados
- MySQL 8.0
- Migrations aditivas e idempotentes
- Índice único como invariante
Integração
- Leitura protegida de clã, tecnologia e território
- Aba embutida no tablet de clã
Processo
- Verificação estática de Lua e JavaScript
- Revisão adversarial por lentes
- Homologação com comando dedicado