Come risolvere i fallimenti del login Blueprint e gli errori degli achievement in Epic Online Services con Unreal
In breve
Questa guida spiega come risolvere i fallimenti di login e gli errori di sincronizzazione degli achievement integrando Epic Online Services (EOS) in Unreal Engine. Analizza la differenza fondamentale tra Epic Account ID (EAID) e Product User ID (PUID) e spiega come correggere i problemi di race condition legati all'esecuzione asincrona dei Blueprint. Infine, fornisce un'implementazione pratica in C++ e le configurazioni corrette per il file DefaultEngine.ini per garantire un'integrazione fluida.
Compili una shipping build del tuo gioco in Unreal Engine, lo avvii dall'Epic Games Launcher e fai clic sul tuo pulsante di login personalizzato. Non succede nulla, oppure il client di gioco si blocca e i log si riempiono di criptici avvisi di fallimento dell'autenticazione. Peggio ancora, il tuo nodo di sblocco degli achievement viene eseguito senza mostrare alcun errore visibile, eppure il profilo del giocatore nell'overlay dell'Epic Games Store rimane completamente vuoto. Questi errori sono incredibilmente comuni quando si integrano le API degli storefront. Fortunatamente, possono essere risolti correggendo il flusso di esecuzione asincrona e comprendendo come il subsystem mappa le identità degli utenti.
Comprendere la pipeline di autenticazione EOS: EAID vs. PUID
L'integrazione di Epic Online Services (EOS) tramite l'Online Subsystem (OSS) di Unreal Engine richiede di destreggiarsi in un sistema di identità a due livelli. L'Epic Account ID (EAID) è gestito dall'Auth Interface. Questo valida l'identità dell'utente a livello di storefront, abilitando funzionalità come l'overlay social, le liste amici e i controlli sulla libreria dell'Epic Games Store.
Al contrario, il Product User ID (PUID) è gestito dal Connect Interface. Il PUID è un identificatore specifico del gioco che collega l'utente ai servizi di backend del gioco. Questi servizi includono matchmaking, statistiche, salvataggi in cloud e achievement.
Perché i mismatch tra EAID e PUID bloccano gli achievement
Un caso tipico di fallimento si verifica quando gli sviluppatori si autenticano con successo tramite l'Auth Interface (generando un EAID), ma il subsystem non riesce a effettuare il login nel Connect Interface. Poiché gli achievement sono gestiti dal Connect Interface tramite i PUID, salvare i progressi degli achievement senza un PUID risolto fallisce restituendo l'errore EOS_InvalidUser.
Nei giochi che si avviano senza un wrapper dello storefront, gli utenti solitamente effettuano il login con credenziali che vengono verificate rispetto a una tabella utenti centralizzata. In un moderno ecosistema di storefront come l'Epic Games Store, l'identità è federata. All'avvio, il gioco riceve un ticket crittografico dal launcher. Il gioco passa quindi questo ticket ai server di autenticazione dello storefront. L'SDK restituisce un Epic Account ID, che funge da passaporto dell'utente per tutti i giochi sulla piattaforma.
Tuttavia, per garantire la privacy e la sicurezza del cross-play, Epic non consente a funzionalità specifiche del gioco, come gli achievement, di leggere direttamente l'Epic Account ID. Il gioco deve invece inizializzare il Connect Interface, che esegue uno scambio secondario per ottenere un Product User ID. Questa separazione assicura che, in caso di violazione del gioco, le credenziali globali dell'account Epic dei giocatori non vengano compromesse. Senza il PUID, il gioco funziona di fatto in uno stato di ospite non autenticato, bloccando l'accesso alle funzionalità EGS. Se la configurazione delle tue credenziali o la policy del client non hanno i permessi corretti nel Portale Sviluppatori Epic, questo collegamento fallisce. L'interfaccia di identità segnala un login riuscito perché l'account Epic è valido, ma il livello dei servizi di gioco non può salvare i dati degli achievement perché nessun PUID è mai stato collegato.
L'anatomia di una sequenza di login Blueprint errata
Molti sviluppatori riscontano problemi di login collegando i pin di esecuzione dei propri Blueprint in modo lineare. Trascinare il pin di esecuzione da un nodo Login direttamente a un nodo Query Achievements o Write Achievement Progress fallirà sistematicamente.
Le richieste di autenticazione devono raggiungere il backend di Epic, il che le rende asincrone. L'engine continua a eseguire il grafo Blueprint già dal frame successivo, molto prima che i server Epic restituiscano le credenziali dell'utente. In questa fase, lo Unique Net ID del giocatore rimane nullo.
Il problema del "nodo mancante": race condition nell'esecuzione asincrona
Se chiami i nodi degli achievement subito dopo il nodo di login, il subsystem restituisce un errore silenzioso perché lo stato utente memorizzato nella cache è vuoto. Il workflow corretto richiede il binding di eventi personalizzati ai delegate asincroni del subsystem.
Inoltre, gli sviluppatori spesso trascurano il passaggio fondamentale di salvare gli achievement in cache prima di scrivervi dati. Non è possibile modificare i progressi di un achievement senza prima interrogare il server per ottenerne lo schema attuale. Chiamare Write Achievements senza una precedente chiamata a Query Achievements causa un fallimento silenzioso o un errore EOS_InvalidUser nel log della console, perché la dimensione della mappa degli achievement locale in cache è pari a 0.
Il corretto flusso asincrono in Blueprint
Per risolvere questo problema, devi separare il trigger del login dall'aggiornamento degli achievement. Per prima cosa, chiama il nodo di login specificando le credenziali di autenticazione corrette.
In secondo luogo, effettua il binding di un evento al delegate On Login Complete dell'interfaccia di identità. Una volta che questo evento viene attivato e restituisce uno stato di successo, recupera lo Unique Net ID dell'utente.
Terzo, passa questo ID al nodo Query Achievements. Infine, effettua il binding di un evento al delegate On Query Achievements Complete e chiama Write Achievement Progress solo all'interno di quella callback.
Implementare un controller di login e achievement EOS robusto in C++
Per gestire in modo pulito queste operazioni asincrone, è altamente consigliato implementare il loop di autenticazione in C++. Ciò garantisce l'accesso diretto a IOnlineSubsystem e alle sue interfacce.
Di seguito è riportata un'implementazione C++ completa e pronta per la produzione di un gestore di login e achievement:
#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."));
}
}
Questo controller utilizza callback sequenziali. Garantisce che l'interfaccia degli achievement venga consultata solo dopo che l'interfaccia di identità ha risolto correttamente sia l'Epic Account ID sia il Product User ID.
Configurare il file DefaultEngine.ini per EOS
I nodi di login Blueprint non riusciranno a inizializzarsi se le configurazioni nel file Config/DefaultEngine.ini sono errate. Il plugin Online Subsystem EOS richiede parametri specifici per interfacciarsi con il client di gioco.
Usa il seguente template di configurazione per assicurarti che il subsystem si inizializzi correttamente:
[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 configurazione del file DefaultEngine.ini funge da ponte tra i binari del gioco compilato e il Portale Sviluppatori Epic. I parametri sotto [OnlineSubsystemEOS] devono corrispondere esattamente alle impostazioni del prodotto.
Una fonte comune di confusione è la differenza tra le credenziali del client e gli ID sandbox. Il Client ID e il Client Secret rappresentano le credenziali del client di gioco, consentendogli di comunicare con il backend di EOS. Il Sandbox ID rappresenta l'ambiente specifico (come Development, Staging o Live) a cui il client sta accedendo.
Se il client di gioco tenta di autenticarsi con un Sandbox ID che non corrisponde alla policy delle credenziali client, la richiesta di autenticazione verrà rifiutata. Inoltre, il flag bUseEpicConnect deve essere impostato su true per garantire che l'Online Subsystem gestisca automaticamente il mapping da EAID a PUID dietro le quinte.
Gestire la perdita di focus dell'overlay e l'integrazione con la piattaforma
Il plugin EOS di Unreal si affida fortemente all'Epic Games Overlay per visualizzare le notifiche, gestire gli inviti degli amici ed eseguire autenticazioni web OAuth. Quando il client di gioco avvia un login utilizzando il tipo di credenziale AccountPortal, il sistema operativo avvia una finestra del browser o apre l'overlay.
Questo reindirizzamento sposta il focus lontano dalla finestra di gioco. Se le modalità di input non sono configurate per gestire la perdita di focus, il gioco può bloccarsi o registrare tasti premuti all'infinito.
Risolvere i problemi di input indotti dall'overlay è un grattacapo comune per gli sviluppatori PC. Ad esempio, l'injection dell'overlay può entrare in conflitto con i driver di raw input e causare il congelamento degli stati di tastiera e mouse. Per evitare che questi bug rovinino l'esperienza dei giocatori, puoi consultare la nostra analisi su The Marathon Input Issues Fix: Architecting PC Games to Survive Overlay Conflicts.
Inoltre, i fallimenti di inizializzazione durante i test sono spesso causati da connessioni socket configurate in modo errato o da soglie di timeout nella configurazione locale. Se stai effettuando il troubleshooting di timeout dei driver all'avvio della sessione, dai un'occhiata alla nostra guida su Uefn Session Launch Timeout Nightmares: Diagnosing Unreal Engine Network Drivers.
Semplificare il backend per storefront multipiattaforma
Configurare manualmente i subsystem per storefront, scrivere catene di delegate in C++ e gestire problemi di focus dell'overlay specifici della piattaforma richiede moltissimo tempo. Farlo per più storefront come Steam, EGS e console moltiplica l'overhead di sviluppo.
Sviluppare questa infrastruttura internamente richiede la configurazione di load balancer, sharding del database e gestione dei certificati SSL — facilmente 4-6 settimane di lavoro.
Con horizOn, ottieni un backend multipiattaforma unificato che astrae queste API di storefront. Invece di dover gestire token a doppia identità (EAID/PUID), sandbox di Epic o il codice di inizializzazione di Steamworks, utilizzi una singola API che gestisce profili utente, achievement, matchmaking e classifiche.
horizOn funge da ponte, sincronizzando automaticamente gli achievement e i progressi dei giocatori con qualsiasi storefront da cui l'utente abbia avviato il gioco. Questo ti permette di concentrarti sul game loop anziché sul boilerplate dello storefront. Ciò significa che i tuoi giocatori possono sbloccare achievement, accedere ai salvataggi in cloud e cercare partite indipendentemente dalla piattaforma o dal launcher che utilizzano, senza che tu debba scrivere una sola riga di codice SDK specifico dello storefront.
Best practice moderne per le integrazioni di Epic Online Services
Non collegare mai i nodi asincroni direttamente: Attendi sempre l'attivazione dei delegate
OnLoginCompleteeOnQueryAchievementsCompleteprima di eseguire operazioni a valle, come la scrittura di statistiche o achievement.Abilita i log dettagliati durante lo sviluppo: Aggiungi le seguenti righe al tuo
DefaultEngine.inisotto[Core.Log]per tracciare gli avvisi EOS nascosti:[Core.Log] LogOnline=VeryVerbose LogOnlineGame=VeryVerbose LogEOSSDK=VeryVerboseMappa gli achievement su EOS nel Portale Sviluppatori: Assicurati che gli achievement creati nell'Epic Games Store (EGS) siano mappati esplicitamente sul tuo backend Epic Online Services (EOS). Se non sono collegati, l'SDK di EOS non riconoscerà l'ID dell'achievement.
Usa ExchangeCode nelle shipping build: Durante lo sviluppo locale, il tipo di login
Developercon un Dev Auth Tool è comodo, ma devi passare al tipo di credenzialiExchangeCodenelle shipping build lanciate dall'Epic Games Launcher. L'uso del tipo di autenticazioneExchangeCodefornito dal launcher evita il reindirizzamento OAuth nel browser web, riducendo la durata della sequenza di login da 8-12 secondi di interazione manuale dell'utente a un handshake automatizzato inferiore ai 500 ms.
Semplificare le integrazioni dello storefront
Risolvere gli errori di login e di sblocco degli achievement in Epic Online Services con Unreal Engine si riduce a comprendere la pipeline asincrona e a mantenere i profili di configurazione perfettamente allineati. Gestendo la transizione tra le interfacce di identità e quelle dei servizi di gioco, gli sviluppatori possono eliminare gli errori silenziosi e offrire un'esperienza giocatore fluida.
Pronto a scalare il tuo backend multiplayer? Prova horizOn gratuitamente o consulta la documentazione delle API.