Knowledge Base
HomeProductsCommunityReviewsSocial
Old Knowledge Base
Old Knowledge Base
  • Knowledge Base
    • Getting to know us
  • Where to Buy
    • Become a Sponsor
    • Heathen License Agreement
  • General
    • ๐Ÿ”ŽTable of Contents
    • ๐ŸคฉGetting Started
      • Indie Check List
      • Sourcing Resources
        • ๐Ÿง™โ€โ™‚๏ธCommunity
        • ๐Ÿงžโ€โ™‚๏ธManaged Services
        • ๐Ÿ“ฃMarketing
        • ๐ŸงชTesting
    • ๐ŸงžTips and Tricks
      • Fundamentals
        • Development Phases
      • Unity
        • Package Manager Installs
          • Missing asset after update
        • Unity Release Version
      • Unreal
        • Unity to Unreal
        • Quick Start
    • ๐Ÿ“Design
      • โ˜๏ธQuick Start
      • ๐ŸฅพBootstraping
      • ๐Ÿค‘Monetization
        • What not to do
        • Models
          • Free
          • Free to Play
          • Pay to Play
          • Pay to Win
          • Play to Earn
        • Tools
          • ๐Ÿ˜กArtificial Scarcity
          • ๐Ÿค‘Bundles
          • ๐Ÿค”Community Marketplace
          • ๐Ÿค‘Expansions
          • ๐Ÿ˜กFear of Missing Out (FOMO)
          • ๐Ÿ˜กGatcha Mechanics
          • ๐Ÿค”Microtransactions (MTX)
          • ๐Ÿ˜กNFT
            • ๐Ÿ˜กBlockchain
          • ๐Ÿค”No Spend Cap
          • ๐Ÿ˜กPremium Currency
          • ๐Ÿค”Season
          • ๐Ÿค‘Subscription
          • ๐Ÿ˜กSurprise Mechanics
      • ๐ŸŽฎMultiplayer
        • Networking Tools
        • Terminology
      • ๐ŸคนMulti-Scene Architecture
      • ๐ŸŒProject Architecture
      • ๐Ÿ˜ŠPlayer Motivation
    • ๐Ÿ—๏ธDevelopment
      • โ˜๏ธQuick Start
      • โ˜Ž๏ธCallbacks & Delegates
      • โ”Conditional Compilation
      • ๐ŸชณDebugging
      • ๐ŸšงDevOps
        • โ˜•Team Collaboration
        • ๐Ÿ›‚Git Control & Unity
      • โ‰๏ธError Handling
        • System Dialog
        • Reporting
      • ๐ŸคฏIntelliSense
      • ๐ŸชถLambda Expressions
      • ๐Ÿคนโ€โ™€๏ธMulti Platform Projects
      • ๐Ÿ“‘Namespace and Using
      • ๐ŸŽฎUnity's "New" Input System
      • ๐Ÿ”ผUpdating Visual Studio and C#
      • ๐Ÿ’กVisual Scripting
    • โš ๏ธPublishers
    • ๐ŸงชTesting
      • ๐Ÿ‘‹Introduction
      • โœ๏ธWriting Formal Tests
    • ๐Ÿง™โ€โ™‚๏ธCommunity
      • โ˜๏ธQuick Start
    • ๐Ÿ“ฃMarketing
      • โ˜๏ธQuick Start
      • ๐Ÿ“ŒTips and Tactics
      • ๐Ÿค“Market Research
    • ๐Ÿ“†Release
    • ๐Ÿ—บ๏ธLive
  • Steam
    • โ˜๏ธQuick Start
    • ๐Ÿ†Achievements
    • ๐ŸŒณBranches
    • ๐Ÿ—ฃ๏ธCommunity Hub
    • โฌ†๏ธUploading to Steam
    • โ˜๏ธCloud Save
    • ๐Ÿ†”CSteamID
    • ๐Ÿ”ŽDiscovery Queue
    • ๐Ÿ•น๏ธDownloadable Content
    • ๐ŸšซEarly Access
    • ๐Ÿ–ฑ๏ธInput
    • ๐Ÿ“ฆInventory
      • ๐Ÿ”จCrafting System
      • ๐Ÿ› ๏ธItem Definition Tools
      • ๐Ÿ’ธMicrotransactions
      • ๐ŸŽPromo Items
    • ๐ŸšขLaunch
    • ๐Ÿฅ‡Leaderboards
      • ๐Ÿ—ฃ๏ธAdvanced Profiles
    • ๐ŸŽฎMultiplayer
      • โ˜๏ธGetting Started
      • ๐ŸงชDev and Test
      • ๐Ÿง‘โ€โš–๏ธAuthentication
      • ๐Ÿ›‹๏ธLobby
      • ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘Matchmaking
      • ๐Ÿง‘โ€๐Ÿ”งRich Presence
      • ๐Ÿ’ฌRoom Systems
      • ๐Ÿ’Steam Game Server
        • ๐Ÿ‘ทBuilds
        • โš™๏ธConfiguration
        • ๐Ÿ“‹Server Browser
        • ๐ŸงSetup Linux
      • ๐Ÿ—ฃ๏ธTerminology
    • ๐ŸคนMulti-Platform Project
    • ๐ŸงชPlaytest
    • ๐Ÿ›‹๏ธRemote Play
    • ๐Ÿ‘€Reviews
    • ๐ŸƒRunning a Build
    • ๐Ÿ’ถSales
    • โญStats
    • ๐Ÿ”‘Steam API Key
    • ๐Ÿ“ƒsteam_appid.txt
    • ๐Ÿ–ฅ๏ธSteam Deck
    • โš™๏ธSteamworks
    • ๐ŸคฏStore Page
    • ๐Ÿ› ๏ธWorkshop
      • Creating an Item
      • In-Game Browser
      • Subscribed Items
    • ๐Ÿง‘โ€๐ŸซUser Information
      • Unity User Tools
      • Unreal User Tools
    • ๐Ÿ—ฃ๏ธVoice
  • Toolkit for Steamworks
    • Introduction
    • Maintenance Cycle
    • F.A.Q
    • Unity
      • โš ๏ธKnown Issues
      • Unity Asset Refund Policy
      • Installation
        • Networking Integrations
      • Getting Started
      • Debugging
      • Learning
      • API Extensions
        • App.Client
        • App.Server
        • App.Web
        • Authentication
        • BigPicture.Client
        • Clans.Client
        • Friends.Client
        • Input.Client
        • Inventory.Client
        • Leaderboards.Client
        • Matchmaking.Client
        • Overlay.Client
        • Parties.Client
        • RemotePlay.Client
        • RemoteStorage.Client
        • Screenshots.Client
        • StatsAndAchievements.Client
        • StatsAndAchievements.Server
        • User.Client
        • UserGeneratedContent.Client
        • Utilities
        • Utilities.Client
        • Voice.Client
      • Objects
        • Classes
          • Achievement Data
          • Achievement Object
          • App Data
          • Authentication Session
          • Authentication Ticket
          • Avg Rate Stat
          • Chat Room
          • Clan Chat Msg
          • Clan Data
          • Currency
          • Data Model
          • DLC Data
          • Downloadable Content Object
          • Favorite Game
          • Float Stat
          • Game Data
          • Input Action
          • Input Action Data
          • Input Action Set
          • Input Action Set Data
          • Input Action Set Layer
          • Input Action Update
          • Input Controller Data
          • Int Stat
          • Inventory Result
          • Item Data
          • Item Definition
          • Item Detail
          • Leaderboard Data
          • Leaderboard Entry
          • Leaderboard Object
          • Lobby Chat Msg
          • Lobby Data
          • Lobby Game Server
          • Lobby Member Data
          • Party Beacon Details
          • Rank Change
          • Remote Storage File
          • Stat Data
          • Steam Game Server Configuration
          • UGC Query
          • User Data
          • Steam Settings
            • Colors
            • Game Client
              • Inventory Settings
            • Game Server
          • User Leave Data
          • Workshop Item
          • Workshop Item Data
          • Workshop Item Data Create Status
          • Workshop Item Key Value Tag
          • Workshop Item Preview File
        • Components
          • Friend Manager
          • Game Server Browser Manager
          • Input Action Event
          • Input Action Glyph
          • Input Action Name
          • Inventory Manager
          • Item Shopping Cart Manager
          • Leaderboard Manager
          • Leaderboard User Entry
          • Overlay Manager
          • Steam Game Server Events
          • Steam Input Manager
          • Steamworks Event Triggers
          • UGC Query Manager
          • Voice Recorder
          • Voice Stream
        • Enums
          • Friend Dialog
          • Inventory Item Type
          • Language Codes
          • Overlay Dialog
          • Sample Rate Method
          • Valve Price Categories
        • Prefabs
          • ๐Ÿ“ฆClan Chat
          • ๐Ÿ“ฆClan List
          • ๐Ÿ“ฆClan Member Count
          • ๐Ÿ“ฆFriend Avatar
          • ๐Ÿ“ฆFriend Groups
          • ๐Ÿ“ฆFriend List
          • ๐Ÿ“ฆFriend Name
          • ๐Ÿ“ฆFriend Profile
          • ๐Ÿ“ฆSelectable Friend ID
        • Programming Tools
          • IChatMessage
          • ILeaderboardEntryDisplay
          • IUserProfile
          • IWorkshopBrowserItemTemplate
          • LobbyMemberSlot
          • User Invite Button
        • UI Components
          • Chat Auto Join
          • Chat Stream
          • Clan Chat Director
          • Clan Chat Member Counter
          • Clan Chat Member List
          • Clan List
          • Clan Profile
          • Friend Group
          • Friend Groups Display
          • Friend Invite Dropdown
          • Friend List
          • Friend Profile
            • Image Field
            • Message Options
            • Text Field
          • Input Action Glyph
          • Input Action Name
          • Leaderboard Entry UI Record
          • Leaderboard UI List
          • Lobby Chat Director
          • Lobby Member Slot
          • Lobby Manager
          • Party Lobby Control
          • Quick Match Lobby Control
          • Rich Presence Reader
          • Rich Presence Setter
          • Set Achievement Description
          • Set Achievement Icon
          • Set Achievement Name
          • Set User Avatar
          • Set User Id Input Field
          • Set User Id Label
          • Set User Name
          • Toggle Event Helper
          • Workshop Browser Simple Item Record
      • Legacy
        • Troubleshooting
        • Getting Started
          • GameObject Initialization
          • ScriptableObject Initialization
          • API Initialization
        • Build Upload Tool
        • Debugging Tools
          • Testing
        • Components
          • Steamworks Behaviour
          • Steamworks Creator
          • Steam System Events
    • Unreal
      • What's New!
      • Installation
      • Getting Started
      • Updating Steamworks SDK
      • Packaging
      • Game Instance
      • Sockets Net Driver
      • Online Subsystem
      • Data Assets
        • Achievement
        • Downloadable Content
        • Inventory Item
        • Leaderboard
        • Stat
      • Widgets
        • BP_FriendsListDisplay
        • BP_FriendsListEntry
        • BP_FriendsListGroup
        • BP_SteamAvatarImage
        • BP_SteamUserName
      • Blueprint Nodes
        • Functions
          • ๐Ÿ”ตAdd Favorite Game
          • ๐Ÿ”ตAdd History Game
          • ๐Ÿ”ตAdd Promo Item
          • ๐Ÿ”ตAdd Request Lobby List Filter
          • ๐Ÿ”ตAdvertise Game
          • ๐Ÿ”ตAssociate with Clan
          • ๐Ÿ”ตAttach Leaderboard UGC
          • ๐Ÿ”ตBegin Auth Session
          • ๐Ÿ”ตCancel Auth Ticket
          • ๐Ÿ”ตCheck Result Steam ID
          • ๐Ÿ”ตClear All Key Values
          • ๐Ÿ”ตClear Achievement
          • ๐Ÿ”ตClear Rich Presence
          • ๐Ÿ”ตClient Initialize
          • ๐Ÿ”ตClient Run Callbacks
          • ๐Ÿ”ตClient Should Restart
          • ๐Ÿ”ตCompue New Player Compatibility
          • ๐Ÿ”ตConsume Item
          • ๐Ÿ”ตCreate Lobby
          • ๐Ÿ”ตDecompress Voice
          • ๐Ÿ”ตDelete Lobby Data
          • ๐Ÿ”ตDeserialize Result
          • ๐Ÿ”ตDestroy Result
          • ๐Ÿ”ตDownload Leaderboard Entries
          • ๐Ÿ”ตDownload Leaderboard Entries for Users
          • ๐Ÿ”ตEnd Auth Session
          • ๐Ÿ”ตExchange Items
          • ๐Ÿ”ตFind Leaderboard
          • ๐Ÿ”ตFind or Create Leaderboard
          • ๐Ÿ“‚Game Server Browser
            • ๐Ÿ”ตPing Server
            • ๐Ÿ”ตPlayer Details
            • ๐Ÿ”ตRequest Server List
            • ๐Ÿ”ตServer Rules
          • ๐Ÿ”ตGenerate Items
          • ๐Ÿ”ตGet Achievement
          • ๐Ÿ”ตGet Achievement by Index
          • ๐Ÿ”ตGet Achievement Icon
          • ๐Ÿ”ตGet Achievement Is Achieved
          • ๐Ÿ”ตGet All Items
          • ๐Ÿ”ตGet App Build ID
          • ๐Ÿ”ตGet App Id
          • ๐Ÿ”ตGet App Owner
          • ๐Ÿ”ตGet Auth Session Ticket
          • ๐Ÿ”ตGet Auth Ticket for Web API
          • ๐Ÿ”ตGet Available Game Languages
          • ๐Ÿ”ตGet Available Voice
          • ๐Ÿ”ตGet Coplay Friends
          • ๐Ÿ”ตGet Current Beta Name
          • ๐Ÿ”ตGet Current Game Language
          • ๐Ÿ”ตGet DLC Count
          • ๐Ÿ”ตGet DLC Data By Index
          • ๐Ÿ”ตGet DLC Download Progress
          • ๐Ÿ”ตGet Earliest Purchase
          • ๐Ÿ”ตGet Favorite Game
          • ๐Ÿ”ตGet Friends
          • ๐Ÿ”ตGet Friend Coplay Game
          • ๐Ÿ”ตGet Friend Coplay Time
          • ๐Ÿ”ตGet Friend Count from Source
          • ๐Ÿ”ตGet Friend Game Played
          • ๐Ÿ”ตGet Friend Groups
          • ๐Ÿ”ตGet Friend Group Members
          • ๐Ÿ”ตGet Friend Group Name
          • ๐Ÿ”ตGet Friend Persona Name
          • ๐Ÿ”ตGet Followed
          • ๐Ÿ”ตGet Installed Depots
          • ๐Ÿ”ตGet Item Definition Properties
          • ๐Ÿ”ตGet Item Price
          • ๐Ÿ”ตGet Items with Price
          • ๐Ÿ”ตGet Items by ID
          • ๐Ÿ”ตGet Launch Command Line
          • ๐Ÿ”ตGet Launch Query Param
          • ๐Ÿ”ตGet Leaderboard Display Type
          • ๐Ÿ”ตGet Leaderboard Entry Count
          • ๐Ÿ”ตGet Leaderboard Name
          • ๐Ÿ”ตGet Leaderboard Sort Method
          • ๐Ÿ”ตGet Lobby Chat Entry
          • ๐Ÿ”ตGet Lobby Data
          • ๐Ÿ”ตGet Lobby Data by Index
          • ๐Ÿ”ตGet Lobby Game Server
          • ๐Ÿ”ตGet Lobby Members
          • ๐Ÿ”ตGet Lobby Member by Index
          • ๐Ÿ”ตGet Lobby Member Data
          • ๐Ÿ”ตGet Lobby Member Limit
          • ๐Ÿ”ตGet Lobby Owner
          • ๐Ÿ”ตGet Most Achieved Achievement Info
          • ๐Ÿ”ตGet My Steam Avatar
          • ๐Ÿ”ตGet My Steam ID
          • ๐Ÿ”ตGet My Steam Level
          • ๐Ÿ”ตGet Num Items with Price
          • ๐Ÿ”ตGet Persona Name
          • ๐Ÿ”ตGet Persona State
          • ๐Ÿ”ตGet Player Nickname
          • ๐Ÿ”ตGet Public IP
          • ๐Ÿ”ตGet Result Item Property
          • ๐Ÿ”ตGet Result Items
          • ๐Ÿ”ตGet Result Status
          • ๐Ÿ”ตGet Result Timestamp
          • ๐Ÿ”ตGet Stat
          • ๐Ÿ”ตGet Steam ID
          • ๐Ÿ”ตGet User Achievement
          • ๐Ÿ”ตGet User Float Stat
          • ๐Ÿ”ตGet User Int Stat
          • ๐Ÿ”ตGet User Restrictions
          • ๐Ÿ”ตGet Rich Presence
          • ๐Ÿ”ตGet User Rich Presence
          • ๐Ÿ”ตGet User Rich Presence Key by Index
          • ๐Ÿ”ตGet User Steam Avatar
          • ๐Ÿ”ตGet Voice
          • ๐Ÿ”ตGet Voice Optimal Sample Rate
          • ๐Ÿ”ตGrant Promo Items
          • ๐Ÿ”ตHas Friend
          • ๐Ÿ”ตId is Me
          • ๐Ÿ”ตId is Valid
          • ๐Ÿ”ตIndicate Achievement Progress
          • ๐Ÿ”ตInstall DLC
          • ๐Ÿ”ตInvite User To Game
          • ๐Ÿ”ตInvite User to Lobby
          • ๐Ÿ”ตInitialize
          • ๐Ÿ”ตIs App Installed
          • ๐Ÿ”ตIs Behind NAT
          • ๐Ÿ”ตIs Cybercafe
          • ๐Ÿ”ตIs DLC Installed
          • ๐Ÿ”ตIs Lobby Owner
          • ๐Ÿ”ตIs Low Violence
          • ๐Ÿ”ตIs Phone Identifying
          • ๐Ÿ”ตIs Phone Requiring Verification
          • ๐Ÿ”ตIs Phone Verified
          • ๐Ÿ”ตIs Steam Initialized
          • ๐Ÿ”ตIs Subscribed
          • ๐Ÿ”ตIs Subscribed App
          • ๐Ÿ”ตIs Subscribed from Family Sharing
          • ๐Ÿ”ตIs Subscribed from Free Weekend
          • ๐Ÿ”ตIs Timed Trial
          • ๐Ÿ”ตIs Two Factor Enabled
          • ๐Ÿ”ตIs VAC Banned
          • ๐Ÿ”ตJoin Lobby
          • ๐Ÿ”ตLeave Lobby
          • ๐Ÿ”ตLoad Item Definitions
          • ๐Ÿ”ตLogged On
          • ๐Ÿ”ตLog Off
          • ๐Ÿ”ตLog On
          • ๐Ÿ”ตLog On Anonymous
          • ๐Ÿ”ตMark Content Corrupt
          • ๐Ÿ”ตQuick Match
          • ๐Ÿ”ตRemove Favorite Game
          • ๐Ÿ”ตRemove History Game
          • ๐Ÿ”ตRemove Property
          • ๐Ÿ”ตReply to Friend Message
          • ๐Ÿ”ตRequest Current Stats
          • ๐Ÿ”ตRequest Eligible Promo Item Definitions IDs
          • ๐Ÿ”ตRequest Friend Rich Presence
          • ๐Ÿ”ตRequest Lobby Data
          • ๐Ÿ”ตRequest Lobby List
          • ๐Ÿ”ตRequest Prices
          • ๐Ÿ”ตRequest Store Auth URL
          • ๐Ÿ”ตRequest User Group Status
          • ๐Ÿ”ตRequest User Information
          • ๐Ÿ”ตRequest User Stats
          • ๐Ÿ”ตReset All Stats
          • ๐Ÿ”ตRun Callbacks
          • ๐Ÿ”ตSecure
          • ๐Ÿ”ตSend Lobby Chat
          • ๐Ÿ”ตSerialize Result
          • ๐Ÿ”ตSet Achievement
          • ๐Ÿ”ตSet Advertise Server Active
          • ๐Ÿ”ตSet Bot Player Count
          • ๐Ÿ”ตSet Dedicated Server
          • ๐Ÿ”ตSet Description
          • ๐Ÿ”ตSet Game Data
          • ๐Ÿ”ตSet Game Tags
          • ๐Ÿ”ตSet In-Game Voice Speaking
          • ๐Ÿ”ตSet Key Value
          • ๐Ÿ”ตSet Map Name
          • ๐Ÿ”ตSet Listen for Friends Messages
          • ๐Ÿ”ตSet Lobby Data
          • ๐Ÿ”ตSet Lobby Game Server
          • ๐Ÿ”ตSet Lobby Joinable
          • ๐Ÿ”ตSet Lobby Member Data
          • ๐Ÿ”ตSet Lobby Member Limit
          • ๐Ÿ”ตSet Lobby Owner
          • ๐Ÿ”ตSet Lobby Type
          • ๐Ÿ”ตSet Max Player Count
          • ๐Ÿ”ตSet Mod Directory Name
          • ๐Ÿ”ตSet Name
          • ๐Ÿ”ตSet Password Protected
          • ๐Ÿ”ตSet Persona Name
          • ๐Ÿ”ตSet Played with User
          • ๐Ÿ”ตSet Product
          • ๐Ÿ”ตSet Property
          • ๐Ÿ”ตSet Region
          • ๐Ÿ”ตSet Rich Presence
          • ๐Ÿ”ตSet Stats
          • ๐Ÿ”ตSet Spectator Name
          • ๐Ÿ”ตSet Spectator Port
          • ๐Ÿ”ตSet User Achievement
          • ๐Ÿ”ตSet User Float Stat
          • ๐Ÿ”ตSet User Int Stat
          • ๐Ÿ”ตShutdown
          • ๐Ÿ”ตStart Purchase
          • ๐Ÿ”ตStart Update Property
          • ๐Ÿ”ตStart Voice Recording
          • ๐Ÿ”ตSteam ID Tools
          • ๐Ÿ”ตStop Voice Recording
          • ๐Ÿ”ตStore Stats
          • ๐Ÿ”ตStore User Stats
          • ๐Ÿ”ตSubmit Update Property
          • ๐Ÿ”ตTransfer Item Quantity
          • ๐Ÿ”ตTrigger Item Drop
          • ๐Ÿ”ตUninstall DLC
          • ๐Ÿ”ตUpdate Avg Rate Stat
          • ๐Ÿ”ตUpdate User Avg Rate Stat
          • ๐Ÿ”ตUpload Leaderboard Score
          • ๐Ÿ”ตUser Has License for App
          • ๐Ÿ”ตWas Restart Requested
        • Events
          • ๐Ÿ”ปDlc Installed
          • ๐Ÿ”ปFriend Chat Msg
          • ๐Ÿ”ปFriend Rich Presence Update
          • ๐Ÿ”ปGame Overlay Activated
          • ๐Ÿ”ปInventory Item Definition Update
          • ๐Ÿ”ปInventory Results Ready
          • ๐Ÿ”ปLobby Chat Msg
          • ๐Ÿ”ปLobby Chat Update
          • ๐Ÿ”ปLobby Data Update
          • ๐Ÿ”ปLobby Game Created
          • ๐Ÿ”ปLobby Join Requested
          • ๐Ÿ”ปMicro Txn Authorization Response
          • ๐Ÿ”ปPersona State Change
          • ๐Ÿ”ปRich Presence Join Requested
          • ๐Ÿ”ปServers Connected
          • ๐Ÿ”ปServer Connect Failure
          • ๐Ÿ”ปServer Disconnected
          • ๐Ÿ”ปTicket for Web API Response
        • Types
          • ๐ŸŸฉAchievement Status
          • ๐ŸŸฉAuth Ticket Data
          • ๐ŸŸฉChat Entry
          • ๐ŸŸฉDecompress Voice Result
          • ๐ŸŸฉFloat Stat
          • ๐ŸŸฉGame Server Item Wrapper
          • ๐ŸŸฉGame Server Player Details Wrapper
          • ๐ŸŸฉGlobal Achievement Status
          • ๐ŸŸฉItem Count
          • ๐ŸŸฉItem Detail
          • ๐ŸŸฉItem Detail With Properties
          • ๐ŸŸฉItem Price
          • ๐ŸŸฉItem With Price
          • ๐ŸŸฉInt Stat
          • ๐ŸŸฉKey Value Pair
          • ๐ŸŸฉLeaderboard Entry
          • ๐ŸŸฉLobby Data
          • ๐ŸŸฉLobby Game Server
          • ๐ŸŸฉServer Achievement Status
          • ๐ŸŸฉServer Stat Float Value
          • ๐ŸŸฉServer Stat Int Value
          • ๐ŸŸฉUser Achievement Status
          • ๐ŸŸฉVoice Result
          • ๐ŸŸฉVoice Available Result
        • Enumerators
          • ๐ŸŸจUEBeginAuthSessionResult
          • ๐ŸŸจUEChatRoomEnterResponse
          • ๐ŸŸจUEFriendFlags
          • ๐ŸŸจUEChatEntryType
          • ๐ŸŸจUEChatMemberStateChange
          • ๐ŸŸจUELeaderboardDataRequest
          • ๐ŸŸจUELeaderboardDisplayType
          • ๐ŸŸจUELeaderboardSortMethod
          • ๐ŸŸจUELobbyComparison
          • ๐ŸŸจUELobbyDistanceFilter
          • ๐ŸŸจUELobbyType
          • ๐ŸŸจUEResult
          • ๐ŸŸจUESteamCurrencyCode
          • ๐ŸŸจUEServerMode
          • ๐ŸŸจUEUserHasLicenseForAppResult
          • ๐ŸŸจUEVoiceResult
      • C++
  • Toolkit for Physics
    • Unity
      • Installation
      • Core Features
        • Ballistics Tools
        • Buoyancy Tools
        • Force Effect Framework
        • Physics Data extended
        • Verlet Integration
      • Sample Scenes
        • Fantasy Style Ballistic Simulation
        • (3D) Deterministic Bounce Prediction
        • (2D) Deterministic Bounce Prediction
        • 1 Buoyancy Example
        • 1 Force Effect Fields
        • 2 Spherical Gravity
        • 3 Multi-body Gravity
        • 1 Verlet Spring Simple Transforms
        • 2 Verlet Spring Skinned Mesh
      • API
        • Ballistics
        • Buoyancy
        • Force Effects
        • Maths
        • Mesh Tools
      • Components
        • Ballistic Aim
        • Ballistic Path Line Render
        • Ballistic Path Follow
        • Buoyant Body
        • Buoyant Body Drag
        • Constant Acceleration
        • Constant Angular Velocity
        • Constant Linear Velocity
        • Force Effect Source
          • Force Effect Direction
          • Force Effect Field
        • Force Effect Reciever
        • Physics Data
        • Surface Tool
        • Trick Shot
        • Trick Shot Line
        • Verlet Spring
      • Objects
        • Force Effect
          • Attract Effect
          • Gravity Effect
          • Repulse Effect
          • Suspend Effect
          • Tractor Effect
          • Wind Effect
        • Point Volume
        • Verlet Hierarchy
        • Verlet Hierarchy Settings
        • Verlet Particle
      • Enums
        • Calculation Mode
  • Toolkit for UI & UX
    • Introduction
    • Unity
      • Installation
      • Learning
        • Sample Scenes
          • Command Parser Example
          • Cursor System Scene
          • Drag and Drop (Behaviours)
          • Drag and Drop (Inventory Example)
          • Drag and Drop (Spell Bar Example)
          • Log Sample Scene
          • Screenshot Sample Scene
        • Core Concepts
          • Command System
          • Cursor System
          • Drag and Drop System
          • Interaction Tools
          • Logging & Feedback
          • Scene Tools
          • Selection System
          • Tooltip System
          • Window System
        • uGUI Extras
          • Key Collection
          • Ligature Tools
          • Tree View Collection
      • API
        • Cursors
        • Json
        • Log
        • Scenes
        • Screenshot
        • Selection
        • Trello
        • Windows
      • Components
        • Action Hold
        • Border Handle
        • Button Cursor State
        • Change Cursor Default State
        • Command Director
        • Cursor Animator
        • Drag Item
        • Drop Container
        • Key Hold
        • Mouse Over Cursor State
        • Move Handle
        • Play On Click
        • Play On Demand
        • Play On Down
        • Play On Enter
        • Play On Exit
        • Play On Up
        • Pointer Hold
        • Scenes Manager
        • Selectable Object
        • Selection Manager
        • Tooltip Trigger
        • Tooltip Window Controller
        • Window
        • Window Clamping Bounds
        • Window Focus Change Event Data
      • Objects
        • Command Data
        • Command Library
        • Cursor Animation
        • Cursor State
        • DragAndDropItemChangeData
        • LogData
      • Enums
        • Clear Drop Behaviour
        • Drag Effect
        • Drag End Behaviours
        • Grab Handle
        • Mask Mode
        • Recieve Mode
        • Window Snap To Location
  • More Heathen Tools
    • ๐ŸŽจArt Assets
      • Breakable
        • Wood Props
          • Installation
    • โš™๏ธSystem Core
      • Installation
      • Learning
        • Asset Developers
      • Command Line
      • Game Events
      • Scriptable Tags
      • Scriptable Variables
      • Heathen Behaviour
      • Heathen UI Behaviour
    • ๐Ÿ“‹Tips for Asset Developers
      • Editor Coroutines
      • Package Manger in C#
      • Session State Values
  • Codex
    • Introduction
      • Article Design Guide
        • Evolution
          • Early Period
          • Middle Period
          • Late Period
      • Codex Organization
    • Irish
      • Folklore
        • Introduction
        • Characters
          • Dรฉithe
            • Cacht
            • Lugh
            • Dag Dia
              • Donn
              • Nuada
              • Ogma
            • Mother?
              • Banba
                • Appearance
                • Name
              • ร‰rui
                • Appearance
                • Name
              • Fรณdla
                • Appearance
                • Name
            • Father ?
              • ร‰thur Mac Cuill
              • Cรฉthur Mac Grรฉine
              • Tรฉthur Mac Cecht
        • Concepts
          • Binding Tablet
          • Druids
          • Sociaty
          • Patron Gods
          • Bile
          • Time
        • Food
          • Elderberry Capers
          • Elderberry Wine
          • Mead
        • Peoples
          • Fomรณire
          • Research Note
            • Hunter Gathers
            • Neolithic Farmers
            • Bronze Age
        • Locations
          • Lughmhagh
          • Temair
            • Name
      • Research
        • Historical Backdrop
        • Disambiguation
          • Banshee
          • Celt
          • Gods and Goddesses
          • Lebor Gabรกla ร‰renn
          • Milesians
          • Mother Goddess
          • Sovereignty Goddess
          • The Morrรญgan
          • Triple Persona
          • Tuatha Dรฉ
          • Wicker Man Sacrafice
        • Links
          • Social Factors
          • Lugh
            • Name
          • Ogma
          • Astronomy
          • Time
        • Sources
        • WIP
          • Artefacts
          • Beings
            • Cannon
              • Belgae
              • Fomorians
              • Sรญog
              • Tuatha Dรฉ Danann
            • Derivative
              • Milesians
              • Muintir Nemid
          • Characters
            • Cannon
            • Derivative
          • Concepts
          • Events
          • Languages
          • Music
          • Places
          • Sources
          • Stories
          • Styles
Powered by GitBook
On this page
  • Introduction
  • Quick Start
  • Publish
  • Troubleshooting
  • Upload ignores my value
  • How to Fix?
  • Examples
  • Get Leaderboard
  • Upload Score
  • Get User's Entry
  • Get Entries
  • Attach File
  • Get Attached File
  1. Steam

๐Ÿฅ‡Leaderboards

Understanding Steam Leaderboards and the Heathen Engineering tool kit

PreviousLaunchNextAdvanced Profiles

Last updated 6 months ago

Like what you're seeing?

Support us as a GitHub Sponsor and get instant access to all our assets, exclusive tools and assets, escalated support and issue tracking and our gratitude. These articles are made possible by our GitHub Sponsors ... become a sponsor today!

Introduction

Steam leaderboards are persistent tables with automatically ordered entries. Leaderboards can be used to display global and friend boards in your game and on your community page. Each title can create up to 10,000 leaderboards, and each leaderboard can be retrieved immediately after a player's score has been uploaded.

There is no limit on the number of players a leaderboard supports. Each leaderboard entry contains a score (as an int) and optionally up to 64 ints of detail data stored as a simple array on the entry. The detailed data can be used to store game-specific information about the play session that resulted in the user's leaderboard entry. This data is not sorted or parsed by Steam and is replaced when a new leaderboard entry is created for the user. Attachments can be linked with the leaderboard via the UGC (User Generated Content) feature of Steam.

Leaderboards can be configured such that only a trusted web API call can set the value. This is strongly recommended if you have any concerns over the validity of leaderboard scores. When the leaderboard's write operation is configured as trusted only a server using the Steam Web API and a publisher token can upload scores to the board. If the board is not configured as a trusted write then anyone can upload any score to the board.

Use the Steam Web API to set trusted leaderboard scores

https://partner.steamgames.com/doc/webapi/ISteamLeaderboards#SetLeaderboardScore

Quick Start

First, you need to create your achievements on the Steam Developer portal. https://partner.steamgames.com/

Log into your Steam Developer Portal and access your app's admin page. Look for the Technical Tools section and select the Edit Steamworks Settings option.

From there select the Stats & Achievements > Leaderboards option and create your new boards.

Make note of the value you use in the API Name field. You will use it when working with achievements in code.

Publish

You **MUST** publish your changes in the Steam Developer Portal before they will be accessible via Steam API. In the Steam Developer Portal when you have pending changes you will see a red banner at the top of the screen ... click it and follow the instructions.

Troubleshooting

Upload ignores my value

A common issue when your start is that it may appear that the leaderboard is ignoring the score you upload, or that it only takes scores in the opposite direction you intended.

For example, if you upload 10, then upload 11 it may ignore the 11 but if you upload 9 it will take the 9.

Why?

Steam Leaderboards are configured to sort scores in a particular direction and when you upload a score you are typically doing so as "Keep Best".

board.UploadScore(42,
    ELeaderboardUploadScoreMethod.k_ELeaderboardUploadScoreMethodKeepBest,
    (result, error) =>
    {
        if(!error)
            Debug.Log("Recorded: " + result.m_nScore +
                      "New Rank: " + result.m_nGlobalRankNew);
    });

The "Keep Best" option tells Steam to only record the new value you present ** if ** that value is better than the previous value recorded. This is determined by the "sort order" you configured for the board in the Steam Portal.

How to Fix?

Assuming you have the board configured incorrectly simply update its configuration in the Steam portal and then publish the changes.

You MUST ALWAYS publish changes when making edits in the Steam Portal. It does not apply the moment you make the change in the portal it is a Perforce-based source control system that requires you to publish your changes.

If for some reason you find your board still acts like it's sorted the other way around, this is likely due to an issue seen a few times with Steam's backend services. Submit a support case letting Valve know that your board appears bugged and is not changing its sort direction as it should.

To work around the issue make a new board (with a new name) and set it up with the sort of direction you desire; do not delete the broken board โ€ฆ please โ€ฆ so Valve can review it.

Examples

Get Leaderboard

Assumes targetBoard is a LeaderboardObject or LeaderboardData

C#

//Leaderboard Object will be "got" for you by the initialization process
//For Leaderboard Data we need as its a struct and not a reference we need
//To get its ID before we can use it

//Before we can use a leaderboard we need to get its ID ... not its API Name ... its ID
//The static function takes in the api name and a delegate to be called when the process is completed
//This is an asynchronous method ... a delegate is simply a pointer to a function
//You could give it a named function you defined in your class but far more commonly you use an anonymous function as we have here
LeaderboardData.Get(apiName, (data, ioError) =>
{
    if (!ioError)
    {
        targetBoard = data;
        Debug.Log($"Found {apiName} with ID {targetBoard.id.m_SteamLeaderboard}");

        //At this point you now have the board and do things with it .... see the functions below that give examples of working with the board such as reading and writing data
    }
    else
    {
        Debug.LogError($"An IO error occurred while attempting to read {apiName}");
    }
});

Blueprint

C++

// You will need to create a variable to store the CallResult
// This must be maintained until the CallResult is returned and complete
CCallResult<YourClass, LeaderboardFindResult_t> m_LeaderboardFindResult_t;

// Next call FindLeaderboard storing the handle
SteamAPICall_t handle = SteamUserStats()->FindLeaderboard(StringCast<ANSICHAR>(*board).Get());
// Use the handle with the CallResult created earlier
// Provide a pointer a suitable function to be called when the result
// Completes Valve will invoke the function passing the requested data
m_LeaderboardFindResult_t.Set(handle, this, &YourClass::Callback);

// Example Function to be called by the CallResult delegate
// Note that Unreal runs the Callback loop on a background thread
// This means you will need to create a GameThreadTask to bring the 
// Result forwarded to the GameThread
void YourClass::Callback(LeaderboardFindResult_t* Response, bool bIOError)
{
	if (!bIOError)
	{
		int64 boardId = static_cast<int64>(Response->m_hSteamLeaderboard);
		bool found = Response->m_bLeaderboardFound > 0 ? true : false;

		// Execute the delegate on the game thread asynchronously
		FGraphEventRef GameThreadTask = FFunctionGraphTask::CreateAndDispatchWhenReady([this, boardId, found]()
		{
			if (Callback.IsBound())
			{
				UE_LOG(LogTemp, Log, TEXT("Board found and callback invoked"));
				Callback.Execute(boardId, found);
			}
			else
			{
				UE_LOG(LogTemp, Log, TEXT("Board found, no callback to invoke"));
			}
		}, TStatId(), nullptr, ENamedThreads::GameThread);
		GameThreadTask->Wait();
	}
	else
	{
		// Execute the delegate on the game thread asynchronously
		FGraphEventRef GameThreadTask = FFunctionGraphTask::CreateAndDispatchWhenReady([this]()
		{
			if (Callback.IsBound())
				Callback.Execute(0, false);
		}, TStatId(), nullptr, ENamedThreads::GameThread);
		GameThreadTask->Wait();
	}
}
// First create a CallResult of type LeaderboardFindResult_t
// This can be used with both Find and Find or Create
// This must be held in memory until the process is returned
// So you will want to create it as a private variable on some object
// That will not be destroyed.
CallResult<LeaderboardFindResult_t> m_LeaderboardFindResult_t = CallResult<LeaderboardFindResult_t>.Create();

// Call Find or FindOrCreate storing the handle
var handle = SteamUserStats.FindLeaderboard(apiName);
// or
var handle = SteamUserStats.FindOrCreateLeaderboard(apiName, sortMethod, displayType);

// Once you have the handle you can set the CallResult
m_LeaderboardFindResult_t.Set(handle, (results, error) =>
{
    // Handle the result if the error is false
    // You want to store the results.m_hSteamLeaderboard for later use
});

Upload Score

Assumes targetBoard is a LeaderboardObject or LeaderboardData

There are multiple overloads to Upload Scores to a leaderboard, see the class description for a full list.

C#

// Call Upload Score passing in any details and indicating an upload Method
// This is an asynchronous function so the last parameter is a delegate
// That will be run when the process completes
targetBoard.UploadScore(score, details, uploadMethod, (callbackResult, ioError) =>
{
    // Handle the result if ioError is false
});

Blueprint

C++

// You will need to create a variable to store the CallResult
// This must be maintained until the CallResult is returned and complete
CCallResult<YourClass, LeaderboardScoreUploaded_t> m_LeaderboardFindResult_t;

SteamAPICall_t handle = SteamUserStats()->UploadLeaderboardScore(board, method, score, data.GetData(), data.Num());
// Use the handle with the CallResult created earlier
// Provide a pointer a suitable function to be called when the result
// Completes Valve will invoke the function passing the requested data
m_LeaderboardScoreUploaded_t.Set(handle, this, &YourClass::Callback);

// Example Function to be called by the CallResult delegate
// Note that Unreal runs the Callback loop on a background thread
// This means you will need to create a GameThreadTask to bring the 
// Result forwarded to the GameThread
void YourClass::Callback(LeaderboardScoreUploaded_t* Response, bool bIOError)
{
	// Execute the delegate on the game thread asynchronously
	FGraphEventRef GameThreadTask = FFunctionGraphTask::CreateAndDispatchWhenReady([this, bIOError, Response]()
	{
		if (!bIOError)
		{
			if (Callback.IsBound())
				Callback.Execute(Response->m_bSuccess == 1, Response->m_bScoreChanged == 1, Response->m_nGlobalRankNew, Response->m_nGlobalRankPrevious);
		}
		else if (Callback.IsBound())
			Callback.Execute(false, false, 0, 0);
	}, TStatId(), nullptr, ENamedThreads::GameThread);
	GameThreadTask->Wait();
}
// First create a CallResult of type LeaderboardScoreUploaded_t
// This must be held in memory until the process is returned
// So you will want to create it as a private variable on some object
// That will not be destroyed.
CallResult<LeaderboardScoreUploaded_t> m_LeaderboardScoreUploaded_t = CallResult<LeaderboardScoreUploaded_t>.Create();

// Call upload leaderboard score
var handle = SteamUserStats.UploadLeaderboardScore(boardId, method, score, details, details == null ? 0 : details.Length);

// Once you have the handle you can set the CallResult
m_LeaderboardScoreUploaded_t.Set(handle, (result, error) =>
{
    // Handle the result if the error is false
});

Get User's Entry

Assumes targetBoard is a LeaderboardObject or LeaderboardData

C#

targetBoard.GetUserEntry(detailEntriesCount, (foundEntry, ioError) =>
{
    // Handle the found entry if ioError is false
});

Blueprint

We have Task

And classic callback style options

C++

// You will need to create a variable to store the CallResult
// This must be maintained until the CallResult is returned and complete
CCallResult<YourClass, LeaderboardScoresDownloaded_t> m_LeaderboardScoresDownloaded_t;

SteamAPICall_t handle = SteamUserStats()->DownloadLeaderboardEntriesForUsers(leaderboard, targetUsers, numUsers);
// Use the handle with the CallResult created earlier
// Provide a pointer a suitable function to be called when the result
// Completes Valve will invoke the function passing the requested data
m_LeaderboardScoresDownloaded_t.Set(handle, this, &YourClass::Callback);

// Example Function to be called by the CallResult delegate
// Note that Unreal runs the Callback loop on a background thread
// This means you will need to create a GameThreadTask to bring the 
// Result forwarded to the GameThread
void YourClass::Callback(LeaderboardScoresDownloaded_t* Response, bool bIOError)
{
    	// Execute the delegate on the game thread asynchronously
	FGraphEventRef GameThreadTask = FFunctionGraphTask::CreateAndDispatchWhenReady([this, bIOError, Response]()
	{
		// Handle the results
	}, TStatId(), nullptr, ENamedThreads::GameThread);
	GameThreadTask->Wait();			
}
// First create a CallResult of type LeaderboardScoresDownloaded_t
// This must be held in memory until the process is returned
// So you will want to create it as a private variable on some object
// That will not be destroyed.
CallResult<LeaderboardScoresDownloaded_t> m_LeaderboardScoresDownloaded_t = CallResult<LeaderboardScoresDownloaded_t>.Create()

// Call upload leaderboard score
var handle = SteamUserStats.DownloadLeaderboardEntriesForUsers(boardId, new CSteamID[]{ SteamUser.GetSteamID() }, 1);

// Once you have the handle you can set the CallResult
m_LeaderboardScoresDownloaded_t.Set(handle, (results, error) =>
{
    //Handle the results as you see fit
});

Get Entries

Assumes targetBoard is a LeaderboardObject or LeaderboardData

C#

//You have several quality-of-life shortcuts to reading records in different ways
//In all cases the final parameter is a delegate that will be called when the
//process completes and will contain the results found if any.

//Top X number of records
int howMany = 42;
int detailsCount = 0;
targetBoard.GetTopEntries(howMany, 
    detailsCount, 
    (entriesFound, ioError) =>
    {
        //Handle the entries found if ioError is false
    });

//Get entries for specific users
UserData[] users; //set this to who you want to read for
int detailsCount = 0;
targetBoard.GetTopEntries(users, 
    detailsCount, 
    (entriesFound, ioError) =>
    {
        //Handle the entries found if ioError is false
    });

//Get entries around the user's entry (includes the user's entry)
int beforeUser = -5;
int afterUser = 5;
int detailsCount = 0;
targetBoard.GetTopEntries(ELeaderboardDataRequest.k_ELeaderboardDataRequestGlobalAroundUser, 
    beforeUser, 
    afterUser, 
    detailsCount, 
    (entriesFound, ioError) =>
    {
        //Handle the entries found if ioError is false
    });
    
//Get all your friend's entries
int detailsCount = 0;
targetBoard.GetTopEntries(ELeaderboardDataRequest.k_ELeaderboardDataRequestFriends, 
    0, 
    0, 
    detailsCount, 
    (entriesFound, ioError) =>
    {
        //Handle the entries found if ioError is false
    });

Blueprint

We have both Tasks

And classic Callback style options

C++

// You will need to create a variable to store the CallResult
// This must be maintained until the CallResult is returned and complete
CCallResult<YourClass, LeaderboardScoresDownloaded_t> m_LeaderboardScoresDownloaded_t;

//Next make the call ... either to "for users"
SteamAPICall_t handle = SteamUserStats()->DownloadLeaderboardEntriesForUsers(leaderboard, targetUsers, numUsers);
// or not
SteamAPICall_t handle = SteamUserStats()->DownloadLeaderboardEntries(leaderboard, dRequest, start, end);
//Both use the same CallResult type so this is the only difference

// Use the handle with the CallResult created earlier
// Provide a pointer a suitable function to be called when the result
// Completes Valve will invoke the function passing the requested data
m_LeaderboardScoresDownloaded_t.Set(handle, this, &YourClass::Callback);

// Example Function to be called by the CallResult delegate
// Note that Unreal runs the Callback loop on a background thread
// This means you will need to create a GameThreadTask to bring the 
// Result forwarded to the GameThread
void YourClass::Callback(LeaderboardScoresDownloaded_t* Response, bool bIOError)
{
    	// Execute the delegate on the game thread asynchronously
	FGraphEventRef GameThreadTask = FFunctionGraphTask::CreateAndDispatchWhenReady([this, bIOError, Response]()
	{
		// Handle the results
	}, TStatId(), nullptr, ENamedThreads::GameThread);
	GameThreadTask->Wait();			
}
// First create a CallResult of type LeaderboardScoresDownloaded_t
// This must be held in memory until the process is returned
// So you will want to create it as a private variable on some object
// That will not be destroyed.
CallResult<LeaderboardScoresDownloaded_t> m_LeaderboardScoresDownloaded_t = CallResult<LeaderboardScoresDownloaded_t>.Create()

//Next we need to set a "start" and "end"
//Exactly what these do depends on the request type
//It is generally self-explanatory, for example, if you want 
//To get the top 10 results then you want to start at 0 and end at 10

// Call upload leaderboard score
var handle = SteamUserStats.DownloadLeaderboardEntries(boardId, 
                ELeaderboardDataRequest.k_ELeaderboardDataRequestGlobal, //type
                0 // Start
                10 //End
                );

// Once you have the handle you can set the CallResult
m_LeaderboardScoresDownloaded_t.Set(handle, (results, error) =>
{
    //Handle the results as you see fit
});

Attach File

Assumes targetBoard is a LeaderboardObject or LeaderboardData

C#

//Note the file will need a name but this is just the name of the file for the temporary upload
//So this is the name that will be in the user's Remote Storage, once attached we can remove it to save space.
//we like to us the same name all the time "tempFile" and we do not bother removing it instead we just let it 
//overwrite each time as a means to hold the space for future attachments
targetBoard.AttachUGC("tempFile", fileData, (ugcResult, ugcIoError) =>
{
    if (!ugcIoError)
    {
        if (ugcResult.Result == Steamworks.EResult.k_EResultOK)
            Debug.Log($"Attached file data to user entry on board {apiName}");
        else
            Debug.LogError($"Failed to attach file data to user entry on board {apiName}, Response Result = {ugcResult.Result}");
    }
    else
    {
        Debug.LogError($"Failed to attach file data to user entry on board {apiName}, IO Error!");
    }
});

Blueprint

This is a 3-step process

Upload data to attach

You can use Remote Storage Write or Write Async to do this

Mark the newly created file as "shared"

Attach the resulting Ugc Handle to the board

C++

As with the blueprints, this will require 3 steps each is asynchronous

// First we need to create our 3 CallResult entries
// File Write ASync Complete
CCallResult<YourClass, RemoteStorageFileWriteAsyncComplete_t> m_RemoteStorageFileWriteAsyncComplete_t;
// File Share Complete
CCallResult<YourClass, RemoteStorageFileShareResult_t> m_RemoteStorageFileShareResult_t;

// Next we need to upload our file data
// Assuming
FString name; // The file name
TArray<uint8> data; // The data to upload

// Then we call the FileWriteAsync
SteamAPICall_t handle = SteamRemoteStorage()->FileWriteAsync(StringCast<ANSICHAR>(*name).Get(), data.GetData(), data.Num());
// And set the handle
m_RemoteStorageFileWriteAsyncComplete_t.Set(handle, this, &YouClass::WriteComplete);

// In your WriteComplete function
// This uses the same file name as before
void YouClass::WriteComplete(RemoteStorageFileWriteAsyncComplete_t* result, bool ioError)
{
    // Share the new file
    SteamAPICall_t handle = SteamRemoteStorage()->FileShare(StringCast<ANSICHAR>(*name).Get());
    m_RemoteStorageFileShareResult_t.Set(handle, this, &YourClass::ShareComplete);
}

// This requires you to know the Board ID you want to attach the file to
// This is the same ID you got when you "found" or "created" the board
// Now in your ShareComplete funciton
void YourClass::ShareComplete(RemoteStorageFileShareResult_t* result, bool ioError)
{
    // Attach the share handle to the target board
    SteamAPICall_t handle = SteamUserStats()->AttachLeaderboardUGC(boardId, result->m_hFile);
    m_LeaderboardUGCSet_t.Set(handle, this, &YourClass::AttachComplete);
}

void YourClass::AttachComplete(LeaderboardUGCSet_t* result, bool ioError)
{
    // The process is now complete
}
// First create your CallResult to catch the results we will need

// This call result is invoked when file write to remote storage is complete
CallResult<RemoteStorageFileWriteAsyncComplete_t> m_RemoteStorageFileWriteAsyncComplete_t = CallResult<RemoteStorageFileWriteAsyncComplete_t>.Create()

// This call result is invoked when the file is shared and we have a share ID
CallResult<RemoteStorageFileShareResult_t> m_RemoteStorageFileShareResult_t = CallResult<RemoteStorageFileShareResult_t>.Create();

// This call result is invoked when the shared file ID is attached to the board
CallResult<LeaderboardUGCSet_t> m_LeaderboardUGCSet_t = CallResult<LeaderboardUGCSet_t>.Create();

// Assuming 
string file; // the name of the file to write
byte[] data; // the data to write to the file

// Call FileWriteAsync
var handle = SteamRemoteStorage.FileWriteAsync(file, data, (uint)data.Length);
// And set the handle to a valid delegate
m_RemoteStorageFileWriteAsyncComplete_t.Set(handle, WriteComplete);


// In the WriteCompleteis where we will "share" the file
void WriteComplete(RemoteStorageFileWriteAsyncComplete_t result, bool ioError)
{
    handle = SteamRemoteStorage.FileShare(file);
    m_RemoteStorageFileShareResult_t.Set(handle, ShareCompelte);
}

// Now in the ShareComplete we can attach the shared ID to the board
void ShareComplete(RemoteStorageFileShareResult_t result, bool ioError)
{
    var handle = SteamUserStats.AttachLeaderboardUGC(boardId, result.m_hFile);
    m_LeaderboardUGCSet_t.Set(handle, (r, e) =>
    {
        // Work is done, the data is now uploaded, shared and attached to the board
    });
}

Get Attached File

Assumes targetBoard is a LeaderboardObject or LeaderboardData

This assumes you already have a LeaderboardEntry you want to read the attachment for. and it assumes the data you are reading is serialized from a serializable object named "SomeObject"

C#

// Assuming
LeaderboardEntry entry;

entry.GetAttachedUgc<ExampleSerializableDataForAttachment>((dataFound, ioError) =>
{
    if(!ioError)
    {
        //Data Found is your attachment if any. Its up to you to check and see if that is a default value or actually set data
        //how you do that depends on what kind of object it is ... for a struct you should always implement the IEquitable, IComparable and overloads for == and != operators
    }
});

Blueprint

You will need the UGC Handle for the entry you want to read ... you can get this from the results of a Download Leaderboard Entries

With that, you can then download and then read the data

C++

// Create a CallResult for the RemoteStorageDownloadUGCResult_t
CCallResult<YourClass, RemoteStorageDownloadUGCResult_t> m_RemoteStorageDownloadUGCResult_t;

// This assumes you have the leaderboard entry you want to read an 
// attachment for ... you can see how to get a leaderboard entry
// from the Get Entries example above

// So this assumes
LeaderboardEntry_t entry; // from the Get Entries
// We will be using the UgcHandle from the entry
UgcHandle_t ugcHandle = entry.m_hUGC;

// Start the download
SteamAPICall_t handle = SteamRemoteStorage()->UGCDownload(ugcHandle, 0);
m_RemoteStorageDownloadUGCResult_t.Set(handle, this, &YourClass::DownloadComplete);

// Now in your download complete
void YourClass::DownloadComplete(RemoteStorageDownloadUGCResult_t* result, bool ioError)
{
    // We can use the same handle and get the data from this file
    TArray<uint8> fileData;
    fileData.SetNumUninitialized(result->m_nSizeInBytes);
    // this will populate the fileData with the data read
    int dataRead = SteamRemoteStorage()->UGCRead(ugcHandle, fileData.GetData(), result->m_nSizeInBytes, 0, EUGCReadAction::k_EUGCRead_ContinueReadingUntilFinished);
}
// This assumes you have the leaderboard entry you want to read an 
// attachment for ... you can see how to get a leaderboard entry
// from the Get Entries example above

// So this assumes
LeaderboardEntry_t entry;
// We will be using the UgcHandle from the entry
UgcHandle_t ugcHandle = entry.m_hUGC;

// Next we need to download this UGC Handle
// To do that we will need to use a CallResult

// This is invoked when the download is completed
CallResult<RemoteStorageDownloadUGCResult_t> m_RemoteStorageDownloadUGCResult_t = CallResult<RemoteStorageDownloadUGCResult_t>.Create();

// Once we have this declared we can set it such as
var handle = SteamRemoteStorage.UGCDownload(ugcHandle , priority);
m_RemoteStorageDownloadUGCResult_t.Set(callbackHandle, DownloadComplete);

// Now in your DownloadComplete handler, you can read the byte[] data of that file
void DownloadComplete(RemoteStorageDownloadUGCResult_t result, bool ioError)
{
    // We call first with empty buffers to get the size of the file
    SteamRemoteStorage.GetUGCDetails(ugcHandle, out _, out _, out int size, out _);
    // We use that size to create a proper buffer
    var results = new byte[size];
    // Now we call again with a properly allocated buffer
    SteamRemoteStorage.UGCRead(handle, results, size, 0, EUGCReadAction.k_EUGCRead_ContinueReadingUntilFinished);
    
    // results is not a byte[] containing the file data
}
Techincal Tools