- Движок: Unreal Engine 5.5.4 (выпуск)
- Онлайн-подсистема: Steam (AppID 480 — Spacewar)
- Методы тестирования:
1. Несколько автономных экземпляров из одного редактора (хост в Steam, клиент часто возвращается к NULL из-за состояния гонки).
2. Два отдельных компьютера и учетные записи Steam (оба успешно инициализировали Steam, но результатов по-прежнему 0). - Плагин: Расширенные сеансы Steam в Engine/Plugins/.
При тестировании с другом в совершенно другой сети также 0 результатов, хотя оверлей Steam активен с обеих сторон и журналы подтверждают, что Steam инициализирован.
Технические наблюдения:
- Журналы (локальный тест): при запуске 2 экземпляра, в одном журнале показано OSS: невозможно создать экземпляр OnlineSubsystem Steam, возвращается значение NULL.
- Журналы (проверка друга): в обоих журналах показано STEAM: [AppId: 480] Клиентский API инициализирован 1. Однако поиск по-прежнему возвращает 0 лобби.
- AppID 480 Шум: я знаю, что AppID 480 переполнен, поэтому я реализовал уникальный фильтр SEARCH_TAG для изоляции моих сеансов.
- Журналы каждый раз показывают это сообщение, однако ServerBuildUniqueId и BuildId должны быть то же самое:
Код: Выделить всё
\[2026.01.26-14.31.43:944\]\[ 32\]LogOnlineSession: Warning: STEAM: Server response IP:123.243.252.232
\[2026.01.26-14.31.43:944\]\[ 32\]LogOnlineSession: Warning: STEAM: Removed incompatible build: ServerBuildUniqueId = 0x00000000, GetBuildUniqueId() = 0x023ecee6
- Перезапустил Steam: оба игрока полностью перезапустили Steam.
- Последовательный запуск: гарантировал, что сеанс хоста полностью создан до того, как клиент начнет поиск.
- Регион загрузки: проверено, что для обоих клиентов Steam установлен один и тот же регион загрузки. (Великобритания/Бельгия).
- Синхронизация идентификатора сборки: проверены журналы с обеих сторон: buildID и ServerUniqueBuildId одинаковы.
Код: Выделить всё
void UPSGameInstance::CreateSession(int32 NumPublicConnections, bool bIsLAN, const FString& SessionName)
{
LastCreatedSessionName = SessionName;
if (!SessionInterface.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("CreateSession: Invalid session interface."));
if (OnSessionCreated.IsBound())
OnSessionCreated.Broadcast(false, SessionName);
return;
}
FNamedOnlineSession* ExistingSession = SessionInterface->GetNamedSession(NAME_GameSession);
if (ExistingSession)
{
SessionInterface->DestroySession(NAME_GameSession);
UE_LOG(LogTemp, Error, TEXT("CreateSession: Destroy Existing Session."));
}
FOnlineSessionSettings SessionSettings;
SessionSettings.bIsLANMatch = bIsLAN;
SessionSettings.NumPublicConnections = NumPublicConnections;
SessionSettings.bShouldAdvertise = true;
SessionSettings.bUsesPresence = true;
SessionSettings.bAllowJoinInProgress = true;
SessionSettings.bUseLobbiesIfAvailable = true;
SessionSettings.bAllowJoinViaPresence = true;
SessionSettings.Set(FName("SESSION_NAME"), SessionName, EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);
SessionSettings.Set(FName("SEARCH_TAG"), FString("POOL_STORY_2026"), EOnlineDataAdvertisementType::ViaOnlineService);
bIsUsingLAN = bIsLAN;
uint32 BuildID = GetBuildUniqueId();
SessionSettings.BuildUniqueId = BuildID;
UE_LOG(LogTemp, Warning, TEXT("[SESSION_DEBUG] CreateSession: Setting ServerUniqueBuildID = 0x%X (%u)"), BuildID, BuildID);
SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(
FOnCreateSessionCompleteDelegate::CreateUObject(this, &UPSGameInstance::OnCreateSessionComplete));
if (!SessionInterface.IsValid())
return;
SessionInterface->CreateSession(0, NAME_GameSession, SessionSettings);
}
Код: Выделить всё
void UPSGameInstance::FindSessions(bool bIsLAN, int32 MaxResults, const FString& SearchKeyword)
{
if (!SessionInterface.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("FindSessions: Invalid session interface."));
OnSessionsFound.Broadcast({});
return;
}
SessionSearch = MakeShareable(new FOnlineSessionSearch());
SessionSearch->bIsLanQuery = bIsLAN;
SessionSearch->MaxSearchResults = MaxResults;
SessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
SessionSearch->QuerySettings.Set(FName("SEARCH_TAG"), FString("POOL_STORY_2026"), EOnlineComparisonOp::Equals);
if (!SearchKeyword.IsEmpty())
{
SessionSearch->QuerySettings.Set(FName("SESSION_NAME"), SearchKeyword, EOnlineComparisonOp::Equals);
}
SessionInterface->AddOnFindSessionsCompleteDelegate_Handle(
FOnFindSessionsCompleteDelegate::CreateUObject(this, &UPSGameInstance::OnFindSessionsComplete));
if (!SessionInterface.IsValid())
return;
SessionInterface->FindSessions(0, SessionSearch.ToSharedRef());
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... -different