Volver al Blog

Cómo solucionar fallos de login en Blueprints de Unreal y errores de logros en Epic Online Services

Publicado el 9 de julio de 2026
Cómo solucionar fallos de login en Blueprints de Unreal y errores de logros en Epic Online Services

En resumen

Esta guía detalla cómo solucionar los fallos de login y registro de logros en Unreal Engine al integrar Epic Online Services. Explica la importancia de vincular correctamente el Epic Account ID (EAID) y el Product User ID (PUID) a través de la Connect Interface. Además, se aborda el flujo asíncrono requerido en Blueprints y C++, proporcionando ejemplos de código y configuraciones de DefaultEngine.ini para evitar errores silenciosos en producción.

Compilas una shipping build de tu juego en Unreal Engine, lo inicias desde el Epic Games Launcher y haces clic en tu botón de login personalizado. No pasa nada, o el cliente del juego se congela, y tus logs se llenan de crípticos avisos de fallos de autenticación. Peor aún, el nodo para desbloquear logros se ejecuta sin lanzar ningún error visible, pero el perfil del jugador en el overlay de Epic Games Store sigue completamente vacío. Estos errores son increíblemente comunes al integrar API de tiendas digitales. Afortunadamente, se pueden resolver corrigiendo el flujo de ejecución asíncrona y comprendiendo cómo el subsistema mapea las identidades de los usuarios.

Entendiendo el pipeline de autenticación de EOS: EAID vs. PUID

Integrar Epic Online Services (EOS) a través del Online Subsystem (OSS) de Unreal Engine requiere navegar por un sistema de identidad de dos niveles. El Epic Account ID (EAID) es gestionado por la Auth Interface. Este valida quién es el usuario a nivel de tienda, habilitando características como el overlay social, las listas de amigos y las verificaciones de la biblioteca de Epic Games Store.

Por el contrario, el Product User ID (PUID) es gestionado por la Connect Interface. El PUID es un identificador específico del juego que vincula al usuario con los servicios de backend del juego. Estos servicios incluyen matchmaking, estadísticas, cloud saves y logros.

Por qué la falta de coincidencia entre EAID y PUID rompe los logros

Un modo de fallo común ocurre cuando los desarrolladores se autentican con éxito en la Auth Interface (generando un EAID), pero el subsistema no logra iniciar sesión en la Connect Interface. Dado que los logros son gestionados por la Connect Interface mediante PUIDs, intentar registrar el progreso de un logro sin un PUID resuelto fallará con un error EOS_InvalidUser.

En juegos que se lanzan sin el wrapper de una tienda digital, los usuarios suelen iniciar sesión con credenciales que se verifican contra una tabla de usuarios centralizada. En un ecosistema de tienda moderno como Epic Games Store, la identidad es federada. Cuando tu juego se inicia, recibe un ticket criptográfico del launcher. Luego, el juego pasa este ticket a los servidores de autenticación de la tienda. El SDK devuelve un Epic Account ID, que actúa como el pasaporte del usuario para todos los juegos de la plataforma.

Sin embargo, para mantener la privacidad y la seguridad del cross-play, Epic no permite que las funciones específicas del juego, como los logros, lean el Epic Account ID directamente. En su lugar, el juego debe inicializar la Connect Interface, que realiza un intercambio secundario para obtener un Product User ID. Esta separación garantiza que, si tu juego es hackeado, las credenciales globales de la Epic Account de los jugadores no se vean comprometidas. Sin el PUID, tu juego está operando prácticamente en un estado de invitado no autenticado, bloqueando el acceso a las funciones de EGS. Si tu configuración de credenciales o tu client policy carecen de los permisos correctos en el Epic Developer Portal, esta vinculación fallará. La interfaz de identidad informará de un login exitoso porque la cuenta de Epic es válida, pero la capa de servicios de juego no podrá registrar los datos de los logros porque nunca se vinculó ningún PUID.

Anatomía de una secuencia de login incorrecta en Blueprints

Muchos desarrolladores se topan con problemas de login al encadenar de forma lineal los pines de ejecución de sus Blueprints. Conectar el pin de ejecución de un nodo Login directamente a un nodo Query Achievements o Write Achievement Progress siempre fallará.

Las solicitudes de autenticación deben viajar al backend de Epic, lo que las hace asíncronas. El motor continúa ejecutando el grafo de Blueprints en el siguiente frame, mucho antes de que los servidores de Epic devuelvan las credenciales del usuario. En esta etapa, el Unique Net ID del jugador sigue siendo nulo.

El error de "nodo faltante": condiciones de carrera en la ejecución asíncrona

Si llamas a los nodos de logros inmediatamente después del nodo de login, el subsistema lanzará un error silencioso porque el estado de usuario en caché está vacío. El flujo de trabajo correcto requiere vincular custom events a los delegates asíncronos del subsistema.

Además, los desarrolladores a menudo omiten el paso crucial de almacenar los logros en caché antes de escribir en ellos. No puedes modificar el progreso de un logro sin consultar primero al servidor para obtener el esquema actual. Llamar a Write Achievements sin una llamada previa a Query Achievements resulta en un fallo silencioso o en un error EOS_InvalidUser en tu log de consola porque el tamaño del mapa de logros local en caché es 0.

El flujo de Blueprint asíncrono correcto

Para resolver esto, debes separar el trigger del login de la actualización del logro. Primero, llama al nodo de login y especifica las credenciales de autenticación correctas.

Segundo, vincula un evento al delegate On Login Complete de la interfaz de identidad. Una vez que este evento se dispare y devuelva un estado de éxito, obtén el Unique Net ID del usuario.

Tercero, pasa este ID al nodo Query Achievements. Finalmente, vincula un evento al delegate On Query Achievements Complete, y solo llama a Write Achievement Progress dentro de esa callback.

Implementación de un controlador robusto de login y logros de EOS en C++

Para manejar estas operaciones asíncronas de manera limpia, se recomienda encarecidamente implementar el bucle de autenticación en C++. Esto proporciona acceso directo a IOnlineSubsystem y sus interfaces.

A continuación, se muestra una implementación completa y lista para producción en C++ de un manejador de login y logros:

#include "OnlineSubsystem.h"
#include "Interfaces/OnlineIdentityInterface.h"
#include "Interfaces/OnlineAchievementsInterface.h"
#include "OnlineSubsystemUtils.h"

void UEOSLoginHandler::LoginToEpicGames(APlayerController* PlayerController)

{
    if (!PlayerController) return;

    IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get(TEXT("EOS"));
    if (!Subsystem)
    {
        UE_LOG(LogTemp, Warning, TEXT("EOS Subsystem not found. Make sure the plugin is enabled."));
        return;
    }

    IOnlineIdentityPtr Identity = Subsystem->GetIdentityInterface();
    if (Identity.IsValid())
    {
        FOnlineAccountCredentials Credentials;
        Credentials.Type = TEXT("ExchangeCode");
        Credentials.Id = TEXT("");
        Credentials.Token = TEXT(""); // The launcher passes this via command line arguments

        Identity->AddOnLoginCompleteDelegate_Handle(0, FOnLoginCompleteDelegate::CreateUObject(this, &UEOSLoginHandler::OnLoginComplete));
        Identity->Login(0, Credentials);
    }
}

void UEOSLoginHandler::OnLoginComplete(int32 LocalUserNum, bool bWasSuccessful, const FUniqueNetId& UserId, const FString& Error)
{
    if (!bWasSuccessful)
    { 
        UE_LOG(LogTemp, Error, TEXT("Epic Online Services Login Failed. Error: %s"), *Error);
        return;
    }

    UE_LOG(LogTemp, Log, TEXT("EOS Login Successful. ID resolved: %s"), *UserId.ToString());

    IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get(TEXT("EOS"));
    IOnlineAchievementsPtr Achievements = Subsystem->GetAchievementsInterface();
    if (Achievements.IsValid())
    { 
        Achievements->QueryAchievements(UserId, FOnQueryAchievementsCompleteDelegate::CreateUObject(this, &UEOSLoginHandler::OnQueryAchievementsComplete));
    }
}

void UEOSLoginHandler::OnQueryAchievementsComplete(const FUniqueNetId& PlayerId, bool bWasSuccessful)
{
    if (!bWasSuccessful)
    {
        UE_LOG(LogTemp, Warning, TEXT("Failed to query achievements from Epic Developer Portal."));
        return;
    }

    UE_LOG(LogTemp, Log, TEXT("Achievements queried successfully. Now writing progress."));

    IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get(TEXT("EOS"));
    IOnlineAchievementsPtr Achievements = Subsystem->GetAchievementsInterface();
    if (Achievements.IsValid())
    {
        FOnlineAchievementsWriteRef WriteObject = MakeShared<FOnlineAchievementsWrite>();
        WriteObject->SetFloatStat(TEXT("ACH_FIRST_BLOOD"), 100.0f);

        Achievements->WriteAchievements(PlayerId, WriteObject, FOnAchievementsWrittenDelegate::CreateUObject(this, &UEOSLoginHandler::OnAchievementsWritten));
    }
}

void UEOSLoginHandler::OnAchievementsWritten(const FUniqueNetId& PlayerId, bool bWasSuccessful)
{
    if (bWasSuccessful)
    {
        UE_LOG(LogTemp, Log, TEXT("Achievement successfully unlocked on Epic Games Store!"));
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to write achievement progress. Check sandbox mappings."));
    }
}

Este controlador utiliza callbacks secuenciales. Garantiza que solo se acceda a la interfaz de logros una vez que la interfaz de identidad haya resuelto con éxito tanto el Epic Account ID como el Product User ID.

Configuración de tu archivo DefaultEngine.ini para EOS

Los nodos de login de Blueprints no se inicializarán si las configuraciones en tu archivo Config/DefaultEngine.ini son incorrectas. El plugin Online Subsystem EOS requiere parámetros específicos para vincularse con el cliente de tu juego.

Usa la siguiente plantilla de configuración para asegurarte de que tu subsistema se inicialice correctamente:

[OnlineSubsystem]
DefaultPlatformService=EOS

[OnlineSubsystemEOS]
bEnabled=true
bUseEpicConnect=true
ProductId=your_product_id_here
SandboxId=your_sandbox_id_here
DeploymentId=your_deployment_id_here
ClientId=your_client_id_here
ClientSecret=your_client_secret_here

[OnlineSubsystemEOS.Auth]
bUseEpicAccount=true

La configuración de tu archivo DefaultEngine.ini actúa como puente entre los binarios compilados de tu juego y el Epic Developer Portal. Los parámetros dentro de [OnlineSubsystemEOS] deben coincidir exactamente con los ajustes de tu producto.

Una fuente común de confusión es la diferencia entre las client credentials y los sandbox IDs. El Client ID y el Client Secret representan las credenciales del cliente de tu juego, lo que le permite comunicarse con el backend de EOS. El Sandbox ID representa el entorno específico (como Development, Staging o Live) al que está accediendo tu cliente.

Si el cliente de tu juego intenta autenticarse con un Sandbox ID que no coincide con la política de Client Credentials, la solicitud de autenticación será rechazada. Además, el flag bUseEpicConnect debe establecerse en true para asegurar que el Online Subsystem maneje el mapeo de EAID a PUID de forma automática en segundo plano.

Gestión de conflictos de foco del overlay e integración con plataformas

El plugin EOS de Unreal depende en gran medida del Epic Games Overlay para mostrar notificaciones, gestionar invitaciones de amigos y realizar autenticaciones web OAuth. Cuando el cliente de tu juego activa un login utilizando el tipo de credencial AccountPortal, el sistema operativo abre una ventana del navegador o despliega el overlay.

Esta redirección quita el foco de la ventana del juego. Si tus modos de entrada (input modes) no están configurados para manejar la pérdida de foco, el juego puede bloquearse o registrar teclas atascadas.

Lidiar con problemas de entrada (input) causados por overlays es un dolor de cabeza habitual para los desarrolladores de PC. Por ejemplo, la inyección del overlay puede entrar en conflicto con los drivers de entrada nativos (raw input) y provocar que los estados del teclado y del ratón se congelen. Para evitar que estos bugs arruinen la experiencia del jugador, puedes consultar nuestro análisis sobre The Marathon Input Issues Fix: Architecting PC Games to Survive Overlay Conflicts.

Además, los fallos de inicialización durante las pruebas suelen deberse a conexiones socket mal configuradas o a límites de tiempo de espera (timeouts) en tu configuración local. Si estás solucionando problemas de timeouts del driver durante el inicio de la sesión, consulta nuestra guía sobre Uefn Session Launch Timeout Nightmares: Diagnosing Unreal Engine Network Drivers.

Simplificación de backends de tiendas multiplataforma

Configurar manualmente los subsistemas de las tiendas, escribir cadenas de delegates en C++ y lidiar con los problemas de foco del overlay específicos de cada plataforma consume muchísimo tiempo. Hacer esto para múltiples tiendas como Steam, EGS y consolas multiplica tu carga de trabajo de desarrollo.

Desarrollar esto por tu cuenta requiere configurar balanceadores de carga (load balancers), sharding de bases de datos y la gestión de certificados SSL; fácilmente de 4 a 6 semanas de trabajo.

Con horizOn, obtienes un backend multiplataforma unificado que abstrae estas API de las tiendas. En lugar de lidiar con tokens de identidad dual (EAID/PUID), sandboxes de Epic o código de inicialización de Steamworks, utilizas una única API que maneja perfiles de usuario, logros, matchmaking y tablas de clasificación (leaderboards).

horizOn actúa como un puente, sincronizando automáticamente los logros y el progreso de los jugadores con cualquier tienda desde la que se inicie el juego, lo que te permite concentrarte en el game loop en lugar del código boilerplate de las tiendas. Esto significa que tus jugadores pueden desbloquear logros, acceder a cloud saves y buscar partidas independientemente de la plataforma o launcher que utilicen, sin que tengas que escribir una sola línea de código de SDK específica de cada tienda.

Buenas prácticas modernas para integraciones de Epic Online Services

  1. Nunca encadenes nodos asíncronos directamente: Espera siempre a que se disparen los delegates OnLoginComplete y OnQueryAchievementsComplete antes de ejecutar operaciones posteriores, como escribir estadísticas o logros.

  2. Habilita el logging detallado (verbose logging) durante el desarrollo: Añade las siguientes líneas a tu DefaultEngine.ini bajo [Core.Log] para rastrear advertencias ocultas de EOS:

    [Core.Log]
    LogOnline=VeryVerbose
    LogOnlineGame=VeryVerbose
    LogEOSSDK=VeryVerbose
    
  3. Mapea los logros a EOS en el Dev Portal: Asegúrate de que los logros creados bajo la Epic Games Store (EGS) estén explícitamente mapeados a tu backend de Epic Online Services (EOS). Si no están vinculados, el SDK de EOS no reconocerá la ID del logro.

  4. Usa ExchangeCode en shipping builds: Durante el desarrollo local, el tipo de login Developer con una Dev Auth Tool resulta conveniente, pero debes cambiar el tipo de credenciales a ExchangeCode en las shipping builds que se inicien desde el Epic Games Launcher. El uso del tipo de autenticación ExchangeCode provisto por el launcher omite la redirección de OAuth en el navegador web, reduciendo la duración de la secuencia de login de 8-12 segundos de interacción manual del usuario a un handshake automatizado de menos de 500 ms.

Agilizando las integraciones con tiendas

Resolver los errores de login y de logros de Epic Online Services en Unreal Engine se reduce a comprender el pipeline asíncrono y mantener los perfiles de configuración perfectamente alineados. Al gestionar la transición entre las interfaces de identidad y de servicios de juego, los desarrolladores pueden eliminar los errores silenciosos y ofrecer una experiencia de juego fluida.

¿Listo para escalar tu backend multiplayer? Prueba horizOn gratis o consulta la documentación de la API.


Fuente: Epic Games Store (Online Services AND Achievements)