Comment corriger les échecs de login et les erreurs d'achievements Epic Online Services dans les Blueprints Unreal
En bref
Ce guide explique comment corriger les erreurs de connexion et d'achievements d'Epic Online Services (EOS) dans Unreal Engine. Il détaille le pipeline d'authentification à double niveau (EAID et PUID) ainsi que la gestion correcte des requêtes asynchrones en Blueprint et en C++. Enfin, il présente les meilleures pratiques de configuration pour `DefaultEngine.ini` et montre comment simplifier l'intégration cross-platform avec horizOn.
Vous compilez un shipping build de votre jeu Unreal Engine, le lancez depuis l'Epic Games Launcher, et cliquez sur votre bouton de login personnalisé. Rien ne se produit, ou le client du jeu freeze, et vos logs se remplissent de notifications d'échec d'authentification cryptiques. Pire encore, votre node d'unlock d'achievement s'exécute sans renvoyer d'erreur visible, mais le profil du joueur dans l'overlay de l'Epic Games Store reste totalement vide. Ces erreurs sont extrêmement courantes lors de l'intégration des API de storefronts. Heureusement, elles peuvent être résolues en corrigeant votre flux d'exécution asynchrone et en comprenant comment le subsystem mappe les identités des utilisateurs.
Understanding the EOS Authentication Pipeline: EAID vs. PUID
L'intégration d'Epic Online Services (EOS) via l'Online Subsystem (OSS) d'Unreal Engine nécessite de naviguer dans un système d'identité à deux niveaux. L'Epic Account ID (EAID) est géré par l'Auth Interface. Il valide l'identité de l'utilisateur au niveau du storefront, activant des fonctionnalités telles que l'overlay social, les listes d'amis et les vérifications de la bibliothèque de l'Epic Games Store.
À l'inverse, le Product User ID (PUID) est géré par la Connect Interface. Le PUID est un identifiant spécifique au jeu qui lie l'utilisateur aux services de backend de jeu. Ces services incluent le matchmaking, les stats, les cloud saves et les achievements.
Why EAID and PUID Mismatches Break Achievements
Un failure mode classique se produit lorsque les développeurs s'authentifient avec succès auprès de l'Auth Interface (générant un EAID), mais que le subsystem ne parvient pas à se connecter à la Connect Interface. Étant donné que les achievements sont gérés par la Connect Interface à l'aide des PUID, l'écriture de la progression d'un achievement sans un PUID résolu échoue avec une erreur EOS_InvalidUser.
Dans les jeux lancés sans wrapper de storefront, les utilisateurs se connectent généralement avec des identifiants qui sont vérifiés par rapport à une table d'utilisateurs centralisée. Dans un écosystème de storefront moderne comme l'Epic Games Store, l'identité est fédérée. Lorsque votre jeu se lance, il reçoit un ticket cryptographique de la part du launcher. Le jeu transmet ensuite ce ticket aux serveurs d'authentification du storefront. L'SDK renvoie un Epic Account ID, qui sert de passeport à l'utilisateur pour tous les jeux de la plateforme.
Cependant, pour préserver la confidentialité et la sécurité du cross-play, Epic ne permet pas aux fonctionnalités spécifiques au jeu comme les achievements de lire directement l'Epic Account ID. Au lieu de cela, le jeu doit initialiser the Connect Interface, qui effectue un échange secondaire pour récupérer un Product User ID. Cette séparation garantit que si votre jeu est hacké, les identifiants Epic Account globaux des joueurs ne sont pas compromis. Sans le PUID, votre jeu fonctionne concrètement dans un état d'invité non authentifié, bloquant l'accès aux fonctionnalités d'EGS. Si votre configuration d'identifiants ou votre client policy ne dispose pas des bonnes permissions dans l'Epic Developer Portal, cette liaison échoue. L'interface d'identité signale un login réussi car le compte Epic est valide, mais la couche de services de jeu ne peut pas écrire les données d'achievements car aucun PUID n'a jamais été lié.
The Anatomy of a Broken Blueprint Login Sequence
De nombreux développeurs rencontrent des problèmes de login en enchaînant les execution pins de leurs Blueprints de manière linéaire. Glisser l'execution pin depuis un node Login directement vers un node Query Achievements ou Write Achievement Progress échouera systématiquement.
Les requêtes d'authentification doivent transiter vers le backend d'Epic, ce qui les rend asynchrones. Le moteur continue d'exécuter le graphe de Blueprint dès la frame suivante, bien avant que les serveurs d'Epic ne renvoient les identifiants de l'utilisateur. À ce stade, l'Unique Net ID du joueur reste null.
The "Missing Node" Mismatch: Race Conditions in Async Execution
Si vous appelez des nodes d'achievements immédiatement après le node de login, le subsystem génère une erreur silencieuse car l'état de l'utilisateur mis en cache est vide. Le workflow correct nécessite de lier des événements personnalisés aux delegates asynchrones du subsystem.
De plus, les développeurs oublient souvent l'étape cruciale de la mise en cache des achievements avant d'y écrire. Vous ne pouvez pas modifier la progression d'un achievement sans avoir préalablement interrogé le serveur pour obtenir le schéma actuel. Appeler Write Achievements sans appel préalable à Query Achievements entraîne un échec silencieux ou une erreur EOS_InvalidUser dans votre console log car la taille de la map d'achievements locale mise en cache est de 0.
The Correct Asynchronous Blueprint Flow
Pour résoudre ce problème, vous devez séparer le déclencheur de login de la mise à jour de l'achievement. Tout d'abord, appelez le node de login et spécifiez les identifiants d'authentification corrects.
Deuxièmement, liez un événement au delegate On Login Complete de l'interface d'identité. Une fois que cet événement se déclenche et renvoie un statut de succès, récupérez l'Unique Net ID de l'utilisateur.
Troisièmement, passez cet ID dans le node Query Achievements. Enfin, liez un événement au delegate On Query Achievements Complete, et appelez Write Achievement Progress uniquement dans ce callback.
Implementing a Robust EOS Login & Achievement Controller in C++
Pour gérer proprement ces opérations asynchrones, il est fortement recommandé d'implémenter la boucle d'authentification en C++. Cela permet un accès direct à l'IOnlineSubsystem et à ses interfaces.
Vous trouverez ci-dessous une implémentation C++ complète et prête pour la production d'un gestionnaire de login et d'achievements :
#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."));
}
}
Ce controller utilise des callbacks séquentiels. Il garantit que l'interface d'achievements n'est accessible qu'une fois que l'interface d'identité a résolu avec succès à la fois l'Epic Account ID et le Product User ID.
Configuring your DefaultEngine.ini File for EOS
Les nodes de login Blueprint ne parviendront pas à s'initialiser si les configurations de votre fichier Config/DefaultEngine.ini sont incorrectes. Le plugin Online Subsystem EOS nécessite des paramètres spécifiques pour se lier à votre client de jeu.
Utilisez le modèle de configuration suivant pour vous assurer que votre subsystem s'initialise correctement :
[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 configuration de votre fichier DefaultEngine.ini sert de pont entre vos binaires de jeu compilés et l'Epic Developer Portal. Les paramètres sous [OnlineSubsystemEOS] doivent correspondre exactement aux paramètres de votre produit.
Une source courante de confusion est la différence entre les client credentials et les ID de sandbox. Le Client ID et le Client Secret représentent les identifiants de votre client de jeu, lui permettant de communiquer avec le backend EOS. Le Sandbox ID représente l'environnement spécifique (comme Development, Staging ou Live) auquel votre client accède.
Si votre client de jeu tente de s'authentifier avec un Sandbox ID qui ne correspond pas à la politique de Client Credentials, la demande d'authentification sera rejetée. De plus, le flag bUseEpicConnect doit être défini sur true pour s'assurer que l'Online Subsystem gère automatiquement le mapping de l'EAID vers le PUID en arrière-plan.
Managing Overlay Focus Mismatches and Platform Integration
Le plugin EOS de Unreal s'appuie fortement sur l'Epic Games Overlay pour afficher des notifications, gérer les invitations d'amis et effectuer des authentifications web OAuth. Lorsque votre client de jeu déclenche un login à l'aide du type de credential AccountPortal, le système d'exploitation lance une fenêtre de navigateur ou ouvre l'overlay.
Cette redirection déplace le focus hors de la fenêtre du jeu. Si vos modes d'input ne sont pas configurés pour gérer la perte de focus, le jeu peut se bloquer ou enregistrer des touches bloquées.
Gérer les problèmes d'input induits par l'overlay est un casse-tête classique pour les développeurs PC. Par exemple, l'injection d'overlay peut entrer en conflit avec les pilotes d'input bruts (raw input) et provoquer le blocage des états clavier/souris. Pour éviter que ces bugs ne gâchent l'expérience des joueurs, vous pouvez consulter notre analyse de The Marathon Input Issues Fix: Architecting PC Games to Survive Overlay Conflicts.
De plus, les échecs d'initialisation lors des tests sont souvent causés par des connexions de sockets mal configurées ou des seuils de timeout dans votre configuration locale. Si vous dépannez des timeouts de pilotes lors du démarrage de session, consultez notre guide sur Uefn Session Launch Timeout Nightmares: Diagnosing Unreal Engine Network Drivers.
Simplifying Cross-Platform Storefront Backends
Configurer manuellement les subsystems de storefronts, écrire des chaînes de delegates C++ et gérer les problèmes de focus d'overlay spécifiques aux plateformes prend énormément de temps. Faire cela pour plusieurs storefronts comme Steam, EGS et les consoles multiplie votre surcharge de développement.
Créer cela vous-même nécessite de mettre en place des load balancers, du sharding de base de données et la gestion des certificats SSL — facilement 4 à 6 semaines de travail.
Avec horizOn, vous disposez d'un backend cross-platform unifié qui abstrait ces API de storefronts. Au lieu de gérer des tokens de double identité (EAID/PUID), des sandboxes Epic ou du code d'initialisation Steamworks, vous utilisez une API unique qui gère les profils utilisateur, les achievements, le matchmaking et les leaderboards.
horizOn agit comme un pont, synchronisant automatiquement les achievements et la progression des joueurs avec le storefront depuis lequel l'utilisateur a lancé le jeu, vous permettant de vous concentrer sur le game loop plutôt que sur le boilerplate de storefront. Cela signifie que vos joueurs peuvent débloquer des achievements, accéder à des cloud saves et rechercher des parties, peu importe la plateforme ou le launcher qu'ils utilisent, sans que vous n'ayez à écrire une seule ligne de code SDK spécifique au storefront.
Modern Best Practices for Epic Online Services Integrations
Never Chain Asynchronous Nodes Directly : Attendez toujours que les delegates
OnLoginCompleteetOnQueryAchievementsCompletese déclenchent avant de lancer des opérations en aval (downstream) comme l'écriture de stats ou d'achievements.Enable Verbose Logging During Development : Ajoutez les lignes suivantes à votre
DefaultEngine.inisous[Core.Log]pour tracer les avertissements EOS masqués :[Core.Log] LogOnline=VeryVerbose LogOnlineGame=VeryVerbose LogEOSSDK=VeryVerboseMap Achievements to EOS in the Dev Portal : Assurez-vous que les achievements créés sous l'Epic Games Store (EGS) sont explicitement mappés à votre backend Epic Online Services (EOS). S'ils ne sont pas liés, l'SDK EOS ne reconnaîtra pas l'ID d'achievement.
Use ExchangeCode in Shipping Builds : Pendant le développement local, le type de login
Developeravec un Dev Auth Tool est pratique, mais vous devez basculer le type de credentials surExchangeCodedans les shipping builds lancés depuis l'Epic Games Launcher. L'utilisation du type d'authentificationExchangeCodefourni par le launcher évite la redirection OAuth du navigateur web, réduisant la durée de la séquence de login de 8-12 secondes d'interaction utilisateur manuelle à un handshake automatique de moins de 500 ms.
Streamlining Storefront Integrations
Résoudre les erreurs de login et d'achievements d'Epic Online Services dans Unreal Engine revient à comprendre le pipeline asynchrone et à maintenir les profils de configuration parfaitement alignés. En gérant la transition entre les interfaces d'identité et de services de jeu, les développeurs peuvent éliminer les erreurs silencieuses et offrir une expérience joueur fluide.
Prêt à scaler votre backend multiplayer ? Essayez horizOn gratuitement ou consultez la documentation de l'API.
Source : Epic Games Store (Online Services AND Achievements)