Inventário Persistente Completo com DataStore Seguro
Gere um sistema profissional de persistência de inventário para Roblox, capaz de salvar e carregar itens com ID, quantidade e raridade entre sessões. O prompt orienta a IA a respeitar a arquitetura já existente no seu jogo, usando os nomes reais de pastas, RemoteEvents, módulos e objetos informados por você.
A solução solicitada prioriza segurança e confiabilidade: o servidor é autoritativo, dados vindos do cliente são validados, o DataStore é acessado com proteção contra falhas e o salvamento ocorre em momentos adequados, incluindo saída do jogador e encerramento do servidor. Ideal para RPGs, simuladores, jogos de coleta, survival e experiências com loot.
Além do código completo e comentado, o prompt exige instruções claras de instalação, configuração e testes no Roblox Studio, para que o resultado possa ser adaptado e colado diretamente no projeto.
Atue como um desenvolvedor Roblox sênior, especialista em Luau, DataStoreService, arquitetura servidor-autoritativa e sistemas persistentes de inventário. Desenvolva um sistema completo, robusto e seguro para salvar e carregar o inventário dos jogadores, preservando item, quantidade e raridade entre sessões. Antes de escrever o código, considere e utilize o contexto abaixo. Caso algum campo esteja vazio, adote convenções profissionais, declare explicitamente as suposições feitas e mantenha a implementação fácil de adaptar: [COLE AQUI O CONTEXTO DO MEU JOGO] - Onde o inventário atual é armazenado: (ex.: Folder no Player, atributos, tabela em ModuleScript, sistema próprio) - Estrutura de cada item: (ex.: ItemId, Amount/Quantidade, Rarity/Raridade, outros metadados) - Lista/catálogo oficial de itens e raridades: (caminho no Explorer ou descrição) - Nomes e caminhos reais no Explorer: (pastas, módulos, RemoteEvents/RemoteFunctions existentes) - RemoteEvents/RemoteFunctions já usados pelo inventário e suas assinaturas: - Formato de UI, se houver, e como ela é atualizada: - Limite de slots, limite de quantidade por item e regras de empilhamento: - Itens que não podem ser salvos, itens iniciais e regras de migração de dados: - Nome desejado para o DataStore e versão/schema atual, se existir: - Outros sistemas que alteram o inventário (loja, loot, trade, crafting, recompensa etc.): [FIM DO CONTEXTO] Entregue uma solução em arquitetura de produção composta por: 1) um ModuleScript chamado InventoryService, localizado em ServerScriptService/Modules/InventoryService; e 2) um Script chamado InventoryPersistence.server.lua, localizado em ServerScriptService. Se a integração com uma interface existente exigir sincronização, inclua somente os RemoteEvents estritamente necessários em ReplicatedStorage/Remotes, descrevendo como criá-los. Não faça o cliente salvar, conceder, remover, definir raridade ou validar itens; toda autoridade de inventário e persistência deve permanecer no servidor. O sistema deve usar DataStoreService com um nome versionado, como InventoryData_v1, e chaves baseadas em UserId. Defina um schema serializável, sem Instances, funções, userdata ou tabelas com chaves inválidas. Cada entrada de item deve conter, no mínimo, itemId (string), quantidade (number inteiro positivo) e raridade (string). Inclua schemaVersion e, se apropriado, campos de metadados seguros. Crie uma função de normalização e validação para dados carregados: descarte registros malformados, limite quantidades conforme as regras fornecidas, valide itemId contra o catálogo oficial no servidor e valide raridade contra valores permitidos ou contra a raridade oficial do item. Nunca aceite uma raridade, ID ou quantidade enviada pelo cliente sem validação independente no servidor. Implemente APIs server-side claras no módulo, como LoadInventory(player), GetInventory(player), AddItem(player, itemId, amount, rarityOpcional), RemoveItem(player, itemId, amount), SaveInventory(player) e ClearCache(player). Proteja operações contra corrida usando um lock por jogador ou fila de salvamento. Ao salvar, use UpdateAsync em vez de SetAsync quando apropriado, pcall, tentativas com backoff exponencial moderado e mensagens de warn detalhadas sem expor dados sensíveis. Evite exceder limites de requisição: use autosave com intervalo configurável e não salve a cada alteração individual. Controle alterações com dirty flag; salve em PlayerRemoving e trate BindToClose aguardando, dentro de um limite razoável, os salvamentos pendentes. Caso sejam necessários RemoteEvents para a UI, trate-os apenas como pedidos de leitura ou ações permitidas. Valide no servidor tipo, tamanho, taxa de chamadas e permissões dos argumentos recebidos. Não implemente RemoteEvent que aceite do cliente uma tabela inteira de inventário para salvar. Caso o projeto já possua remotes no contexto, adapte-se a eles em vez de criar duplicatas. Retorne ao cliente apenas uma cópia sanitizada dos dados necessários para exibição. Forneça o resultado em português do Brasil, sem pseudocódigo e sem omitir trechos essenciais. Organize a resposta nesta ordem: visão geral da arquitetura; árvore exata de objetos no Explorer; código integral de cada arquivo, cada um em seu próprio bloco markdown ```lua, com cabeçalho informando tipo e localização; passos de integração com o inventário existente; e roteiro de testes no Roblox Studio. Os códigos devem estar completos, sintaticamente válidos em Luau e amplamente comentados, incluindo comentários sobre segurança, schema, retries, cache, dirty flag e desligamento do servidor. Ao final, explique como habilitar API Services para testar DataStore em Studio, como testar com Start Server/Start Player, como verificar persistência entre sessões e como simular falhas de DataStore sem corromper o inventário.