Volver al Blog

Solucionando la falta de la opción Clear Player Data en Fortnite Creative: reseteos con Verse y recuperación de estado con Backend personalizado

Publicado el 19 de julio de 2026
Solucionando la falta de la opción Clear Player Data en Fortnite Creative: reseteos con Verse y recuperación de estado con Backend personalizado

En resumen

Este artículo aborda cómo solucionar el problema de la desaparición del botón 'Clear Player Data' en Fortnite Creative y UEFN implementando un sistema manual de versionado de esquemas en Verse. Se detalla el proceso para forzar la migración y limpieza de datos persistentes locales mediante código y la configuración del editor. Finalmente, se analizan las limitaciones de la persistencia nativa y cómo el uso de un Backend externo como [horizOn](https://horizon.pm) ofrece una solución definitiva y escalable.

Tu último mapa de Fortnite Creative o UEFN está listo. Has refactorizado tu economía, rediseñado tu sistema de clases y optimizado tu gameplay loop. Pero cuando vas a publicar, te encuentras con una pesadilla que rompe el motor: la opción "Press Triangle to Clear Player Data" ha desaparecido de la pantalla de confirmación de publicación. Estás atrapado. Tus jugadores están cargando el mapa con datos de persistencia obsoletos, lo que provoca stack overflows instantáneos, líneas de misiones rotas y desajustes de estado que cuelgan el juego.

Este problema exacto ha afectado a los creadores en los foros de desarrolladores de Epic, donde la repentina ausencia del botón de reset no deja ningún mecanismo basado en la interfaz de usuario para purgar estados de producción obsoletos. Cuando el esquema de tus datos de persistencia de jugadores cambia, el Backend de Epic intenta mapear los datos serializados antiguos en tus nuevas estructuras. Si tu código no está diseñado para manejar estas propiedades desajustadas de manera limpia, romperás por completo el estado del juego para el 100% de los jugadores que regresen.

En este tutorial, analizaremos a fondo las soluciones técnicas temporales para este bug. Te mostraremos cómo construir un sistema robusto de versionado de esquemas en Verse, configurar los ajustes locales de UEFN para borrar los estados de prueba y explorar cómo los backends externos personalizados pueden liberarte de las limitaciones de la persistencia de plataformas cerradas.

La causa raíz: por qué fallan los esquemas en las actualizaciones de versión

En Fortnite Creative y Unreal Editor for Fortnite (UEFN), los datos persistentes se almacenan en la infraestructura de bases de datos de Epic mediante estructuras weak_map. Un weak_map vincula una instancia de jugador a una clase personalizada marcada con el especificador <persistable>. A diferencia de las bases de datos SQL o documentales tradicionales, la capa de almacenamiento de Epic no ejecuta un pipeline de migración formal cuando lanzas una actualización. En su lugar, intenta deserializar cualquier payload binario que exista en el guardado en la nube del jugador en la definición actual de la clase de Verse.

Cuando eliminas una variable, renombras una propiedad o cambias un tipo (por ejemplo, cambiar un campo de int a float), el deserializador encuentra un desajuste. Dependiendo de la gravedad del cambio, esta divergencia de esquema da como resultado uno de estos tres modos de fallo:

  • Fallos silenciosos: El runtime asigna valores por defecto a las propiedades modificadas, borrando el progreso de todos modos pero sin colgarse.
  • Corrupción del estado: La aplicación lee estados de memoria inválidos o se encuentra con estructuras de datos inesperadas, lo que provoca errores de lógica en otras partes.
  • Cuelgues graves de runtime: El mapa no se carga o la Verse VM detiene la ejecución porque no puede desempaquetar el mapa persistente.

Cuando el botón "Clear Player Data" de la consola de publicación desaparece, pierdes la capacidad de hacer borrón y cuenta nueva a nivel global. Si un desarrollador realiza cambios fundamentales en el diseño de sus datos de guardado, el juego se rompe.

La solución manual: versionado de esquemas dentro de Verse

Dado que no puedes depender del portal de publicación de Epic para borrar los datos, debes implementar un fallback a nivel de software. La estrategia es sencilla: introduce un rastreador de versiones directamente en tus clases persistentes. Al comparar la versión guardada del jugador con la versión activa de la aplicación al inicio de la sesión, puedes identificar los guardados obsoletos y sobrescribirlos con valores por defecto.

Aquí tienes una implementación de Verse lista para producción que configura una capa de persistencia controlada por versiones.

using { /Fortnite.com/Devices }
using { /Fortnite.com/Characters }
using { /Fortnite.com/Playspaces }
using { /Verse.org/Simulation }

# Una clase persistente simple que representa nuestro esquema de guardado de jugadores.
# Nota: Las clases etiquetadas con <persistable> solo pueden contener ciertos tipos como int, float, string y maps.
player_save_data := class<persistable>:
    # El SchemaVersion realiza un seguimiento de a qué generación de datos de jugador pertenece esta estructura.
    SchemaVersion : int = 0
    GoldCount : int = 0
    XP : int = 0
    HasCompletedTutorial : int = 0  # Uso de int como representación de flag booleana para restricciones de Verse más antiguas

# El dispositivo persistence_manager_device maneja la carga, validación y migración de datos de jugadores.
persistence_manager_device := class(creative_device):

    # Al actualizar este valor en el Editor, forzamos una migración de esquema la próxima vez que se ejecute el juego.
    @editable
    TargetSchemaVersion : int = 2

    # Map para almacenar datos de jugadores en memoria
    var PlayerDataMap : weak_map(player, player_save_data) = map{}

    # Inicializa la lógica de persistencia para un jugador que se une
    InitializePlayer(Player : player) : void =
        # Comprobar si el jugador ya tiene datos persistentes
        if (ExistingData := PlayerDataMap[Player]):
            # Si la versión almacenada es anterior a nuestra versión objetivo, activa un reseteo manual
            if (ExistingData.SchemaVersion < TargetSchemaVersion):
                Print("Data version mismatch. Local: {ExistingData.SchemaVersion}, Target: {TargetSchemaVersion}. Resetting player data.")
                ResetPlayerData(Player)
            else:
                Print("Loaded existing player data. Version: {ExistingData.SchemaVersion}")
        else:
            # Si no existen datos, inicializa un nuevo registro con la versión actual
            Print("No player data found. Initializing new record.")
            ResetPlayerData(Player)

    # Vuelve a inicializar el registro de un jugador con valores por defecto en la versión actual
    ResetPlayerData(Player : player) : void =
        NewData := player_save_data:
            SchemaVersion := TargetSchemaVersion
            GoldCount := 0
            XP := 0
            HasCompletedTutorial := 0

        # Guarda el bloque de datos recién inicializado en el map de persistencia
        if (set PlayerDataMap[Player] = NewData):
            Print("Successfully saved fresh persistent data block.")

Desglosando el script de versionado

Este patrón se basa en una validación temprana dentro del método InitializePlayer. La lógica paso a paso se desarrolla de la siguiente manera:

  1. La comprobación de entrada: Cuando un jugador se une, el sistema consulta en PlayerDataMap una instancia existente de player_save_data.
  2. La evaluación de la versión: Si existe un estado de guardado, el motor comprueba su propiedad SchemaVersion.
  3. El activador de migración: Si SchemaVersion es menor que la propiedad @editable TargetSchemaVersion del dispositivo, el script llama a ResetPlayerData(Player).
  4. Sobrescritura de estado: ResetPlayerData construye una nueva instancia de player_save_data configurada con el nuevo TargetSchemaVersion y actualiza el map.

Al incrementar manualmente TargetSchemaVersion en la configuración de tu dispositivo dentro de UEFN, fuerzas un borrado de datos objetivo para todos los jugadores en la inicialización de su próxima sesión, haciendo que la ausencia del botón en la interfaz de Epic sea irrelevante.

Procedimiento de prueba paso a paso

Para validar de forma segura este script de migración dentro de tu ciclo de playtest, sigue estos pasos secuenciales:

  1. Arrastra tu persistence_manager_device personalizado al viewport de tu nivel en UEFN.
  2. En el panel de Detalles de UEFN, establece el TargetSchemaVersion inicial en 1.
  3. Inicia una sesión de juego, acumula algo de puntuación u oro y luego finaliza la partida.
  4. De vuelta en el editor, actualiza el campo TargetSchemaVersion en el dispositivo de 1 a 2.
  5. Inicia la sesión de nuevo. Observa la salida del registro de la consola: 'Data version mismatch. Local: 1, Target: 2. Resetting player data.'
  6. Verifica que el oro y el progreso de tu jugador se hayan reseteado limpiamente sin colgar la Verse VM.

Ajustes de desarrollo local: omitir archivos de guardado durante la iteración

Aunque el versionado de código en runtime resuelve los problemas en los servidores en vivo, añade una fricción no deseada durante el playtesting local. Modificar manualmente el número de versión dentro de UEFN cada vez que modificas una característica en desarrollo resulta tedioso. Para optimizar tu proceso de depuración, puedes omitir la persistencia local por completo a través de la configuración del editor.

Sigue estos pasos para desactivar la persistencia local:

  1. En UEFN, navega a Island Settings en el panel Outliner.
  2. Busca la subsección User Options - Game Rules.
  3. Localiza la opción Enable Persistence y desactívala.
  4. Si estás probando bucles de Multiplayer localmente, abre las Editor Preferences, dirígete al menú In-Game Play y localiza la casilla Clear Local Saved Data On Launch. Marcar esto asegura que cada simulación comience con un caché vacío.

Sin embargo, las omisiones locales no simulan escenarios de producción. Aunque las velocidades de iteración en las pruebas pueden bajar de 45 segundos a menos de 5 segundos con la caché de persistencia desactivada, debes ejecutar al menos un ciclo completo de staging con la persistencia activada antes de pasar a producción. Aquí es donde los obstáculos de conexión pueden complicarse. Las configuraciones de playtest local son conocidas por conflictos de controladores, lo que hace que los desarrolladores pierdan un tiempo valioso diagnosticando controladores de red de Unreal Engine durante los tiempos de espera de inicio de sesión de UEFN.

Limitaciones de la persistencia integrada de UEFN

El uso de la capa de persistencia nativa de Verse conlleva importantes limitaciones arquitectónicas. Incluso cuando las opciones de borrado en la nube funcionan a la perfección, los desarrolladores están limitados por restricciones estrictas de la plataforma:

  • Presupuestos de almacenamiento: Los bloques de datos persistentes están limitados a 12 KB por jugador y sesión. Superar este límite impide que se guarde el estado.
  • Solo tipos primitivos: No puedes serializar clases personalizadas que no estén marcadas como <persistable>, ni puedes almacenar referencias a objetos del juego (como creative_device o actores dinámicos).
  • Sin consultas externas: El sistema de Epic es una caja negra completa. No puedes consultar los datos de los jugadores desde un panel externo, auditar los estados de los usuarios en busca de exploits ni migrar bases de datos dinámicamente.
  • Cuellos de botella en telemetría: El diseño de paneles de analíticas complejos dentro de UEFN está fuertemente limitado por las restricciones de longitud de cadena. Por ejemplo, los desarrolladores luchan constantemente con las restricciones al superar el límite de 32 caracteres para el nombre del evento del dispositivo de analíticas en UEFN.

Para minijuegos casuales, estos límites son manejables. Pero para RPGs persistentes complejos, shooters con live-ops o títulos multiplataforma, depender únicamente de una persistencia patentada y de bucle cerrado bloquea tu camino de escalabilidad.

La alternativa del arquitecto: estados de base de datos externos con horizOn

Para construir un juego escalable que no esté restringido por bugs de interfaz específicos de la plataforma o tamaños de datos propietarios, los desarrolladores están recurriendo a arquitecturas de Backend externas. En lugar de almacenar los estados del juego en los mapas de memoria local de Verse, tu proyecto de UEFN puede comunicarse con una base de datos externa utilizando el módulo http_client de Verse.

Este enfoque te otorga un control total sobre el ciclo de guardado del jugador. Cuando necesitas borrar los datos de persistencia del jugador, no tienes que buscar un botón que falta en la consola de Epic ni subir una actualización de código. Simplemente puedes ejecutar un script de base de datos administrativo o hacer clic en un solo botón en tu panel de control del Backend para borrar, migrar o parchear las tablas de los jugadores.

Construir esto por tu cuenta requiere configurar Load Balancing, fragmentación de bases de datos y gestión de certificados SSL; fácilmente de 4 a 6 semanas de trabajo. Con horizOn, estos servicios de Backend vienen preconfigurados, lo que te permite lanzar tu juego en lugar de preocuparte por tu infraestructura.

Al canalizar los estados de los jugadores a través de horizOn, tu código de Verse se convierte en un cliente simple que lee y escribe el estado a través de endpoints REST limpios:

# Pseudocódigo que muestra la sincronización de estado basada en HTTP con [horizOn](https://horizon.pm)
sync_manager_device := class(creative_device):

    # Envía el progreso del jugador al endpoint de [horizOn](https://horizon.pm)
    SavePlayerState(Player : player, SaveData : player_save_data) : void =
        # En un entorno real, construyes un payload JSON y lo envías
        # a través del http_client de Verse. Esto evita el límite de persistencia local de 12 KB.
        RequestURL := "https://api.horizon.pm/v1/players/{GetPlayerID(Player)}/state"
        Print("Dispatching persistent payload to [horizOn](https://horizon.pm) at: {RequestURL}")
        
        # Esto mantiene el payload del lado del servidor ligero (menos de 240 bytes) 
        # al tiempo que asegura el almacenamiento a largo plazo fuera del motor de Fortnite.

Esta configuración desvincula por completo tu gameplay loop de los bugs físicos del Backend de la plataforma. Si un parche rompe la compatibilidad de tu guardado local, puedes activar una migración de esquema específica en tu base de datos de horizOn en tiempo real, con cero interrupciones en el servidor de juego en vivo. Evitas el riesgo de romper los servidores en producción por pequeños ajustes estructurales.

Buenas prácticas para gestionar la persistencia del estado del juego

Tanto si te limitas a los maps nativos de Verse como si aprovechas una arquitectura de servidores externos, mantener un ciclo de vida de persistencia estable es vital para los juegos Multiplayer. Sigue estos principios para proteger los estados de los jugadores:

  1. Implementa un versionado implícito de forma temprana: Incluye siempre un entero SchemaVersion en tu diseño inicial de datos de guardado. Incluso si no planeas modificar tu esquema, tener la clave de versión desde el primer día evita la corrupción catastrófica de datos a largo plazo.
  2. Aplica reglas de validación de estado: Al leer el estado cargado, valida los rangos de cada atributo. Si el recuento de oro guardado de un jugador es negativo o supera el límite estructural de tu mapa, resetea esa propiedad específica para evitar exploits en la economía.
  3. Minimiza la frecuencia de guardado: Escribir en la nube es costoso. En lugar de actualizar la base de datos con cada moneda recogida, agrupa tus escrituras. Activa los guardados durante hitos clave, como la finalización de la partida, la subida de nivel del jugador o cuando el jugador abandona la sesión.
  4. Construye estructuras de fallback limpias: Nunca permitas que una lectura fallida impida que un jugador entre al juego. Si el payload de persistencia no se deserializa correctamente, recurre a una estructura de estado por defecto de forma instantánea.
  5. Desacopla el código de gameplay de la lógica de almacenamiento: Mantén tus consultas de almacenamiento aisladas en un dispositivo gestor de persistencia dedicado. Tus dispositivos de armas, progresión e interfaz de usuario deberían consultar a este gestor en lugar de hacer llamadas directas al map de datos.

Próximos pasos

Depender de la interfaz de usuario de la consola de Epic para gestionar migraciones de estado críticas es un patrón de diseño arriesgado. Cuando la opción "Clear Player Data" falla, el versionado en runtime dentro de Verse sirve como tu primera línea de defensa. Sin embargo, si tu juego exige guardados de alta frecuencia, telemetría compleja o un control administrativo completo, migrar tu base de datos a un Backend dedicado es la solución definitiva.

¿Listo para escalar tu Backend Multiplayer? Prueba horizOn de forma gratuita o consulta la documentación de la API.


Fuente: botón clear players data en creative 1