Andrade Systems
Em desenvolvimentoFiveM

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.

  1. 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.

  2. 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