Las transacciones dentro de la isla te permiten comercializar objetos, ofertas y ofertas por paquete en tu isla utilizando Verse.
En esta guía, obtendrás más información sobre cómo configurar tus propios objetos, ofertas y ofertas por lote. Mediante el módulo del Marketplace en la API de Verse, podrás gestionar la venta de objetos en el juego.
Objetos
Los objetos se definen en Verse como productos y se dividen en dos categorías: objetos consumibles, que se eliminan del inventario del jugador cuando se utilizan, y objetos duraderos, que el jugador puede seguir utilizando sin que se eliminen de su inventario.
Cada producto de Verse tiene las siguientes propiedades:
Nombre: el nombre del producto, con un máximo de 50 caracteres.
Descripción: la descripción larga que se muestra con el producto, de hasta 500 caracteres.
Descripción breve: una descripción breve que resume el producto en un cuadro de diálogo más pequeño de hasta 100 caracteres.
Ícono: una imagen del producto.
Si tu producto es un objeto aleatorio pago, debes incluir en la descripción las probabilidades numéricas exactas de lo que el jugador puede recibir. Para obtener más información, consulta Objetos aleatorios pagos.
Un producto de Verse también puede tener las siguientes propiedades opcionales:
MaxCount: la cantidad máxima de ese producto que el jugador puede poseer en un momento dado.
Consumible: si se establece en verdadero, el producto se puede consumir, lo que reduce el número total de usos. Si se establece en falso, el producto es un objeto permanente y no se consumirá con el uso.
PaidArea: Si se establece en verdadero, el producto proporciona acceso a un área de pago.
PaidRandomItem: si se establece en verdadero, estos productos se compran o canjean con contenido para obtener una recompensa aleatoria.
ConsequentialToGameplay: si se establece en verdadero, el objeto proporciona una ventaja importante en tu isla. Consulta Consecuente con la jugabilidad para ver más información.
Si tienes productos activos que no están en uso, y no confirmas las compras desde la aplicación en el cuestionario de IARC, tu isla fallará la moderación.
Para evitar esto, puedes comentar tus productos en Verse hasta que tengas todo listo para usarlos en un juego en vivo. Con los productos desactivados, no es necesario reclamar compras en la aplicación en el cuestionario de IARC.
Cómo crear una licencia consumible de productos en Verse
Los productos se definen en Verse, derivados de la clase base de productos. El siguiente fragmento de código muestra la creación de un objeto consumible. En este ejemplo, crearás semillas de maíz como objeto consumible. A continuación, se incluye un ícono de las semillas para que lo utilices.
# The base entitlement you should define for ALL of your entitlements in your experience.
my_island_entitlement := class<abstract><castable>(entitlement){}
CornSeedPacket<public> := module:
Name<public><localizes> : message = "Corn seed pack"
Description<public><localizes> : message = "A pack of corn seeds. Opening a pack yields 10 corn seeds for planting."
ShortDescription<public><localizes> : message = "Contains 10 corn seeds for planting."
cornseedpacket<public> := class<concrete>(my_island_entitlement):
var Name<override>:message = CornSeedPacket.Name
Cuando creas un producto, debes incluir una ruta a una textura de ícono válida para que tu código Verse se compile con éxito. Toma el paquete de semillas de maíz y otros íconos incluidos en esta guía como obsequio.
Asegúrate de que los íconos de tus productos utilicen una textura cuadrada con potencia de dos para obtener imágenes de la mejor calidad en tu tienda. Para obtener información sobre cómo importar texturas a UEFN con el fin de utilizarlas como íconos, consulta Cómo importar recursos. Para obtener más información sobre cómo exponer los recursos, por ejemplo, las texturas en Verse, consulta Cómo exponer recursos.
Cómo crear productos duraderos en Verse
Los productos duraderos en Verse siguen el mismo formato que los productos consumibles, pero con una diferencia clave: Consumable está establecido en falso en lugar de verdadero. Los jugadores solo pueden comprar los productos duraderos una vez y solo pueden poseer uno de cada producto duradero.
Para este ejemplo, crearás una pala como un producto duradero. Se incluye un ícono para la textura de la pala después del fragmento de código siguiente.
Shovel<public> := module:
Name<public><localizes>: message = "Shovel"
Description<public><localizes>: message = "An unbreakable shovel used to dig holes for planting."
ShortDescription<public><localizes>: message = "Digs holes."
shovel<public> := class<concrete>(my_island_entitlement):
var Name<override>:message = Shovel.Name
var Description<override>:message = Shovel.Description
var ShortDescription<override>:message = Shovel.ShortDescription
var Icon<override>:texture = # path to your texture here
De forma predeterminada, los elementos no son Consumable y tienen un MaxCount de 1. Si el objeto es un área de pago, un objeto aleatorio pago o proporciona una ventaja importante que es consecuente con la jugabilidad, los campos pertinentes deben estar definidos en el código.
Reglas de validación de productos
Un producto válido en Verse debe cumplir con las siguientes directrices. Las compras de un producto que no las cumpla no se realizarán.
Las reglas que definen un producto válido son las siguientes:
Nombre tiene un límite de 50 caracteres.
Descripción tiene un límite de 500 caracteres.
ShortDescription tiene un límite de 100 caracteres.
MaxCount debe ser 1 cuando Consumible=falso.
MaxCount tiene un valor máximo de 10,000,000.
La configuración MaxCount < 1 no se aplica, pero dará error, ya que no se puede otorgar menos de un objeto a un jugador.
El Catálogo de productos
Puedes utilizar el Catálogo de productos para ver todos los productos que ofreces a los jugadores.
Puedes ver un informe con la lista de tus productos en UEFN al hacer clic en Herramientas > Catálogo de productos, o directamente desde el catálogo en el Portal de creadores de tu isla.
Ofertas
Una oferta especifica un precio en monedas V para un objeto o un recurso. Cada oferta tiene su propio nombre, descripción e ícono, independientes de las especificaciones de productos. Una oferta se define en Verse.
Cada oferta tiene las siguientes propiedades:
Nombre: el nombre de la oferta.
Descripción: la descripción larga que se muestra junto a la oferta.
ShortDescription: una descripción breve que puedes utilizar para resumir la oferta en cuadros de diálogo más pequeños.
Ícono: una imagen de la oferta.
EntitlementType: una declaración del producto incluido en la oferta.
Precio: un precio en monedas V. No debe ser inferior a 50 monedas V ni superior a 5000 monedas V. El precio debe establecerse en múltiplos de 50.
Cómo crear una oferta simple
Este fragmento define una oferta básica para una oferta sencilla: el paquete de semillas de maíz. Puedes reutilizar el ícono de semillas de maíz del ejemplo de producto como ícono para esta oferta.
CornSeedPacket<public> := module:
Name<public><localizes> : message = "Corn seed pack"
Description<public><localizes> : message = "A pack of corn seeds. Opening a pack yields 10 corn seeds for planting."
ShortDescription<public><localizes> : message = "Contains 10 corn seeds for planting."
corn_seed_pack<public> := class(entitlement_offer):
var Name<override> : message = CornSeedPacket.Name
var Description<override> : message = CornSeedPacket.Description
var ShortDescription<override> : message = CornSeedPacket.ShortDescription
El precio en monedas V debe ser un múltiplo de 50 y estar entre 50 y 5000 monedas V.
Debes garantizar que los jugadores puedan ver las probabilidades numéricas exactas de obtener cada objeto aleatorio pago antes de la compra. De no hacerlo, se considerará una infracción del Reglamento de desarrolladores de Fortnite, y tú y tu isla estarán sujetos a las sanciones correspondientes.
Para obtener más información, consulta Restricciones a las transacciones dentro de la isla.
Cómo crear y modificar ofertas fijas y alternativas
Puedes hacer ofertas alternativas por el mismo producto para ofrecer precios especiales para vacaciones, bonificaciones de lanzamiento y variar el precio por área. También puedes usarlo para probar los productos al crear una oferta idéntica pero con un ícono diferente para ver cuál atrae más a los jugadores. Utilicemos este ícono como ejemplo.
CornSeedPacketAlternate<public> := module:
Name<public><localizes> : message = "Corn seed pack"
Description<public><localizes> : message = "Special price! Only today!"
ShortDescription<public><localizes> : message = "Special offer half price!"
corn_seed_pack_alternate<public> := class(entitlement_offer):
var Name<override> : message = CornSeedPacketAlternate.Name
var Description<override> : message = CornSeedPacketAlternate.Description
var ShortDescription<override> : message = CornSeedPacketAlternate.ShortDescription
var Icon<override> : texture = # Your texture here
Oferta por lote
Los lotes se definen en Verse y pueden contener una combinación de diferentes ofertas, conjuntos de la misma oferta o una mezcla de ambos. Al igual que las ofertas simples, las ofertas por lote especifican su propio precio, nombre y descripción, y tienen un ícono que es distinto a los productos y las ofertas. También puedes anidar ofertas al incluir lotes dentro de una oferta por lote. Un ejemplo sería un lote por tiempo limitado que incluye una pala y un paquete de semillas de maíz. Esto te permite utilizar lotes más pequeños como bloques de construcción para lotes combinados más grandes.
Los tipos de lotes estándar son los siguientes:
Lote apilado: un lote que contiene varias ofertas del mismo producto, normalmente a un precio con descuento.
Lote de varias ofertas: un paquete que combina ofertas para varios productos, que también puede incluir una combinación de ofertas apiladas y ofertas normales.
La profundidad de las ofertas anidadas no puede superar las 5, o la transacción fallará. Intenta limitar las ofertas anidadas siempre que sea posible.
Cómo crear un lote apilado
Este fragmento define un lote apilado de semillas de maíz. Un lote contiene una matriz de tuplas de ofertas, la cual contiene la oferta definida y un int que indica el número de ofertas. En este caso, habría dos ofertas de corn_seed_pack en este paquete. Se incluye un ícono a modo de ejemplo.
CornSeedPacketBundle<public> := module:
Name<public><localizes> : message = "Corn seed pack bundle"
Description<public><localizes> : message = "Two packs of corn seeds. Opening a pack yields 10 corn seeds for planting."
ShortDescription<public><localizes> : message = "Two packs of corn seeds containing 10 corn seeds for planting."
corn_seed_pack_bundle<public> := class(bundle_offer):
var Name<override> : message = CornSeedPacketBundle.Name
var Description<override> : message = CornSeedPacketBundle.Description
var ShortDescription<override> : message = CornSeedPacketBundle.ShortDescription
var Icon<override> : texture = # your texture here
Cómo crear lotes con varias ofertas
Es posible que los jugadores quieran evitar realizar varias transacciones, por lo que puedes crear un paquete que incluya varias ofertas con diferentes productos. Este fragmento de código crea un lote con varias ofertas que ofrece al jugador la cantidad máxima de paquetes de maíz y una pala.
StarterBundle<public> := module:
Name<public><localizes> : message = "Starter bundle"
Description<public><localizes> : message = "Everything a new player needs. Get fully stocked to start quickly! A shovel that digs holes, and ten packs of corn seeds each containing 10 corn seeds for planting."
ShortDescription<public><localizes> : message = "A shovel that digs holes, and ten packs of corn seeds each containing 10 corn seeds for planting."
starter_bundle<public> := class(bundle_offer):
var Name<override> : message = StarterBundle.Name
var Description<override> : message = StarterBundle.Description
var ShortDescription<override> : message = StarterBundle.ShortDescription
var Icon<override> : texture = # your texture here
En Verse, los paquetes no contienen productos directamente. En cambio, contienen ofertas que a su vez tienen definiciones de productos.
Ofertas creadas de forma dinámica
Una oferta creada dinámicamente es una oferta o un lote de ofertas que se genera en tiempo de ejecución en Verse. Entre los casos de uso comunes de las ofertas dinámicas se pueden encontrar los siguientes:
Una oferta por la cantidad máxima de madera que un jugador puede tener para un juego de creación.
Un lote para maximizar las pociones de vida y maná a la entrada de una mazmorra para un explorador de mazmorras.
Para simplificar, vincúlalo a algo sencillo, como un botón o un letrero. En el código Verse, esto seguiría el siguiente flujo: Al interactuar > llamar a BuyOffer.
Este fragmento muestra una forma de vender un lote de semillas de maíz hasta la cantidad máxima que un jugador puede tener. Si la compra falla, se muestra un mensaje de error.
TryBuyOffer(Player : player)<suspends>:void =
Purchases := GetPurchasedEntitlements(Player, Entitlements.corn_seed_pack)
var NumPlayerCornSeedPacks : int = 0
if (Purchase := Purchases[0]):
set NumPlayerCornSeedPacks = Purchase(1)
# Limit to at least 1 packet.
# If the player has the maximum amount, the offer displays with a disabled purchase button.
NumCornSeedPacks := Max(1, Entitlements.corn_seed_pack{}.MaxCount - NumPlayerCornSeedPacks)
Reglas de validación de ofertas
Una oferta válida o una oferta por paquete debe cumplir con las siguientes directrices. Las compras que no cumplan con estas condiciones no pasarán la moderación. Las reglas que definen una oferta válida son las siguientes:
La profundidad de las ofertas anidadas no puede superar las 5.
El número total de identificadores de productos no puede superar los 100 por oferta. Esto significa que la cantidad total de diferentes productos vendidos a la vez es de 100 como máximo.
El precio de la oferta debe estar entre 50 y 5000 monedas V y solo puede ser múltiplo de 50.
El texto predeterminado para el
Namede una oferta no puede superar los 50 caracteres.El texto predeterminado de la
Descriptionde una oferta no puede superar los 500 caracteres.El texto predeterminado de la
ShortDescriptionde una oferta no puede superar los 100 caracteres.Una oferta debe incluir al menos 1 producto.
Una oferta no puede incluir una cantidad de un producto superior al
MaxCountdel producto.Una oferta no contiene un producto duradero con un
MaxCount> 1.
Podrás optar por establecer restricciones sobre dónde se muestran tus ofertas y quién puede verlas. Para obtener más información, consulta Restricciones a las transacciones dentro de la isla.
Crea una tienda
Ahora que ya tienes configurados tus productos y sus ofertas y lotes, ¡necesitas un lugar para venderlos!
La IU predeterminada
La IU predeterminada de la tienda se abre con una lista de todos los productos y las ofertas que añadiste. El primer producto de la lista aparece resaltado y muestra una descripción general del producto en una ventana junto a la lista.
Las tiendas pueden tener varias páginas.
Las listas con más de cinco objetos se pueden deslizar.
Un jugador inicia el proceso de compra llamando al método BuyOffer o utilizando la tienda predeterminada con el método ShowOffersDialog. A continuación, se muestran ejemplos de algunos dispositivos que puedes usar a fin de integrar el proceso de compra en tu tienda en el diseño de tu juego:
Dispositivo de volumen
Dispositivo de cronómetro de Scene Graph
PNJ
Dispositivo de conversación
A la hora de diseñar una tienda, lo más recomendable es requerirle al jugador que elija abrir un proceso de compra. Si omites esta opción y obligas a los jugadores a abrir el proceso de compra, se elimina la capacidad de decisión de los jugadores y puede generar que no sientan satisfacción.
Todas las ofertas tienen los botones Comprar e Inspeccionar, que abren ventanas del Marketplace para comprar un artículo o inspeccionar lo que incluye una oferta. Solo los lotes tienen el botón Inspeccionar lote.
Al seleccionar el botón Cerrar, se cierra el Marketplace.
La experiencia de la tienda la controla totalmente el desarrollador:
Tú decides qué objetos o propiedades de juego quieres ofrecer a tus jugadores.
También puedes establecer el precio de cada oferta u oferta por lote.
Puedes presentar tu propia tienda o utilizar la IU prediseñada de Fortnite.
La IU de la tienda
Este fragmento define una llamada de retorno de evento genérica que abre la IU prediseñada de la tienda de Fortnite. La llamada de retorno puede provenir de una suscripción, la pulsación de un botón, un evento de conversación, etc.
OnEvent(Agent:agent):void=
if(Player:= player[Agent]):
spawn{ShowOffersDialog(Player, array{
ExampleOffers.shovel{},
ExampleOffers.cornseedpacket{}
})}
Cómo controlar las ventas
Este fragmento incluye una compra de oferta genérica. Si la compra falla, se muestra un mensaje de error.
TryBuyOffer(Player:player, Offer : offer)<suspends>:void =
Result := BuyOffer(Player, Offer)
if (not Result?):
Print("Failed to buy the {offer.name} offer.")Para facilitar la depuración de las compras fallidas, incluye una forma de identificar qué compra falló en el mensaje de error, por ejemplo, al incluir el nombre de la oferta en el mensaje de error anterior.
Funciones adicionales
Objetos aleatorios pagos
Existen las siguientes dos formas de ofrecer objetos aleatorios pagos en tu isla:
Puedes ofrecerlos directamente para su compra con monedas V
Puedes ofrecerlos indirectamente al permitir que los jugadores compren productos con monedas V, las cuales luego pueden canjearse o afectar la probabilidad de recibir una recompensa aleatoria.
Al crear un elemento que otorga una recompensa aleatoria, debes establecer PaidRandomItem en true.
Si ofreces contenido que se puede utilizar para canjear una recompensa aleatoria, debes utilizar la función RestrictPaidRandomItems a fin de evitar que los jugadores sin acceso la adquieran.
OnEvent(Agent:agent):void=
if (Player := player[Agent]):
if (RestrictPaidRandomItems[Player]):
Print("Player is not allowed to purchase PaidRandomItems.")
else:
Print("Player is allowed to purchase PaidRandomItems.")
Indicaciones directas de compra
Si tu isla tiene indicaciones directas de compra, debes utilizar la función RestrictDirectPromptsToPurchase a fin de determinar si un jugador es elegible para recibirlas.
OnEvent(Agent:agent):void=
if (Player:= player[Agent]):
if (RestrictDirectPromptsToPurchase[Player]):
Print("Player is not allowed to receive direct purchase prompts.")
else:
Print("Player is allowed to receive direct purchase prompts.")
Consecuente con la jugabilidad
Si el objeto que vendes les da a los jugadores una ventaja importante en tu isla, debes establecer ConsequentialToGameplay como verdadero.
Los objetos que son consecuentes con la jugabilidad incluyen cualquiera que, de comprarse, proporcionan a los jugadores una ventaja importante en el juego. Esto puede ser directo (por ejemplo, un objeto que aumente la tasa de progreso del jugador, su poder o sus capacidades) o indirecto (por ejemplo, un objeto que otorgue acceso a otro objeto que tenga un impacto importante en la rapidez con la que el jugador puede avanzar en el juego o en su probabilidad de ganar).
Si existe una alternativa al objeto que estás vendiendo que esté disponible gratuitamente para todos los jugadores al mismo tiempo que se presenta la oferta y que proporcione la misma ventaja, entonces no necesitas establecer ConsequentialToGameplay en verdadero. Si el objeto de jugabilidad tiene un impacto incidental y no consecuente, como el caso en el que distintos colores de atuendos tienen distintas visibilidades en distintos entornos, o el hecho de que distintos gestos realicen distintos movimientos corporales, se considera que esto no es consecuente.
# The base entitlement you should define for ALL of your entitlements in your experience.
my_island_entitlement := class<abstract><castable>(entitlement){}
CornSeedPacket<public> := module:
Name<public><localizes> : message = "Corn seed pack"
Description<public><localizes> : message = "A pack of corn seeds. Opening a pack yields 10 corn seeds for planting."
ShortDescription<public><localizes> : message = "Contains 10 corn seeds for planting."
cornseedpacket<public> := class<concrete>(my_island_entitlement):
var Name<override>:message = CornSeedPacket.Name