Il dispositivo Verse Transazioni all'interno dell'isola contiene un modello per le transazioni all'interno dell'isola. Include tutte le implementazioni degli aspetti chiave del modulo Marketplace nell'API Verse. Ciò include oggetti, offerte, offerte bundle e la gestione degli acquisti tramite la UI predefinita della vetrina. Usa questo codice come guida per configurare rapidamente la tua vetrina.
Per accedere al dispositivo:
Vai a Verse Explorer.
Fai clic con il tasto destro sul nome del progetto.
Seleziona Aggiungi un nuovo file Verse al progetto.
Seleziona dispositivo Transazioni all'interno dell'isola.
Creazione di oggetti
Gli oggetti sono definiti in Verse come diritti e si suddividono in due categorie: oggetti consumabili, che vengono rimossi dall'inventario del giocatore dopo l'uso, e oggetti durevoli, che il giocatore può continuare a utilizzare senza che vengano rimossi dall'inventario.
Il modulo EntitlementInfo
I moduli sono unità di codice atomiche che possono essere riutilizzate in più file. I moduli possono essere modificati nel tempo senza compromettere le dipendenze del file in cui sono già utilizzati. Puoi separare blocchi di codice lunghi o ripetitivi, come le definizioni di diritto, in un file separato e importarli tramite l'istruzione using.
Il modulo EntitlementInfo raccoglie i nomi, le descrizioni e le descrizioni brevi di tutti i diritti nel modello. Includi questo modulo in qualsiasi file in cui devi definire i diritti, senza la necessità di ridefinire ripetutamente il nome e altre variabili per lo stesso prodotto, il che rende più semplici le modifiche alle informazioni sui diritti e riduce la complessità del debug dei tuoi diritti.
# Setup your entitlements and offers data, in this case that's your Names, Descriptions & Short Descriptions as well as any other data you want to be constant
EntitlementInfo<public> := module:
Potion<public> := module:
Name<public><localizes>:message = "Potion"
Description<public><localizes>:message = "Adds +10 health when used. Green so you know its healthy!"
Definizione dei diritti
Ogni diritto Verse presenta le seguenti proprietà:
Nome: il nome del diritto, fino a 50 caratteri
Descrizione: La descrizione estesa che viene visualizzata con il diritto, fino a 500 caratteri.
ShortDescription: Una descrizione breve che riassume il diritto in fino a 100 caratteri.
Icona: un'immagine del diritto.
Se il tuo diritto è un oggetto casuale a pagamento, devi includere probabilità numeriche accurate nella descrizione di ciò che il giocatore potrebbe ricevere. Per ulteriori informazioni, vedi Oggetti casuali a pagamento.
Un diritto Verse può includere inoltre le seguenti proprietà facoltative:
MaxCount: il numero massimo di quel diritto che il giocatore può possedere contemporaneamente.
Consumabile: Se impostato su vero, l'oggetto può essere consumato con
ConsumeEntitlement, riducendo il numero totale di oggetti consumati che l'utente possiede nei sistemi di Epic. Se impostato su falso, il diritto è un oggetto permanente e non viene consumato all'uso.PaidArea: se impostato su vero, il diritto garantisce l'accesso a un'area protetta da paywall.
PaidRandomItem: se impostato su vero, questi diritti vengono acquistati o riscattati tramite contenuti per ottenere una ricompensa casuale.
ConsequentialToGameplay: se impostato su vero, l'oggetto offre un vantaggio significativo nella tua isola. Per maggiori dettagli vediConsequenziale al gameplay.
Nello snippet seguente, utilizzi il modulo EntitlementInfo definito in precedenza per creare le definizioni dei tuoi diritti. Per definire un diritto consumabile, Consumabile deve essere impostato su vero.
Prima di definire i tuoi diritti, devi creare una classe di diritti di base che sarà utilizzata per i diritti nella tua esperienza,
in questo caso, feature_example_entitlement.
Devi anche definire un percorso di file per una texture di icona per ogni definizione di diritto, altrimenti la convalida non riuscirà.
Entitlements<public> := module:
using {EntitlementInfo}
# The base entitlement you should define for ALL your entitlements in your experience
feature_example_entitlement<public> := class<abstract><castable>(entitlement){}
basic_sword<public> := class<concrete>(feature_example_entitlement):
var Name<override>:message = Sword.Name
Per impostazione predefinita, gli oggetti non sono Consumabili e hanno MaxCount = 1. Se l'oggetto è un'area a pagamento, un oggetto casuale a pagamento oppure offre un vantaggio significativo che è consequenziale al gameplay, i relativi campi dovranno essere definiti nel tuo codice.
Offerte diritto
Un'offerta specifica un prezzo in V-buck per un oggetto o un asset. Ogni offerta ha un proprio nome, una descrizione e un'icona, separati dalle specifiche dei diritti. Un'offerta è definita in Verse.
Per vendere il diritto, devi avere un'offerta corrispondente per quel diritto.
Ogni offerta presenta le seguenti proprietà:
Name (nome): il nome dell'offerta.
Description (descrizione): la descrizione estesa visualizzata accanto all'offerta.
ShortDescription (descrizione breve): una descrizione breve che riassume l'offerta in finestre di dialogo più piccole.
Icon (icona): un'immagine dell'offerta.
EntitlementType (tipo di diritto): una dichiarazione del diritto incluso nell'offerta.
Price (prezzo): un prezzo espresso in V-buck. Non deve essere inferiore a 50 V-buck e non deve essere superiore a 5.000 V-buck. Il prezzo deve essere impostato in multipli di 50.
Questo snippet mostra come definire le offerte di diritto, utilizzando il modulo EntitlementInfo esistente per le informazioni di base sull'offerta di diritto. Devi anche definire un'icona, l'EntitlementType,
che definisce il diritto a cui si riferisce l'offerta e il prezzo in V-buck. Puoi anche definire un'età minima opzionale per l'acquisto di un'offerta, basandoti su un valore fisso, un codice paese, limitando l'accesso all'offerta in base alla famiglia di piattaforme o a una combinazione di questi fattori. Alcuni esempi di ciò sono illustrati nello snippet seguente.
I codici di suddivisione non sono attualmente supportati e saranno disponibili in una futura versione.
ExampleOffers<public> := module:
using {EntitlementInfo}
basic_sword<public> := class(entitlement_offer):
var Name<override>:message = EntitlementInfo.Sword.Name
var Description<override>:message = EntitlementInfo.Sword.Description
var ShortDescription<override>:message = EntitlementInfo.Sword.ShortDescription
Il prezzo in V-buck deve essere un multiplo di 50 e compreso tra 50 e 5.000 V-buck.
Per gli oggetti casuali a pagamento, devi assicurarti che i giocatori possano vedere le probabilità numeriche accurate di ottenere ciascun oggetto casuale a pagamento nei dettagli dell'offerta. La mancata indicazione sarà considerata una violazione del Regolamento per sviluppatori Fortnite e potrà comportare sanzioni per te e per la tua isola.
Per ulteriori informazioni, consulta Limitazioni sulle Transazioni all'interno dell'isola.
Offerte bundle
I bundle sono definiti in Verse e possono contenere una combinazione di offerte diverse, più istanze della stessa offerta o un mix delle due. Come avviene per le offerte semplici, anche le offerte bundle specificano un prezzo, un nome e una descrizione propri, inoltre presentano un'icona distinta da quella di diritti e offerte. Puoi anche annidare le offerte includendo bundle all'interno di un'altra offerta bundle. Un esempio può essere un bundle a tempo limitato che include una pala e un bundle di pacchetti di semi di mais. Ciò permette di utilizzare piccoli bundle come elementi costitutivi per bundle più grandi e combinati.
I tipi di bundle standard sono:
Bundle impilato: un bundle che contiene più offerte dello stesso diritto, solitamente a prezzo scontato.
Bundle multi-offerta: un bundle che combina offerte per più diritti, che può includere anche una combinazione di offerte impilate e offerte regolari.
Un bundle contiene un array di tuple di offerte, che include l'offerta definita e un int che indica il numero di offerte.
La profondità delle offerte annidate non può superare 5, altrimenti la transazione fallirà. Limita l'annidamento delle offerte ove possibile.
Lo snippet seguente mostra la costruzione di un pacchetto di pozioni. Le informazioni sull'offerta sono definite all'interno del modulo EntitlementInfo e include la variabile PotionCount.
ExampleOffers<public> := module:
using {EntitlementInfo}
<# --- other offer definitions above --- #>
potion_pack<public> := class(bundle_offer) :
var Name<override>:message = EntitlementInfo.PotionPack.Name
Restrizioni sugli acquisti
Puoi limitare gli acquisti con diritto per consentire la creazione di oggetti per le festività limitati, offerte promozionali o stagionali e creare contenuti specifici per regione.
GetMinPurchaseAge
Usa GetMinPurchaseAge per definire una restrizione di acquisto personalizzata per una specifica entitlement_offer. Viene chiamato automaticamente come parte della convalida dell'acquisto e quindi richiede solo una definizione. Puoi definire un valore intero specifico, un codice paese o una famiglia di piattaforme.
I codici di suddivisione non sono attualmente supportati e saranno disponibili in una futura versione.
Di seguito sono riportati alcuni esempi della funzione GetMinPurchaseAge.
# Optional overrideable function you can use to inform Epic systems what the minimum age a player needs to be to purchase this offer
GetMinPurchaseAge<override>(CountryCode:string, SubdivisionCode:string, PlatformFamily:string)<decides><computes>:int =
# A Hypothetical example where you only want to sell swords to people who don't live in Antarctica
CountryCode <> CountryCodes.Antarctica
return 0
Convalida dei diritti del giocatore
La convalida dei diritti dei giocatori è un passaggio necessario per garantire che i diritti acquistati dai giocatori vengano mantenuti tra una sessione e l'altra. La mancata convalida dei diritti può causare problemi quali la duplicazione o la perdita dei diritti, ad esempio.
Verifica degli acquisti precedenti
Lo snippet seguente mostra una semplice convalida di un diritto eseguita quando un giocatore si unisce a una sessione. Innanzitutto, controlla se il giocatore in entrata è iscritto all'evento OnPurchasesChanged. Successivamente, se non è già iscritto, lo sarà anche il giocatore in entrata. Infine, viene recuperato un registro di tutti gli oggetti acquistati per quel giocatore utilizzando ValidatePreviousPurchases.
È buona norma eseguire anche controlli di convalida dei diritti del giocatore in questa fase, per garantire che qualsiasi dato salvato nell'esperienza corrisponda a ciò che l'API Marketplace dice di possedere e che corrisponda all'inventario del giocatore.
OnPlayerJoin(InPlayer:player):void =
Subscription := GetEntitlementsChangedEvent(InPlayer, Entitlements.feature_example_entitlement).Subscribe(OnPurchasesChanged)
if (set EntitlementChangeSubscription[InPlayer] = option{Subscription}):
Print("Adding entitlement Change Subscription player subscription")
# On players joining you are likely going to want to run some validation checks to make sure that any data you save
Gestione degli acquisti
Le due funzioni principali utilizzate per gestire gli acquisti dei diritti sono BuyOffer e OnPurchasesChanged. La prima funzione gestisce la logica per presentare al giocatore un'offerta e convalidare l'acquisto. La seconda funzione gestisce la logica di una transazione o di un rimborso riusciti. Gli snippet seguenti illustrano le due funzioni.
# Base Implementation of how to present players with an offer to purchase in your experience
TryBuyOffer(Player:player, Offer:entitlement_offer)<suspends>:void =
Result := BuyOffer(Player, Offer)
if (Result?):
# do nothing it should respond in the purchase subscription, see OnPurchasesChanged for details
Gestione Consumabili
Per utilizzare un diritto di consumabile, devi usare la funzione ConsumeEntitlement dell'API Marketplace Verse. Una volta che il consumo ha esito positivo, devi gestire la logica dell'effetto generato dopo il consumo. Il conteggio del diritto posseduto dal giocatore verrà diminuito del conteggio consumato nella funzione.
Lo snippet seguente mostra come un diritto specifico viene consumato da un determinato giocatore.
# Base Implementation of how to flag a consumable in your experience as being consumed
TryConsumeEntitlement(Player:player, Entitlement:concrete_subtype(entitlement), NumberConsuming:int)<suspends>:void =
Result := ConsumeEntitlement(Player, Entitlement, ?Count := NumberConsuming)
if (Result?):
Print("Successfully consumed entitlement!")
Non puoi consumare un diritto durevole. Se provi a fare questa operazione, ConsumeEntitlement non funzionerà.
Assegnazione dei diritti
A differenza dell'acquisto di un diritto che richiede V-buck, puoi anche concedere diritti ai giocatori con il metodo GrantEntitlement.
I potenziali casi d'uso per l'assegnazione di un diritto includono oggetti promozionali, campioni gratuiti di consumabili e il ripristino di oggetti persi a causa di bug o glitch.
Questo snippet dimostra un metodo per assegnare i diritti ai tuoi giocatori.
# Base Implementation of how to give players a entitlement in your experience without them purchasing it
TryGrantEntitlement(Player:player, Entitlement:concrete_subtype(entitlement), NumberToGrant:int)<suspends>:void =
Result := GrantEntitlement(Player, Entitlement, ?Count := NumberToGrant)
if (Result?):
Print("Successfully granted a player your entitlement!")
Provare a concedere più del numero massimo di un diritto o più di 1 diritto durevole comporterà il fallimento dell'assegnazione del diritto.
Mostra le tue offerte di diritti ai giocatori
Il Marketplace module offre un'interfaccia utente integrata per la vetrina, da utilizzare sulle tue isole con la funzione ShowOffersDialog. Il frammento seguente mostra un metodo per visualizzare una vetrina che presenta offerte per un giocatore specifico.
# Base Implementation of how to show an array of offers to the player that are available for purchase
ShowArrayOfOffers(Player:player)<suspends>:void =
ShowOffersDialog(Player, array{ExampleOffers.basic_sword{}, ExampleOffers.potion{}, ExampleOffers.potion_pack{}, ExampleOffers.potion_thanksgiving{}, ExampleOffers.potion_gib{}})Codice completo
using { /Fortnite.com/Devices }
using { /Fortnite.com/Marketplace }
using { /UnrealEngine.com/Temporary/Diagnostics }
using { /Verse.org/Assets }
using { /Verse.org/Simulation }