Skip to content

@garrynewman garrynewman released this Feb 28, 2020 · 101 commits to master since this release

Mostly fixes, but I implemented the SteamNetworkSocket stuff into Rust so there's been some changes and additions there too.


  • Add Steamworks.Dispatch.OnDebugCallback
  • Fixed Dispatch not stopping properly when Server/Client Shutdown
  • Now throws an exception is try to initialize more than once
  • Fixed SteamFriends events not being hooked
  • Fixed SteamServer events being hooked twice
  • Added SteamNetworkingUtils.ConnectionTimeout
  • Added SteamNetworkingUtils.Timeout
  • Renamed SteamNetworkingUtils.GetConfigInt to SetConfigInt
  • Fixed dispatch double callbacks when server initialized
  • Added a bunch of functions/properties to NetIdentity
  • Added a bunch more functions to NetAddress
  • ConnectionInfo exposes NetAddress, NetIdentity
  • Rename SocketInterface to SocketManager
  • Rename ConnectionInterface toConnectionManager
  • Fixed Sockets created using CreateRelaySocket not receiving messages
  • Added interface versions of Connection/SocketManagers
  • Removed SteamClient.OnCallbackException
  • Removed SteamServer.OnCallbackException
  • Added Dispatch.OnException
  • Fixed Leaderboards returning corrupt results under Unity
  • Added SteamNetworkingUtils.SendBufferSize
Assets 3

@garrynewman garrynewman released this Feb 24, 2020 · 144 commits to master since this release

Steamwork Update

We're now using Valve's latest SDK - version 1.48

Library Changes

Facepunch.Steamworks.Posix32/64.dll are now combined and we only have Facepunch.Steamworks.Posix.dll.

If you have Facepunch.Steamworks.Posix32.dll or Facepunch.Steamworks.Posix64.dll anywhere - delete them.

Callback Changes

We're using the new ManualDispatch for events & callbacks. It's cleaner and friendlier to C#.

Nothing should change from an end user's point of view - but if you had other code, like c++ code or something that is using the Steam callback code - it's not going to work anymore.

Flat Functions & 32Bit Support

We're back to using the provided flat functions instead of recreating the internal classes. Valve put a lot of work into cleaning this up for us and it's now a lot cleaner, friendlier and feature complete.

This has also meant that we can now support 32bit platforms properly again.

New Wiki

There's a bunch of new examples and usage help on the wiki !


  • Updated to Steamworks 1.48
  • Added SteamRemotePlay Interface
  • Added Friend.RequestUserStats()
  • Added Friend.GetAchievementUnlockTime
  • Added Friend.GetAchievement
  • Added Friend.GetStatInt
  • Added Friend.GetStatFloat
  • Fixed SocketInterface creating duplicate connections & callbacks
  • Added SteamNetworkUtils.DebugLevel
  • Added SteamNetworkUtils.OnDebugOutput
  • Fixed NetMsg creating garbage on dispose
  • Added SteamUtils.IsSteamChinaLauncher
  • Added SteamUser.OnDurationControl
  • Added SteamUserStats.RequestGlobalStatsAsync
  • SteamFriends.OnGameOverlayActivated now correctly passes a bool
  • Added Leaderboard.EntryCount
  • Added SteamInput.GetDigitalActionGlyph
  • Added ConnectionInfo.EndReason
  • Limit SourceServerQuery to one concurrent request per endpoint
  • Fixed false sometimes wrongly returned from SubscribeDownloadAsync
  • Added SteamServer.UserHasLicenseForApp
  • Added SteamUgc.DownloadAsync
  • Added SteamUgc.StartPlaytimeTracking
  • Added SteamUgc.StopPlaytimeTracking
  • Added SteamUgc.StopPlaytimeTrackingForAllItems
Assets 3

@garrynewman garrynewman released this Aug 29, 2019 · 254 commits to master since this release

A big change here is that the dlls are now split between Posix (Linux+Mac) and Windows. This simplified some of the code paths internally, but it also prevents some (non harmful) warnings in Unity which looks for the other platforms libraries.

We've been testing this version with Rust for a while with a new IL2CPP compile, so have managed to work out and fix a few bugs related to it. This means that if you're using Unity and want to ship a IL2CPP build with Steamworks, it should no longer be an issue.

  • Fixed strings getting messed up when using IL2CPP in Unity
  • Fixed IL2CPP calling convention problems
  • Fixed GetFriends returning blocked friends
  • Fix Utf8StringToNative.GetInstance getting optimized out in Unity
  • Throw exceptions if trying to use client interfaces with no client
  • Can disable automatic RunCallback in Init calls
  • Don't catch and send exceptions to OnCallbackException when calling RunCallback manually
  • Added UGCItem download stats
  • Added Steamworks.Ugc.Query.WhereSearchText
  • Added Steamworks.Ugc.Item.VotesUp
  • Added Steamworks.Ugc.Item.VotesDown
  • Added Steamworks.Ugc.Item.Subscribe
  • Added Steamworks.Ugc.Item.Unsubscribe
  • Added LobbyQuery filters
  • Added SteamMatchmaking.OnLobbyCreated
  • Added SteamMatchmaking.OnLobbyGameCreated
  • Added SteamNetworking.AllowP2PPacketRelay
  • Added SteamUserStats.IndicateAchievementProgress
  • Added Lobby.SetGameServer
  • Added SteamId.IsValid
  • Fixed ServerQuery.AddFilter issues
  • Unexpected Steam Shutdown handled nicely
Assets 3

@garrynewman garrynewman released this Jun 21, 2019 · 320 commits to master since this release

Hey guys - I've dropped the preview in this version because we've been running it in Rust for a month without any real problems.

If you're using Unity and want to see how to use some stuff, there's a test repo here.


  • Fixed strings passed to functions not being marshalled as UTF8
  • Fixed strings in structs not being marshalled as UTF8
  • Added SteamClient.RestartAppIfNecessary
  • Added OnLobbyEntered
  • Added baseline SteamInput
  • OnP2PConnectionFailed passes error enum
  • Increased max string length
  • Fixed SteamNetworkingSockets events not working on server
  • Add IntPtr version of HandleIncomingPacket
  • Added OnSteamServerConnectFailure
  • Added SteamServer.ClearKeys()
  • Added SteamServer.LogOff()
  • Fixed server not automatically being listed with master server
  • Fixed how some currencies are presented
Assets 3

@garrynewman garrynewman released this May 27, 2019 · 348 commits to master since this release

Facepunch.Steamworks v2.0 is an almost total rewrite of the previous version of Facepunch.Steamworks.

I felt that we should be using global static classes to make things easier, and that we were being too heavy handed in some places. This version stays a bit more faithful to the regular API, while making things a bit easier.

We're using async for callbacks too - which makes things a lot less shitty.

var leaderboard = await SteamUserStats.FindLeaderboardAsync( "Testleaderboard" );

var friendScores = await leaderboard.Value.GetScoresFromFriendsAsync();

foreach ( var e in friendScores )
	Console.WriteLine( $"{e.GlobalRank}: {e.Score} {e.User}" );


I've implemented this into Rust on the staging branch. This has meant I've added and tested everything that Rust is using, and it's being actively tested and used on Windows, Linux and Mac.


Valve's new netcode stuff is implemented, but not tested. I've tried to keep it as relatively raw as possible while keeping it relatively simple to use.

This should get better over the next few months because I intend to try replacing our current Raknet implementation with it in Rust, and also adding netcode from scratch into one of our prototypes using it.

Creating a normal socket on any/all ip addresses on port 21893:

private class MySocketInterface : SocketInterface
	public override unsafe void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
		// Handle Incoming Message

var mysocket = SteamNetworkingSockets.CreateNormalSocket<MySocketInterface>( Data.NetAddress.AnyIp( 21893 ) );

Or using Valve's relay system (clients connect via the server's steamid)

var mysocket = SteamNetworkingSockets.CreateRelaySocket<MySocketInterface>();

Connecting to a normal thing

private class TestConnectionInterface : ConnectionInterface
	public override unsafe void OnMessage( IntPtr data, int size, long messageNum, long recvTime, int channel )
		// Handle messages from server
var connection = SteamNetworkingSockets.ConnectNormal<MyConnectionInterface>( NetAddress.From( "", 21893 ) )

Or via Steam relay

var connection = SteamNetworkingSockets.ConnectRelay<TestConnectionInterface>( serverSteamId );

SocketInterface and ConnectionInterface have a few different methods you can override. SocketInterface tries to maintain a good list of connecting/connected clients to easy access.

Changes since alpha 1

  • Fixed possible crashes due to hanging pointers
  • Added InventoryRecipe
  • Added Acquired and Origin properties to InventoryItem
  • Added InventoryDef.GetRecipesContainingThis()
  • Fixed SteamInventory not getting events on server
  • Fixed server not getting inventory definitions
  • Fixed NRE in OnAchievementIconFetched
  • Added InventoryResult.BelongsTo( )
  • Async calls are abandoned if steam is released during call
  • Added GetAuthSessionTicketAsync
  • UGC Queries are all on one struct again
  • Steam types implement IComparable, IEquatable
  • Filled out FriendGameInfo
  • Added SteamInventory.StartPurchaseAsync
  • Added SteamMatchmaking.GetHistoryServers
  • Added SteamMatchmaking.GetFavoriteServers
  • Added Ugc.Item.Edit()
  • Added Steamworks.ServerList.IpList for querying an array of Ips
  • OnGameLobbyJoinRequested now passes a lobby object
  • Added SteamServerStats
  • SteamServer.Update becomes RunCallbacks, has OnCallbackException
  • Added byte version of SteamUser.DecompressVoice
  • Added SteamUserStats.ResetAll
  • OnAchievementProgress returns a Achievement instead of a string
  • Fixed using wrong struct packing on windows, sometimes
  • Added InventoryDef.IsGenerator
  • Added SteamInventory.Items (because it's nice and noob friendly)
  • Added RequestEncryptedAppTicketAsync
  • Added SteamNetworkingSockets (normal and relay)
  • Fixed some SteamInventory methods not being public
  • Added UgcEditor.WithChangeLog( changes )
  • Added UgcEditor.WithPreviewFile( file )
  • Made SteamInventory.FindDefinition public
  • Added ServerInfo.QueryRulesAsync (source style query)
  • Added Ugc.Item.Directory
  • Added SteamFriends.RequestUserInformation
  • Added ReadVoiceDataBytes
  • Added SteamNetworkUtil
  • Added SteamParties (which seems useless, lmk if you're using it)
  • Added SteamMatchmaking (lobbies)
Assets 3

@garrynewman garrynewman released this Apr 30, 2019

This is a preview of version 2 of Facepunch.Steamworks. This has had a decent enough testing across Windows, Osx and Linux, but it could do with more before it comes out of alpha.

Things have changed in Unity and C# since I made the original library. We now have a decently up to date .net version and can use some more advanced features that wasn't possible before.

Big changes here:

  • Global static class based rather than instance class
  • Uses simulated vtables instead of Valve's flat functions (some classes are missing in flat versions)
  • Uses async for functions with callresults
  • 32bit OSes no longer supported (less bullshit)
  • Created from the ground up
  • Totally incompatible with previous versions (but you'll probably want to use this instead)
  • Some features are missing (just lobbies and a few random functions, working on it)
  • The Unity plugin in the zip file should automatically copy/ship the right libraries

Let me know if there are any problems.

Assets 3

@garrynewman garrynewman released this Dec 6, 2017 · 795 commits to master since this release


  • Throw exception if trying to create Client after Server
  • Workshop upload progress will return sane values
  • Fixed leaderboard.AddScore description
  • Renamed Achievement.Percentage to GlobalUnlockedPercentage
  • Fixed zero length packets clogging p2p queue
  • Added Leaderboard.OnBoardInformation callback
  • Added Friend.GetAvatar( size )
  • Friends.GetAvatar takes a callback instead of returning an Image
  • Added Friends.GetCachedAvatar - returns Image or null (old behaviour of Friends.GetAvatar)
  • Added Lobby.OnChatStringRecieved
  • Fixed Lobby sometimes losing chat messages
  • Added RemoteFile.Forget()
  • Voice no longer requires unsafe
  • Fixed RemoteStorage errors on osx/linux
  • Replaced netstandard1.6 with netstandard2.0
  • Added support for publishing workshop items from another app (tools)
  • Server Lists return IPAddress instead of int
  • Added ServerRequest.OnServerResponded
  • Added ServerRequest.OnFinished
  • Throw exception if trying to create a new instance when once exists
  • Fixed not being able to change the lobby owner
  • Added Screenshots.Write( data, width, height )
  • Changed Server.Stats.Set to SetInt/SetFloat
  • Server stats callback includes client steamid
  • Checks GameId on achievement callbacks
  • Added Achievments.OnAchievementStateChanged
  • Refresh achievements on startup
  • Calls on an unresolved leaderboard are deferred
  • Workshop Item Subscription

Breaking Changes

So some breaking changes there. Biggest one you'll probably run into is GetAvatar. If you're too lazy to fuck about just change the calls to GetCachedAvatar instead. The benefit of using GetAvatar with the callback is that if Steam hasn't downloaded that user's avatar, it'll download it so you don't have to test and refresh download manually.

Assets 5

@garrynewman garrynewman released this Jul 6, 2017 · 872 commits to master since this release


  • Added Stats.Set
  • Added Stats.Add
  • Added Friend.IsOnline
  • Added Friend.IsAway
  • Added Friend.IsBusy
  • Added Friend.IsSnoozing
  • Refactored Server Init
  • Simpified Client.RemoteStorage
  • Added Client.RestartIfNecessary (static)

New Server Init

Some people found it difficult to create a server that was actually visible in the previous versions. This was because to get your server listed you needed to fill in GameDescription, ModDir and Product. Since these things can't be changed at any point beyond initialization I've refactored the way servers are created.

Old Way:

var server = new Facepunch.Steamworks.Server( 252490, 0, 30003, 30004, 30005, false, "VersionString" ) 

New Way:

var serverInit = new ServerInit( "rust", "Rust" );
  serverInit.GamePort = 28015;
  serverInit.Secure = true;
  serverInit.QueryPort = 28016;

var server = new Facepunch.Steamworks.Server( 252490, serverInit )

This feels like a common sense change, making the process a bit more self documenting and a lot more foolproof. We've been using this new initialization method in Rust for a couple of weeks, so it's all tried and tested.

Missing Features

If you're using the library and are missing features - open a new issue and we'll try to add it as soon as possible.

Assets 3

@garrynewman garrynewman released this Jun 9, 2017 · 886 commits to master since this release

  • Updated to Steamworks SDK 1.40 (new redistributes included).
  • Added Client.CurrentLanguage + AvailableLanguages
  • Added NetCore support
  • Added Achievement support
  • Added RichPresence support
Assets 3

@garrynewman garrynewman released this Mar 16, 2017 · 928 commits to master since this release

Added leader-boards, a ton of App functions and fixed a bunch of bugs.

Assets 3
You can’t perform that action at this time.