-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
Version: 2.0 · Engine: Unreal Engine 5.6 · Author: Marc Fraedrich
UE Steam Framework exposes the full Steamworks SDK through Unreal Engine Game Instance Subsystems. Each domain of the Steam API is a separate subsystem you can query in Blueprint or C++ without needing a custom Game Instance class.
| Old approach (v1) | New approach (v2) |
|---|---|
Custom UUESFGameInstance required |
Any UGameInstance works |
USteamFrameworkMain (plain UObject, AddToRoot) |
UGameInstanceSubsystem — lifetime managed by UE |
| Lobby + friends mixed in one class | One subsystem per domain |
Manual NewObject + null-checks in Blueprints |
Auto-created, always valid |
UGameInstance
├── USteamCoreSubsystem — init/shutdown, RunCallbacks tick, user info, rich presence
├── USteamFriendsSubsystem — friends list, avatars, Steam overlay
├── USteamLobbySubsystem — lobby CRUD, search, metadata, chat, invites
├── USteamAchievementsSubsystem — stats + achievements + leaderboards
├── USteamInventorySubsystem — Steam Inventory / item economy
├── USteamRemoteStorageSubsystem — Steam Cloud saves
├── USteamUGCSubsystem — Workshop / User-Generated Content
└── USteamNetworkingSubsystem — P2P networking (ISteamNetworking)
All subsystems depend on USteamCoreSubsystem, which is guaranteed to initialize first. SteamAPI_RunCallbacks() is called once per frame by USteamCoreSubsystem's tick, so every other subsystem receives its callbacks automatically.
Open Edit → Project Settings → Plugins → Steam Framework and set:
| Setting | Description |
|---|---|
| App ID | Your Steam App ID (480 = Spacewar for development) |
| Enforce App Ownership Check | Exits with a dialog if the running App ID doesn't match |
| Product Name / Game Description | Shown in the server browser |
| Server Version | Reported to Steam backend |
The plugin requires Steam to be the default Online Subsystem:
[OnlineSubsystem]
DefaultPlatformService=Steam
[OnlineSubsystemSteam]
bEnabled=true
SteamDevAppId=480Place a file called steam_appid.txt in the same folder as your .exe (or the project root during Play-In-Editor) containing just your App ID, e.g.:
480
Steam requires this to be present when launching outside of Steam.
Unlike v1, you do not need to set a custom Game Instance class. All subsystems are auto-created by Unreal's subsystem framework.
Get Game Instance → Get Subsystem (class = Steam Core Subsystem)
Use the same pattern for any subsystem.
SteamCoreSubsystem → Is Steam Initialized
Always guard Steam calls behind this check in the Editor, where Steam may not be running.
The entry point. Drives the Steam callback pump.
| Function | Category | Description |
|---|---|---|
IsSteamInitialized |
Core | Returns true after SteamAPI_Init() succeeded |
GetAppID |
Core | Running App ID |
GetBuildID |
Core | Steam build counter |
GetCurrentGameLanguage |
Core | e.g. "english"
|
GetAvailableGameLanguages |
Core | Comma-separated list |
IsSubscribed |
Core | User owns the app |
IsVACBanned |
Core | User has a VAC ban |
GetLocalUserSteamID |
User | Local player's FSteamID |
GetLocalPersonaName |
User | Local player's display name |
GetAvatar(SteamID, bLarge) |
User | Returns UTexture2D* (184×184 or 64×64) |
SetRichPresence(Key, Value) |
RichPresence | Set a rich-presence key |
ClearRichPresence |
RichPresence | Remove all keys |
GetFriendRichPresence(SteamID, Key) |
RichPresence | Read a friend's key |
Delegates:
| Delegate | Parameters | When fired |
|---|---|---|
OnSteamShutdown |
— | Steam requests the game to exit |
OnGameOverlayActivated |
bool bActive |
Overlay opens / closes |
| Function | Description |
|---|---|
GetFriendsList(bOnlineOnly) |
TArray<FSteamFriend> — all or online-only friends |
GetFriendInfo(SteamID) |
Single FSteamFriend
|
GetPersonaName(SteamID) |
Display name for any user |
GetPersonaState(SteamID) |
ESteamPersonaState |
HasFriend(SteamID) |
Is this person a friend? |
GetFriendAvatar(SteamID, bLarge) |
UTexture2D* |
ActivateOverlay(Dialog) |
Open overlay ("friends", "achievements", …) |
ActivateOverlayToUser(Dialog, SteamID) |
Open overlay focused on a user |
ActivateOverlayToWebPage(URL) |
Open overlay browser |
ActivateOverlayToStore(AppID) |
Open store page |
InviteFriendToGame(SteamID, ConnectString) |
Send a game invite |
RequestPersonaData(SteamID) |
Trigger async refresh |
GetFriendRichPresenceValue(SteamID, Key) |
Read a rich-presence value |
Delegates:
| Delegate | Parameters |
|---|---|
OnPersonaStateChanged |
FSteamID |
OnAvatarLoaded |
FSteamID |
OnGameInviteReceived |
FSteamID InviterSteamID |
CreateLobby(Params) → OnLobbyCreated(FLobbyCreateResult)
JoinLobby(LobbyID) → OnLobbyEntered(FSteamID LobbyID)
LeaveLobby() → OnLobbyLeft()
IsInLobby() → bool
GetCurrentLobbyID() → FSteamID
IsOwner() → bool
GetOwner() → FSteamID
GetMemberCount() → int32
GetMembers() → TArray<FSteamFriend>
GetLobbyData(Key) → FString
SetLobbyData(Key, Value) → bool (owner only)
GetMemberData(SteamID, Key) → FString
SetMemberData(Key, Value) — local user only
// Optional filters (call before RequestLobbyList):
AddStringFilter(Key, Value, Comparison)
AddNumericalFilter(Key, Value, Comparison)
AddSlotsAvailableFilter(MinOpenSlots)
SetDistanceFilter(Filter)
SetResultCountLimit(Max)
RequestLobbyList() → OnSearchComplete(TArray<FLobbySearchResult>)
SetLobbyVisibility(ELobbyVisibility)
SetJoinable(bool)
SetMemberLimit(int32)
SendChatMessage(Message) → bool
InviteFriend(FriendSteamID) → bool
All Delegates:
OnLobbyCreated, OnLobbyEntered, OnLobbyLeft, OnLobbyDataUpdated,
OnMemberJoined, OnMemberLeft, OnChatMessageReceived, OnInviteReceived, OnSearchComplete
Stats are automatically requested on subsystem startup. Wait for OnStatsReceived before reading or writing stats.
| Function | Description |
|---|---|
RequestCurrentStats |
Async fetch from Steam |
StoreStats |
Upload accumulated changes |
ResetAllStats(bAchievementsToo) |
⚠ Permanent — wipes player progress |
SetAchievement(APIName) |
Unlock an achievement |
GetAchievement(APIName) |
Is it unlocked? |
ClearAchievement(APIName) |
Re-lock an achievement |
GetAchievementByIndex(Index) |
FSteamAchievement (name, description, unlock time) |
GetNumAchievements |
Total achievements for this app |
IndicateAchievementProgress(Name, Current, Max) |
Show progress toast without unlocking |
GetAchievementGlobalUnlockPercent(Name) |
0.0–100.0 |
GetStatInt(Name) / SetStatInt(Name, Value)
|
Integer stat |
GetStatFloat(Name) / SetStatFloat(Name, Value)
|
Float stat |
Delegates: OnStatsReceived(bool), OnStatsStored(bool), OnAchievementUnlocked(FString APIName)
| Function | Description |
|---|---|
GetAllItems |
Async fetch of all owned items → OnItemsUpdated
|
GetCachedItems |
Returns last-fetched TArray<FSteamInventoryItem>
|
ConsumeItem(InstanceID, Quantity) |
Decrement item stack |
AddPromoItem(DefinitionID) |
Grant a promotional item |
TriggerItemDrop(DropListID) |
Request a random playtime drop |
GetItemDefinitionIDs |
All defined item IDs |
GetItemDefinitionProperty(DefID, PropertyName) |
e.g. "name", "description", "icon_url"
|
Delegates: OnItemsUpdated(TArray<FSteamInventoryItem>), OnDefinitionsUpdated()
| Function | Description |
|---|---|
IsCloudEnabledForApp / IsCloudEnabledForAccount
|
Cloud availability |
GetQuota(OutTotal, OutAvailable) |
Quota in bytes |
WriteFile(FileName, Data) |
Write raw bytes |
ReadFile(FileName, OutData) |
Read raw bytes |
DeleteFile(FileName) |
Delete |
FileExists(FileName) |
Exists? |
GetFileSize(FileName) |
Bytes, or -1 |
GetFileList |
TArray<FSteamCloudFile> |
WriteString(FileName, Content) |
UTF-8 string helper |
ReadString(FileName, OutContent) |
UTF-8 string helper |
| Function | Description |
|---|---|
QueryAllItems(MatchingType, MaxResults) |
Browse Workshop → OnQueryComplete
|
QuerySubscribedItems(MatchingType) |
Items the local user is subscribed to |
QueryItemByID(PublishedFileID) |
Fetch a single item's details |
SubscribeItem(PublishedFileID) |
Subscribe + auto-download |
UnsubscribeItem(PublishedFileID) |
Unsubscribe + remove |
IsItemInstalled(PublishedFileID, OutPath) |
Check install state |
Delegates: OnQueryComplete(bool, TArray<FSteamUGCItem>), OnDownloadComplete(int64, bool)
ISteamNetworking legacy P2P (channel-based, Steam relayed).
| Function | Description |
|---|---|
SendPacket(RemoteID, Channel, Data, SendType) |
Send raw bytes |
SendString(RemoteID, Channel, Message, SendType) |
UTF-8 string helper |
AcceptP2PSession(RemoteID) |
Accept a pending session |
CloseP2PSession(RemoteID) |
Close and flush |
CloseP2PChannel(RemoteID, Channel) |
Close one channel only |
GetP2PSessionState(...) |
Connection diagnostics |
Set ActiveChannels (default {0}) to control which channels are polled each tick.
Delegates: OnSessionRequest(FSteamID, Channel), OnSessionFailed(FSteamID, Channel, ErrorCode), OnPacketReceived(FSteamID, Channel, TArray<uint8>)
| Type | Description |
|---|---|
FSteamID |
64-bit Steam ID wrapper. .Value is int64; use .AsUInt64() for the raw value. |
FSteamFriend |
SteamID + PersonaName + PersonaState + bIsInGame |
FLobbyCreateParams |
LobbyName, MaxPlayers, Password (hashed), Visibility |
FLobbyCreateResult |
LobbyID + ELobbyCreateResult |
FLobbySearchResult |
LobbyID, LobbyName, MemberCount, MaxMembers, bHasPassword |
FSteamAchievement |
APIName, DisplayName, Description, bUnlocked, UnlockTime |
FSteamInventoryItem |
InstanceID, DefinitionID, Quantity |
FSteamItemDef |
DefinitionID, Name, Description, IconURL |
FSteamCloudFile |
FileName, FileSizeBytes, Timestamp |
FSteamUGCItem |
PublishedFileID, Title, Description, OwnerSteamID, Score, VotesUp, VotesDown, bIsSubscribed, bIsInstalled, InstallPath |
ESteamPersonaState |
Offline / Online / Busy / Away / Snooze / LookingToTrade / LookingToPlay |
ELobbyVisibility |
Private / FriendsOnly / Public / Invisible |
ELobbyCreateResult |
Success / Failed / Timeout / NoConnection |
ELobbyComparison |
Comparison operators for lobby search filters |
ELobbyDistanceFilter |
Close / Default / Far / Worldwide |
EUGCMatchingType |
Items, Collections, Artwork, Videos, Screenshots, … |
ESteamP2PSendType |
Unreliable / UnreliableNoDelay / Reliable / ReliableWithBuffering |
#include "SteamLobbySubsystem.h"
if (UGameInstance* GI = GetGameInstance())
{
USteamLobbySubsystem* Lobby = GI->GetSubsystem<USteamLobbySubsystem>();
if (Lobby)
{
FLobbyCreateParams Params;
Params.LobbyName = TEXT("My Game");
Params.MaxPlayers = 4;
Params.Visibility = ELobbyVisibility::Public;
Lobby->OnLobbyCreated.AddDynamic(this, &AMyGameMode::OnLobbyCreated);
Lobby->CreateLobby(Params);
}
}#include "SteamAchievementsSubsystem.h"
USteamAchievementsSubsystem* Ach = GetGameInstance()->GetSubsystem<USteamAchievementsSubsystem>();
if (Ach)
{
Ach->SetAchievement(TEXT("ACH_WIN_ONE_GAME"));
Ach->StoreStats();
}#include "SteamNetworkingSubsystem.h"
USteamNetworkingSubsystem* Net = GetGameInstance()->GetSubsystem<USteamNetworkingSubsystem>();
if (Net)
{
TArray<uint8> Payload = { 0x01, 0x02, 0x03 };
Net->SendPacket(RemoteSteamID, /*Channel=*/0, Payload, ESteamP2PSendType::Reliable);
}| v1 | v2 |
|---|---|
UUESFGameInstance |
Delete — no longer needed |
USteamFrameworkMain |
USteamLobbySubsystem |
USteamFrameworkHelper::GetSteamInterface() |
GetGameInstance()->GetSubsystem<USteamLobbySubsystem>() |
USteamFrameworkHelper::GetFriendsList() |
USteamFriendsSubsystem::GetFriendsList() |
USteamFrameworkHelper::GetSteamAvatar() |
USteamFriendsSubsystem::GetFriendAvatar() |
USteamFrameworkHelper::GetUsername() |
USteamFriendsSubsystem::GetPersonaName() |
USteamFrameworkHelper::GetUserSteamID() |
USteamCoreSubsystem::GetLocalUserSteamID() |
FSteamID::SteamID (uint64 field) |
FSteamID::Value (int64) — use .AsUInt64()
|
steamsdk_lambda_callresults.h |
Internal TLambdaCallResult<P> in SteamLobbySubsystem.cpp
|
FrameworkDef.h |
SteamTypes.h |
UESteamFramework.Build.cs uses AddEngineThirdPartyPrivateStaticDependencies(Target, "Steamworks") — the engine provides the correct Steamworks SDK version for the engine release automatically; no SDK version numbers need to be hard-coded.
The module type is Runtime (was Developer in v1), so the plugin loads in packaged builds.
Copyright © Marc Fraedrich.
See the root LICENSE file for terms.
Copyright 2026 Marc Fraedrich
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.