If you don't know it, Steamworks is a framework/SDK that allows to control Steam and its functionalities just like your games do, so interaction with friends, networking, matchmaking, music and more:
http://partner.steamgames.com
I will continue to update the thread with all the strange, funny and interesting things I will notice so stay tuned and add your personal experience if you want.
Visual Studio only
Steamworks uses the Microsoft fastcall for the API and so there is no way to use Mingw/GCC.
Documentation
Basically the documentation is made just by the comments in the header files
There is an example game (SpaceWars) but sometimes it's not enough to understand how something works or should work.
Quickly how it works
Your program uses the local steam_api.dll as way to communicate with Steam.exe via IPC (mutex, file mapping, shared memory and so on), basically there is a part of code that is executed by this local dll and another (core) part executed in Steam.exe, by steamclient.dll.
You need an AppID
You need to specify the ID of a game for using Steamworks.
There are two ways to do that:
- creation of the local file steam_appid.txt containing the number
- setting of SteamAppId and SteamGameId environament variables
Go with the env vars!
When you use the steam_appid.txt method, Steam automatically creates the two environment variables and they have the priority during the initialization.
So if you create steam_appid.txt with id 480, call SteamAPI_Init, call SteamAPI_Shutdown, and then you want to use appid 10... you can't, because Steamworks will continue to use appid 480.
So use ever the environment.
callbacks
Some API are async, so you call them and then you must wait the response from a callback.
The problem is that they are not callbacks easy to use like in C, they are objects.
So something like "set callback; call API; wait callback;" is not possible, you must create an object that contains both the caller and callback and you must initialize (new), use and maybe destroy it (delete).
If you are not used to C++ and objects you will find it very annoying.
Frames
The callbacks are frame-related.
Basically when you use a callback you must call SteamAPI_RunCallbacks or RunFrame every X milliseconds.
It's made to be game compatible but the concept is quite strange, it's like the implemented IPC method is blocked instead of async.
Some API are weird
An example of API that doesn't have much sense is GetInstalledApps that requires two arguments:
- an array of integers to use as destination
- the highest appid number
Yeah I know that probably it's impossible for someone to have 1000000 games, anyway...
Sometimes you need to own a game to query it, other times not
This is something that I find very weird, basically there are some features of Steamworks that can be used only if you own the game.
For example if you don't have Left 4 Dead 2, you cannot retrieve the list of online lobbies.
But if you don't have Serious Sam HD (appid 41010), you can retrieve the list without problems.
That's quite confusing, really.
Some API don't work
Some API, when called, return an error or an empty result.
That's the case of GetAppName and GetAppInstallDir of SteamAppList, but there are also a couple in the matchmaking part that do the same.
Use-after-free (no security bug)
Just for fun, nothing serious so don't worry:
Code: Select all
SteamAPI_Init();
for(i = 0; i < 10; i++) {
SteamClient()->BReleaseSteamPipe(i);
}
SteamController()->Shutdown();