Saltar para o conteúdo principal

Como projetar recompensas diárias Roblox sem bolsas duplicadas

Diagrama de sistemas Roblox autoritativos e seus limites de execução protegidos.

Um design prático servidor-autoritativo para Roblox recompensas diárias que resiste a solicitações repetidas, servidores concorrentes, falhas de datastore e subsídios parciais.

Tratar uma reivindicação como uma transação, não um botão pressionar

Uma interface de recompensa diária parece simples: mostre um calendário, destaque hoje e deixe o jogador reclamar. A parte difícil é tudo por trás desse botão. Um cliente pode enviar o mesmo pedido repetidamente. Dois servidores podem observar o mesmo estado armazenado. Uma solicitação de armazenamento de dados pode falhar depois de parte da lógica de recompensa ter sido executada. Um jogador pode desconectar entre persistência e apresentação. Se a implementação tratar cada pedido como permissão para conceder, a moeda duplicada e os itens são um resultado esperado, em vez de um caso de borda.

O modelo mais seguro é uma transação de propriedade do servidor. O cliente pede para reivindicar, mas ele nunca decide se uma recompensa é devida, o que a recompensa contém, ou se o subsídio foi bem sucedido. O servidor deriva o período de recompensa atual, carrega o estado de perfil autoritário, valida a recompensa configurada, tenta uma transição de estado atômico, e só então retorna um resultado que o cliente pode exibir.

Essa separação é a regra central: a interface do usuário comunica intenção; o servidor possui elegibilidade e mutação.

Definir o menor estado autoritário

Recompensas diárias não precisam de um histórico de cada interação de interface. Eles precisam de estado durável suficiente para responder a três perguntas: qual período de recompensa foi cometido pela última vez, que posição de raia segue desse estado, e se a solicitação atual pode mover o estado para frente.

Um perfil prático geralmente precisa de uma chave de período estável, uma chave de última reivindicação bem sucedida e um valor de raia. A chave de período deve vir do tempo do servidor e de uma política de redefinição documentada. Se o produto reinicia à meia- noite do UTC, numa fronteira regional configurada ou depois de uma duração de rolamento é uma decisão de produto, mas a decisão deve ser determinística no servidor. Os relógios do cliente nunca deverão determinar a elegibilidade.

Mantenha a configuração separada do estado do jogador. O calendário configurado pode definir identificadores de recompensa, quantidades, nomes de moeda, comportamento de raia e datas activas. O estado do jogador deverá referir- se a uma versão de configuração validada ou a um identificador de recompensa estável, em vez de copiar as cargas arbitrárias dos clientes para o armazenamento.

Validar o comando antes de tocar no armazenamento

A orientação de segurança Roblox trata cada valor atravessando o limite cliente- servidor como não confiável. Para uma reivindicação diária, a solicitação deve ser deliberadamente entediada. Em muitos projetos, o servidor não precisa de valor de recompensa, número de ranhura ou índice de dia do cliente; ele pode derivar esses valores em si.

Antes do início do trabalho de datastore, o servidor deve aplicar uma pequena cadeia de rejeição:

  • confirmar o pedido chegado no servidor pretendido RemoteEvent ou RemoteFunction;
  • Rejeitar tipos inesperados, identificadores adicionais ou cargas úteis malformadas;
  • tentativas de reivindicação de limite de taxa por jogador no servidor;
  • verificar se o perfil do jogador e a configuração relevante do recurso estão disponíveis;
  • recusar pedidos enquanto uma reivindicação para esse jogador já está sendo processada localmente.

Limitação de taxa não é a garantia de doação duplicada. Ele protege a capacidade do servidor e reduz o abuso. A garantia durável ainda deve sobreviver a dois servidores, repetições, reconexões e reinícios do processo.

Fazer da elegibilidade e compromisso uma atualização atômica

Um `GetAsync()` seguido por `SetAsync()` deixa uma janela de corrida. Dois servidores podem ler o mesmo estado não reclamado, ambos decidem que o jogador é elegível, e ambos escrevem uma concessão. Roblox documents `UpdateAsync()` como a operação multi-servidor mais segura porque ele lê o valor atual e repete o retorno de chamada quando o conflito de atualizações simultâneas.

Coloque a decisão de elegibilidade dentro dessa atualização atômica. O retorno de chamada recebe o valor armazenado mais recente, verifica se o período atual já foi cometido e retorna um novo estado ou `nulo` para cancelar. O retorno de chamada não deve render, por isso não deve chamar serviços externos, esperar por instâncias ou executar a recompensa visível em si.

O estado comprometido deve incluir um marcador de subvenção durável: o período de recompensa e o identificador de recompensa estável ou chave de transação que ganhou a atualização. Se o callback descobre que o marcador já existe, o resultado correto é “já reivindicado,” não outro subsídio.

Este padrão converte requisições repetidas em leituras repetidas do mesmo resultado. A primeira transição válida ganha. Tentações posteriores observam o marcador comprometido e tornam- se no- ops.

Fechar a lacuna entre persistência e entrega de recompensa

O estado do perfil atómico impede duas transições de reivindicação, mas o desenho ainda precisa de uma ordem de entrega clara. Se a moeda for adicionada antes que o marcador de reivindicação seja durável, uma falha de datastore pode deixar o valor concedido sem um registro. Se o marcador for armazenado primeiro e o servidor falhar antes da entrega, o jogador pode ter uma reivindicação comprometida sem o item.

A resposta robusta é um registro de subvenção idempotente. Comprometa um identificador de transação e um estado de entrega, em seguida, faça a entrega de recompensa segura para repetir contra esse identificador. Moeda, inventário, crachá ou serviços de direito devem reconhecer que uma determinada transação já foi aplicada. Um caminho de recuperação pode inspecionar registros compromissados, mas não entregues, e tentar novamente sem criar uma segunda recompensa.

Nem toda experiência precisa de um livro de contabilidade complexo, mas toda experiência precisa de uma resposta explícita para a questão de falha parcial. “O pedido provavelmente termina” não é uma garantia.

Preservar a ordem de operação durante as repetições

As chamadas de datastore podem falhar, e a fundação LiveOps Goblin runtime usa um invólucro de datastore seguro com o comportamento de retry e backoff. A repetição não é a mesma que enviar a mesma operação novamente de várias tarefas independentes. O Roblox avisa que retries ingênuos podem reordenar operações de estado.

Use um caminho de reivindicação serializado por jogador, preserve a ordem das mudanças de perfil e mantenha o identificador de transação estável entre repetições. Tente apenas a operação falhada com backoff limitado. Não recompute um novo período de recompensa ou chave de transação em cada tentativa. Se o jogador sair, a recuperação durável deverá ser capaz de continuar a partir do estado armazenado em vez de de uma bandeira de memória.

Os diagnósticos devem distinguir pedidos rejeitados, limites de taxa, avisos de datastore, resultados já reclamados, reclamações cometidas e recuperação de entrega. Esses eventos são evidência operacional; eles não devem expor segredos ou fabricar atividade quando nenhum provedor de análise está configurado.

Mantenha a configuração segura antes de chegar ao jogo

A proteção duplicada é enfraquecida quando o calendário de recompensa exportado em si é ambíguo. LiveOps Goblin valida quantidades impossíveis, chaves de datastore faltando, nomes de moeda ambíguos, códigos duplicados e agendamentos expirados antes de produzir uma configuração Roblox versionada.

Uma definição de recompensa deve usar identificadores estáveis, quantidades limitadas, moeda conhecida ou alvos de inventário, regras de programação explícitas, e uma versão que pode ser rastreada em diagnósticos. calendários vazios devem permanecer vazios até que um criador adiciona recompensas reais. Valores de demonstração na configuração de produção são mais perigosos do que um estado vazio honesto porque eles podem se tornar mutações de economia real.

Quando um calendário muda, decida o que acontece com os jogadores no meio do streak. Identificadores de recompensa estáveis e configuração versionada tornam essa política testável. Suposições somente de posição facilitam para que "três dias" se refira a recompensas diferentes antes e depois de uma atualização.

Teste as falhas, não só o caminho feliz

Uma matriz útil de teste de recompensa diária deve incluir mais do que “afirmar uma vez e receber moedas”. No mínimo, exercício:

  • Dois pedidos rápidos do mesmo cliente;
  • pedidos de dois contextos de servidor contra o mesmo perfil armazenado;
  • Um pedido por um período já autorizado;
  • Cargas remotas malformadas e comportamento de limite de velocidade;
  • conflito de datastore, falha transitória e caminhos de repetição esgotados;
  • desligar após compromisso, mas antes da confirmação do cliente;
  • Repetição da entrega utilizando o mesmo identificador de transação;
  • Uma alteração da versão do calendário durante uma sequência ativa;
  • uma configuração de recompensa em falta ou inválida;
  • analytics desactivado com diagnósticos ainda em funcionamento.

O resultado esperado não é meramente “nenhum acidente”. Cada teste deve afirmar o estado durável final, o número de subsídios aplicados, o resultado cliente-visível, e o evento diagnóstico.

Uma lista de verificação concisa de implementação

O desenho final pode ser revisto com dez perguntas. A elegibilidade é derivada do servidor? O tempo de redefinição é determinístico? O cliente envia apenas a intenção? As requisições remotas são validadas e as taxas de servidor são limitadas? A transição de reivindicação é atômica? O estado armazenado inclui um marcador de transação estável? A entrega de recompensa pode ser repetida sem duplicação? As repetições preservam a ordem? As configurações são versionadas e validadas? Os testes de concordância e falha parcial provam exatamente uma concessão durável?

Quando todas as dez respostas são concretas, uma recompensa diária deixa de ser um manipulador de botões frágil e torna-se uma pequena e compreensível transação LiveOps.

Sistema relacionadoExplore o LiveOps Goblin