Hoppa till huvudinnehåll

Hur man designar Roblox dagliga belöningar utan dubbla bidrag

Diagram av serverauktoritativa Roblox LiveOps-system och deras skyddade runtime-gränser.

En praktisk serverauktoritativ design för Roblox dagliga belöningar som motstår upprepade förfrågningar, samtidiga servrar, databutiksfel och partiella bidrag.

Behandla ett påstående som en transaktion, inte en knapptryckning

Ett dagligt belöningsgränssnitt ser enkelt ut: visa en kalender, markera idag och låt spelaren hävda. Den svåra delen är allt bakom den knappen. En klient kan skicka samma begäran upprepade gånger. Två servrar kan observera samma lagrade tillstånd. En databutiksförfrågan kan misslyckas efter en del av belöningslogiken har körts. En spelare kan koppla mellan uthållighet och presentation. Om genomförandet behandlar varje begäran som tillstånd att bevilja, duplicera valuta och objekt är ett förväntat resultat snarare än ett kant fall.

Den säkrare modellen är en serverägd transaktion. Kunden ber att hävda, men det bestämmer aldrig om en belöning beror, vad belöningen innehåller, eller om bidraget lyckades. Servern härrör den nuvarande belöningsperioden, laddar det auktoritativa profiltillståndet, validerar den konfigurerade belöningen, försöker en atomstatlig övergång, och endast sedan returnerar ett resultat som kunden kan visa.

Denna separation är den centrala regeln: användargränssnittet kommunicerar avsikt; servern äger behörighet och mutation.

Definiera det minsta auktoritativa tillståndet

Dagliga belöningar behöver inte en historia av varje interaktion mellan gränssnittet. De behöver tillräckligt hållbart tillstånd för att svara på tre frågor: vilken belöningsperiod som senast begicks, vilken ståndpunkt följer av det tillståndet, och om den nuvarande begäran kan flytta staten framåt.

En praktisk profil behöver vanligtvis en stabil periodnyckel, en sista framgångsfull-claim-nyckel och ett streak-värde. Periodnyckeln bör komma från servertid och en dokumenterad återställningspolicy. Oavsett om produkten återställs vid UTC midnatt, vid en konfigurerad regional gräns, eller efter en rullande varaktighet är ett produktbeslut, men beslutet måste vara deterministiskt på servern. Kundklockor bör aldrig bestämma behörighet.

Håll konfiguration separat från spelarstatus. Den konfigurerade kalendern kan definiera belöningsidentifierare, kvantiteter, valutanamn, streakbeteende och aktiva datum. Spelarstaten bör hänvisa till en validerad konfigurationsversion eller stabil belöningsidentifierare snarare än att kopiera godtyckliga klientbelastningar till lagring.

Validera fjärrkontrollen innan du rör lagring

Roblox säkerhetsvägledning behandlar varje värde som korsar klient-server gränsen som opålitlig. För en daglig påstående bör begäran vara avsiktligt tråkig. I många mönster servern behöver ingen belöningsbelopp, streak nummer eller dag index från klienten alls; det kan härleda dessa värden själv.

Innan databutiken börjar bör servern tillämpa en liten avslagskedja:

  • bekräfta begäran som anlände till den avsedda servern RemoteEvent eller RemoteFunction;
  • avvisa oväntade typer, extra identifierare eller missbildade nyttolast;
  • räntebegränsade anspråksförsök per spelare på servern;
  • verifiera spelarprofilen och relevant funktionskonfiguration är tillgängliga;
  • vägra förfrågningar medan en fordran för den spelaren redan behandlas lokalt.

Betygsbegränsning är inte dubblettgarantin. Det skyddar serverkapacitet och minskar missbruk. Den hållbara garantin måste fortfarande överleva två servrar, retries, reconnects och processreparationer.

Gör behörighet och åtagande en atomuppdatering

En "GetAsync()" följt senare av "SetAsync()" lämnar ett tävlingsfönster. Två servrar kan läsa samma oclaimed tillstånd, båda bestämmer spelaren är berättigad, och båda skriver ett bidrag. Roblox dokument "UpdateAsync()" som den säkrare multi-server operation eftersom det läser det aktuella värdet och retries callback när samtidiga uppdateringar konflikt.

Sätt behörighetsbeslutet inuti den atomuppdateringen. Uppringningen får det senaste lagrade värdet, kontrollerar om den nuvarande perioden redan har begåtts och returnerar antingen ett nytt tillstånd eller "nil" för att avbryta. Uppringningen får inte ge, så det bör inte ringa externa tjänster, vänta på instanser eller utföra det synliga belöningsbidraget själv.

Det åtagande staten bör innehålla en varaktig bidragsmarkör: belöningsperioden och den stabila belöningsidentifieraren eller transaktionsnyckeln som vann uppdateringen. Om återkopplingen upptäcker att markören redan finns, är det korrekta resultatet "redan hävdat", inte ett annat bidrag.

Detta mönster omvandlar upprepade förfrågningar till upprepade läsningar av samma resultat. Den första giltiga övergången vinner. Senare försök att observera den engagerade markören och bli no-ops.

Nära klyftan mellan uthållighet och belöning leverans

Atomprofilstatus förhindrar två fordringsövergångar, men designen behöver fortfarande en tydlig leveransorder. Om valutan läggs till innan fordringsmarkören är hållbar, kan ett databutiksfel lämna värde som beviljats utan rekord. Om markören lagras först och servern kraschar före leverans, kan spelaren ha ett åtagande utan objektet.

Det robusta svaret är en idempotent bidragsrekord. Begå en transaktionsidentifierare och ett leveranstillstånd, gör sedan belöningsleveransen säker att upprepa mot den identifieraren. Valuta, lager, märke eller rättegångstjänster bör erkänna att en viss transaktion redan har tillämpats. En återhämtningsväg kan inspektera engagerade men unelivered poster och retry dem utan att skapa en andra belöning.

Inte alla erfarenheter behöver en komplex huvudbok, men varje erfarenhet behöver ett uttryckligt svar på partiell misslyckande fråga. "Frågan är förmodligen slut" är inte en garanti.

Bevara driftsordningen under retries

Datastore samtal kan misslyckas, och LiveOps Goblin runtime foundation använder en säker datastore wrapper med retry och backoff beteende. Retrying är inte detsamma som att skicka samma operation igen från flera oberoende uppgifter. Roblox varnar för att naiva retries kan beställa statliga operationer.

Använd en serialiserad anspråksbana per spelare, bevara ordning av profiländringar och hålla transaktionsidentifieraren stabil över retries. Retry endast den misslyckade operationen med gränsad backoff. Tävla inte en ny belöningsperiod eller transaktionsnyckel på varje försök. Om spelaren lämnar, bör hållbar återhämtning kunna fortsätta från lagrat tillstånd snarare än från en minnesflagga.

Diagnostik bör skilja avvisade förfrågningar, räntebegränsningar, databutiksvarningar, redan uttagna resultat, begångna påståenden och leveransåterhämtning. Dessa händelser är operativa bevis; de bör inte avslöja hemligheter eller fabricera aktivitet när ingen analysleverantör är konfigurerad.

Håll konfigurationen säker innan den når spelet

Duplicat skydd försvagas när den exporterade belöningskalendern själv är tvetydig. LiveOps Goblin validerar omöjliga mängder, saknas datastore-nycklar, tvetydiga valutanamn, dubbla koder och utgångna scheman innan du producerar en versionerad Roblox-konfiguration.

En belöningsdefinition bör använda stabila identifierare, bundna kvantiteter, kända valuta- eller lagermål, uttryckliga schemaregler och en version som kan spåras i diagnostik. Tomma kalendrar bör förbli tomma tills en skapare lägger till verkliga belöningar. Demo-värden i produktionskonfiguration är farligare än ett ärligt tomt tillstånd eftersom de kan bli verkliga ekonomimutationer.

När en kalender ändras, bestäm vad som händer med spelare i mitten av stallet. Stabil belöningsidentifierare och versionerad konfiguration gör den policyn testbar. Position-bara antaganden gör det enkelt för "dag tre" att hänvisa till olika belöningar före och efter en uppdatering.

Testa misslyckanden, inte bara den lyckliga vägen

En användbar daglig belöning testmatris bör innehålla mer än "ta en gång och ta emot mynt".

  • två snabba förfrågningar från samma klient;
  • Förfrågningar från två serverkontexter mot samma lagrade profil;
  • en fordran för en period som redan begåtts,
  • missbildade fjärrbelastningar och räntebegränsat beteende;
  • databutik konflikt, övergående misslyckande och utmattade retry vägar;
  • koppla av efter engagemang men före kundbekräftelse;
  • leverans retry med samma transaktionsidentifierare;
  • en kalenderversion ändras under en aktiv streak;
  • en försvunnen eller ogiltig belöningskonfiguration;
  • Analytics funktionshindrade med diagnostik fortfarande fungerar.

Det förväntade resultatet är inte bara "ingen krasch". Varje test bör hävda det slutliga hållbara tillståndet, antalet ansökningar som tillämpas, klientsynliga resultat och diagnostiska händelsen.

En koncis genomförande checklista

Den slutliga utformningen kan granskas med tio frågor. Är behörighet som härrör på servern? Återställs tid deterministisk? Skickar klienten bara avsikt? Är fjärrförfrågningar validerade och server-rate-limited? Är fordringsövergångsatomiken? Har det lagrade tillståndet en stabil transaktionsmarkör? Kan belöningsleveransen upprepas utan duplicering? Bevarar retries order? Är konfigurationer versionerade och validerade?

När alla tio svar är konkreta, slutar en daglig belöning att vara en bräcklig knapphanterare och blir en liten, begriplig LiveOps-transaktion.

Relaterat systemUtforska LiveOps Goblin