Overslaan en naar de inhoud gaan

Hoe te ontwerpen Roblox dagelijkse beloningen zonder dubbele subsidies

Diagram van Roblox LiveOps systemen en hun beschermde runtime grenzen.

Een praktisch server-authoritatief ontwerp voor Roblox dagelijks beloningen die bestand zijn tegen herhaalde verzoeken, gelijktijdige servers, datastore storingen, en gedeeltelijke subsidies.

Behandel een claim als een transactie, geen druk op de knop

Een dagelijkse-beloningsinterface ziet er eenvoudig uit: toon een agenda, markeer vandaag, en laat de speler claimen. Het moeilijke deel is alles achter die knop. Een client kan hetzelfde verzoek herhaaldelijk verzenden. Twee servers kunnen dezelfde opgeslagen staat observeren. Een datastore-verzoek kan mislukken nadat een deel van de beloningslogica is uitgevoerd. Een speler kan de verbinding tussen persistentie en presentatie verbreken. Als de implementatie behandelt elke aanvraag als toestemming om te verlenen, dubbele valuta en items zijn een verwachte uitkomst in plaats van een randgeval.

Het veiligere model is een transactie die eigendom is van de server. De client vraagt om aanspraak te maken, maar het beslist nooit of een beloning verschuldigd is, wat de beloning bevat, of dat de subsidie is gelukt. De server haalt de huidige beloningsperiode, laadt de gezaghebbende profielstatus, valideert de geconfigureerde beloning, probeert een atoomtoestandstransitie, en geeft alleen dan een resultaat terug dat de client kan weergeven.

Die scheiding is de centrale regel: de gebruikersinterface communiceert intent; de server bezit in aanmerking komende en mutatie.

Definieer de kleinste gezaghebbende staat

Dagelijkse beloningen hebben geen geschiedenis van elke interface interactie nodig. Ze hebben genoeg duurzame staat nodig om drie vragen te beantwoorden: welke beloningsperiode was het laatst vastgelegd, welke streeppositie volgt uit die staat, en of het huidige verzoek de staat vooruit kan helpen.

Een praktisch profiel heeft meestal een stabiele periodesleutel, een last-succesvol-claim sleutel en een streepwaarde nodig. De periodesleutel moet afkomstig zijn van de servertijd en een gedocumenteerd resetbeleid. Of het product zich herstart om middernacht UTC, op een geconfigureerde regionale grens, of na een rolduur is een productbeslissing, maar de beslissing moet deterministisch zijn op de server. Klokken van klanten mogen nooit bepalen of ze in aanmerking komen.

Houd de configuratie gescheiden van de spelerstatus. De geconfigureerde agenda kan reward identifiers, hoeveelheden, valuta namen, streak gedrag en actieve data definiëren. Spelerstatus moet verwijzen naar een gevalideerde configuratieversie of stabiele beloning identifier in plaats van het kopiëren van willekeurige client payloads in opslag.

Valideer de remote voordat u de opslag aanraakt

Roblox security guidance behandelt elke waarde die de client-servergrens overschrijdt als onbetrouwbaar. Voor een dagelijkse claim moet het verzoek bewust saai zijn. In veel ontwerpen heeft de server geen beloningsbedrag, streak-nummer of dagindex van de client nodig; het kan deze waarden zelf afleiden.

Voordat datastore werk begint, moet de server een kleine afwijzingsketen toepassen:

  • het verzoek dat is binnengekomen op de beoogde server RemoteEvent of RemoteFunction te bevestigen;
  • onverwachte types, extra identificaties of misvormde ladingen afwijzen;
  • poging tot het claimen van tarieven per speler op de server;
  • na te gaan of het spelerprofiel en de relevante functieconfiguratie beschikbaar zijn;
  • weigeren verzoeken terwijl een claim voor die speler al lokaal wordt verwerkt.

Prijsbeperking is niet de dubbele garantie. Het beschermt de servercapaciteit en vermindert misbruik. De duurzame garantie moet nog steeds overleven twee servers, retries, reconnects, en proces herstarten.

Werk het recht op een beloning en de toekenning bij in één atomaire handeling

Een `GetAsync()` die later wordt gevolgd door `SetAsync()` laat ruimte voor een raceconditie. Twee servers kunnen dezelfde status lezen waarin de beloning nog niet is geclaimd, allebei besluiten dat de speler in aanmerking komt en allebei een toekenning opslaan. Roblox beschrijft `UpdateAsync()` als de veiligere bewerking voor meerdere servers, omdat deze de huidige waarde leest en de callback opnieuw uitvoert wanneer gelijktijdige updates conflicteren.

Plaats het besluit om in aanmerking te komen in die atomaire update. De callback ontvangt de nieuwste opgeslagen waarde, controleert of de huidige periode al is vastgelegd, en retourneert ofwel een nieuwe staat of . . . . om te annuleren. De callback mag niet opleveren, dus het moet geen externe diensten bellen, wachten op instanties, of het uitvoeren van de zichtbare beloning subsidie zelf.

De vastgelegde staat moet een duurzame subsidie marker omvatten: de beloningsperiode en de stabiele beloning identifier of transactie sleutel die de update gewonnen. Als de callback ontdekt dat marker al bestaat, het juiste resultaat is al geclaimd, ... niet een andere subsidie.

Dit patroon zet herhaalde verzoeken om in herhaalde lezingen van dezelfde uitkomst. De eerste geldige overgang wint. Latere pogingen observeren de commit marker en worden no-ops.

De kloof tussen doorzettingsvermogen en beloning dichten

Atomic profiel staat voorkomt twee claim overgangen, maar het ontwerp moet nog steeds een duidelijke levering bestelling. Als valuta wordt toegevoegd voordat de claim marker duurzaam is, kan een datastore fout waarde toegekend zonder een record. Als de marker wordt opgeslagen eerst en de server crasht voor levering, kan de speler een vastgelegde claim zonder het item.

Het robuuste antwoord is een idempotent subsidie record. Doe een transactie-identificatie en een levering staat, maak beloning levering veilig om te herhalen tegen die identificatie. Valuta, inventaris, badge, of rechten diensten moeten erkennen dat een bepaalde transactie al is toegepast. Een herstel pad kan controleren gepleegde-maar-undelivered records en opnieuw proberen zonder het creëren van een tweede beloning.

Niet elke ervaring heeft een complex grootboek nodig, maar elke ervaring heeft een expliciet antwoord nodig op de gedeeltelijke falende vraag.

Behoud operatievolgorde tijdens retrieves

Datastore calls kunnen mislukken, en de LiveOps Goblin runtime foundation maakt gebruik van een veilige datastore wrapper met retry en backoff gedrag. Opnieuw proberen is niet hetzelfde als het verzenden van dezelfde operatie opnieuw van verschillende onafhankelijke taken. Roblox waarschuwt dat naïeve retries kunnen herordenen stateful operaties.

Gebruik één geserialiseerde claim pad per speler, behoud de volgorde van profielwijzigingen, en houd de transactie-identificatie stabiel over retrieves. Probeer alleen de mislukte operatie met begrensde backoff. Bereken geen nieuwe beloningsperiode of transactiesleutel bij elke poging. Als de speler vertrekt, moet duurzaam herstel kunnen doorgaan vanuit opgeslagen toestand in plaats van vanuit een in-geheugen vlag.

Diagnostics moeten onderscheiden afgewezen verzoeken, tarieflimieten, datastore waarschuwingen, reeds opgeëiste resultaten, vastgelegde claims en levering herstel. Deze gebeurtenissen zijn operationeel bewijs; ze mogen geen geheimen blootleggen of activiteit fabriceren wanneer geen analytics provider is geconfigureerd.

Houd configuratie veilig voordat het het spel bereikt

Dubbele bescherming is verzwakt wanneer de geëxporteerde beloning kalender zelf dubbelzinnig is. LiveOps Goblin valideert onmogelijke hoeveelheden, ontbrekende datastore sleutels, dubbelzinnige valuta namen, dubbele codes, en verlopen schema's voor het produceren van een versioned Roblox configuratie.

Een beloning definitie moet gebruik maken van stabiele identificaties, begrensde hoeveelheden, bekende valuta of inventaris targets, expliciete schema regels, en een versie die kan worden getraceerd in diagnostiek. Lege kalenders moeten leeg blijven totdat een maker voegt echte beloningen. Demo waarden in productie configuratie zijn gevaarlijker dan een eerlijke lege staat omdat ze kunnen worden echte economie mutaties.

Wanneer een agenda verandert, beslissen wat er gebeurt met spelers mid-streak. Stabiele beloning identificaties en versioned configuratie maken dat beleid testable. Position-only veronderstellingen maken het gemakkelijk voor dag drie te verwijzen naar verschillende beloningen voor en na een update.

Test de mislukkingen, niet alleen het gelukkige pad

Een nuttige dagelijkse beloningstestmatrix moet meer dan één keer claimen en munten ontvangen.

  • twee snelle verzoeken van dezelfde cliënt;
  • verzoeken van twee servercontexten tegen hetzelfde opgeslagen profiel;
  • een vordering voor een reeds vastgelegde periode;
  • misvormd remote payloads en snelheidslimietgedrag;
  • datastore conflict, transiënte storing en uitgeputte retry-paden;
  • loskoppelen na verbintenis, maar vóór cliëntbevestiging;
  • de levering opnieuw te proberen met dezelfde transactie-identificatiecode;
  • een wijziging van de kalenderversie tijdens een actieve streep;
  • een ontbrekende of ongeldige beloningsconfiguratie;
  • analytics uitgeschakeld met diagnostiek nog steeds functioneren.

Het verwachte resultaat is niet alleen een crash.Afhankelijk van elke test moet de uiteindelijke duurzame staat, het aantal subsidies toegepast, de cliënt-zichtbare uitkomst, en de kenmerkende gebeurtenis.

Een beknopte implementatiechecklist

Het uiteindelijke ontwerp kan worden herzien met tien vragen. Is subsidiabiliteit afgeleid op de server? Is reset tijd deterministisch? Stuurt de client alleen intentie? Zijn remote verzoeken gevalideerd en server-rate-limited? Is de claim transitie atomic? Bevat de opgeslagen staat een stabiele transactie marker? Kan de levering worden beloond zonder duplicatie? Worden retries orde behouden? Zijn configuraties versioned en gevalideerd? Doen concurrency en gedeeltelijk falen testen precies één duurzame subsidie?

Wanneer alle tien antwoorden concreet zijn, stopt een dagelijkse beloning met het zijn van een fragiele button handler en wordt een kleine, begrijpelijke LiveOps transactie.

Verwant systeemVerken LiveOps Goblin