Backup e Versionamento Seguro de Dados Roblox
Este prompt produz uma implementação profissional de backup e versionamento de dados de jogador para Roblox, ideal para jogos que evoluem o formato de inventário, moedas, progressão, pets, missões ou estatísticas persistentes. O sistema detecta versões antigas, executa migrações controladas e preserva snapshots recuperáveis antes de alterações críticas.
A saída solicitada inclui um ModuleScript central e um Script de inicialização no servidor, com DataStoreService, UpdateAsync, validação estrutural, tentativas com backoff, controle de sessão, limites de histórico e logs úteis. O foco é segurança, integridade de dados e operação realista em produção, sem confiar no cliente.
O prompt também pede que o desenvolvedor informe a estrutura real do próprio jogo, como nomes de DataStores, módulos, RemoteEvents e formato atual dos perfis. Assim, o código gerado pode ser adaptado ao Explorer existente e ficar pronto para colar e testar no Roblox Studio.
Atue como um desenvolvedor Roblox sênior especializado em Luau, DataStoreService, migrações de schema e sistemas de persistência seguros para jogos em produção. Crie um sistema completo de backup e versionamento dos dados de jogador entre atualizações, adaptado ao contexto do meu jogo que fornecerei abaixo. O objetivo é permitir que mudanças futuras no formato dos dados — como novos campos de inventário, moedas, progresso, pets, missões, habilidades ou configurações — sejam migradas sem perda de dados e com possibilidade de recuperação de snapshots anteriores. Antes de escrever o código, considere e utilize o contexto que vou colar ao final deste pedido. Ele poderá conter nomes reais de objetos no Explorer, nome do DataStore atual, estrutura da tabela de perfil, módulos existentes, sistema de carregamento/salvamento já utilizado, RemoteEvents/RemoteFunctions existentes, convenções de atributos e requisitos de gameplay. Se alguma informação essencial estiver ausente, faça no máximo 5 perguntas objetivas antes de gerar o código. Se eu não responder, adote nomes configuráveis no topo do módulo e documente claramente as premissas; não invente dependências externas nem objetos que não sejam necessários. Arquitetura obrigatória: gere 2 arquivos completos. O primeiro deve ser um ModuleScript chamado `PlayerDataVersioning`, localizado em `ServerScriptService/Modules/PlayerDataVersioning` (ou no caminho equivalente indicado por mim). Ele será responsável por schema atual, normalização de dados, validação, migrações incrementais, criação e leitura de backups, serialização segura quando necessária e políticas de retenção. O segundo deve ser um `Script` chamado `PlayerDataVersioningBootstrap`, localizado em `ServerScriptService`, responsável por conectar `Players.PlayerAdded`, `Players.PlayerRemoving` e `game:BindToClose()`, coordenar carregamento/migração/salvamento e integrar-se ao meu sistema existente. Se meu jogo já possuir um serviço de perfil, adapte o bootstrap para chamá-lo sem duplicar carregamentos ou salvamentos concorrentes. Implemente uma estratégia de dados robusta: use um DataStore principal para o perfil atual e um DataStore separado para backups versionados, com chaves determinísticas baseadas no `UserId` e identificador de snapshot. Toda alteração persistente deve usar `UpdateAsync`, nunca `SetAsync` como mecanismo principal de atualização concorrente. Inclua uma constante explícita `CURRENT_SCHEMA_VERSION`, um campo `SchemaVersion` dentro do perfil e uma tabela/roteador de funções de migração incremental, por exemplo da versão 1 para 2, de 2 para 3, até a versão atual. As migrações devem preservar campos desconhecidos sempre que possível, preencher valores padrão de modo não destrutivo, validar tipos, impedir valores inválidos e falhar de forma segura caso uma migração seja impossível. Antes de aplicar uma migração relevante, crie um snapshot do perfil bruto no DataStore de backups, contendo pelo menos `UserId`, versão de origem, versão de destino planejada, horário UTC (`os.time()`), motivo do backup, identificador único de snapshot e os dados originais. Não salve dados Lua não serializáveis, instâncias, funções, userdata ou chaves incompatíveis com DataStore. Implemente retenção configurável, por exemplo manter apenas os 5 backups mais recentes por jogador, e explique no código uma estratégia segura para listar/limpar metadados sem gerar consumo excessivo de orçamento. Caso a listagem completa de backups não seja viável diretamente com DataStoreService, use um índice de snapshots por jogador mantido com `UpdateAsync` e trate falhas de forma resiliente. Inclua também uma função de restauração manual, exclusivamente no servidor, como `RestoreBackup(userId, snapshotId)`, protegida para uso administrativo por uma lista configurável de UserIds autorizados ou por uma função de autorização que eu possa conectar ao meu sistema de admin. Não exponha restauração, backups, moeda, inventário, dano ou decisões persistentes ao cliente. Não crie RemoteEvents novos sem necessidade. Se eu informar RemoteEvents existentes, trate qualquer solicitação recebida por eles como não confiável: valide tipo, limites, permissão, estado do jogador e dados no servidor antes de executar qualquer ação. O cliente jamais deve informar versão do schema, conteúdo do perfil, saldo, inventário ou qual backup restaurar sem validação autoritativa no servidor. Implemente tratamento de erro profissional: `pcall` em chamadas de DataStore, tentativas limitadas com exponential backoff e jitter, mensagens de log contextualizadas, prevenção de operações simultâneas para o mesmo jogador, timeout de carregamento e comportamento definido quando o DataStore falhar. Priorize não sobrescrever dados possivelmente mais novos. Se não for seguro salvar, mantenha o jogador em estado protegido e explique, em comentário, a política adotada. Considere encerramento de servidor com `BindToClose`, limite de orçamento do DataStore e jogadores saindo durante operações pendentes. Entregue a resposta em português do Brasil e nesta ordem: 1) resumo da arquitetura e das premissas; 2) árvore exata de onde inserir cada arquivo no Explorer; 3) código completo do ModuleScript; 4) código completo do Script Bootstrap; 5) instruções de integração caso já exista um gerenciador de dados; 6) checklist de testes no Roblox Studio. Cada arquivo deve estar em seu próprio bloco Markdown usando exatamente ```lua, sem pseudocódigo, sem trechos omitidos e sem usar `...` como substituto de lógica. Comente o código de forma útil, especialmente migrações, concorrência, backups, retenção e segurança. Ao final, ensine como testar com jogadores simulados, como alterar artificialmente uma versão antiga, como confirmar um backup criado, como simular falhas e como validar uma restauração sem arriscar dados de produção. Contexto do meu jogo para adaptar a solução: [COLE AQUI a árvore relevante do Explorer, DataStore(s), formato atual do perfil, versão/schema existente, módulos de dados, RemoteEvents/RemoteFunctions, IDs de administradores, frequência de salvamento e requisitos específicos.]