Steamworks Documentation
Steamworks API Example Application (SpaceWar)

Overview

In order to help developers understand the usage of the Steamworks API we have included source code for a fully functional version of the classic Spacewar! multi-player shooter game. It is a simple 2D game with support for up to 4 players and provides a perfect opportunity to showcase many of the APIs available in the Steamworks SDK.

As you look through the code keep in mind that our goal was to write a simple, stripped-down game so we could showcase the Steamworks API as clearly as possible. You won't find any magnificent new graphics tech here; instead we hope you'll find clear examples of how deeply to integrate Steamworks functionality into your own projects.

The APIs and Steamworks features demonstrated in the example code include:
  • Cloud
  • Community Integration (avatars, friends names, etc)
  • Crash Reporting
  • Friends
  • HTML Surface
  • Inventory
  • Leaderboards
  • Matchmaking (Both lobbies and server browser)
  • Multi-Player Authentication (4 players supported in-game)
  • Networking
  • Stats & Achievements
  • Voice Chat

spacewar.png

Building & running the example

Requirements:
  • Visual Studio 2005 or newer.
  • DirectX SDK
  • Steamworks SDK. (Download the latest release.)

Once you have downloaded and extracted the Steamworks SDK package, find the sub-directory named SteamworksExample. Inside of this directory you'll find SteamworksExample.sln, which can be opened in Visual Studio. Open the solution and compile the project. If compilation succeeds then you're ready to go and can run the project directly from Visual Studio (you'll need to have Steam running in the background). If the build or execution fails try one of the tips below.

Common Build Problems

  • Cannot open include file: 'd3d9.h'
    If you encounter this error it means that your systems include path does not include the D3D include path, or that you have not installed the D3D SDK. First, make sure you have downloaded and installed the DirectX SDK. Once the SDK is installed you need to set up the include path. You can do this system wide via the standard Visual Studio environment variables, or you can set them up just for the SteamworksExample project by editing the project properties.
  • Fatal error LNK1104: cannot open file 'd3d9.lib'
    If you encounter this error it means that your systems library path does not include the D3D library directory. See the instructions above, except you need to update the library path instead of the include path.
  • Steam must be running to play this game (SteamAPI_Init failed).
    If you encounter this error when running the game, make sure that Steam is running. If Steam is running, ensure there is a steam_appid.txt file in the directory with the game executable. This file ships with the SDK example and should be present if you run from within Visual Studio or directly from the Debug or Release sub directories.

    When you are launching the game from the exe directly, outside of the Steam UI this file must be present and must contain a single line with the game's AppID (for your games, Valve will assign each an AppID, the example game's AppID is 480). When you ship your own game through Steam this file will not be needed as Steam will auto-detect your AppID when the game is launched.
  • The application has failed to start because steam_api.dll was not found. Re-installing the application may fix this problem.
    In order to run successfully steam_api.dll must be located in the same directory as the example game executable. This will also be true for your own games which utilize Steamworks. The Visual Studio project file should place the executable in the appropriate directory when building, but if you are using a different compiler or have modified the solution or project files you may need to copy it yourself. You can redistribute steam_api.dll with your own Steamworks games when shipping them.
  • The application has failed to start because d3dx_??.dll was not found. Re-installing the application may fix this problem.
    The example relies on the D3D9X helper library which ships with the DirectX SDK. If you run the example on the same machine you have built it on the library should be found automatically. If you copy your compiled binary to another machine you may need to install the D3D redistributables to obtain the same version of D3D9X that you compiled against on your development machine.

Code Overview

Once you have the Spacewar! example project compiling and running you'll want to start looking at the code. If you browse the files within the Visual Studio solution explorer you'll see that the code has been broken up into Game and Engine code. You can ignore the code in the Engine folder - it supports basic 2D rendering via D3D and basic keyboard input. All of the important code documenting Steamworks API usage is files in the Game folder.

The most interesting areas to begin looking at the code are described briefly below:
  • Main.cpp -- Main entry point for the example game.
    API Usage shown:
    • Client API Initialization -- You'll need to initialize the API early during app startup, and you'll see how this is done inside of the RealMain() function in Main.cpp.
    • API Error/Warning logging -- During development you may want to get some logging output from the Steam APIs in order to help debug problems. You can see an example of setting up debug logging inside the RealMain() function where ISteamClient::SetWarningMessageHook is called.
    • Crash reporting -- You may wish to use Steam's built in minidump crash reporting in your games. If you do you'll find an example of installing the exception handler and setting up minidump writing in WinMain() and MiniDumpFunction() within Main.cpp.
  • SpaceWarServer.cpp/h -- Server code for the example game.
    API Usage shown:
    • Gameserver API Initialization -- Inside game servers you'll want to initialize a stripped down version of the API that doesn't have the individual user interfaces exposed. You'll find this done in the constructor for CSpaceWarServer in SpaceWarServer.cpp.
    • Running API Callbacks -- In your games you'll want to periodically run Steam callbacks to process results from Steam's asynchronous API calls. You'll find an example of running callbacks in a game server via SteamGameServer_RunCallbacks in the CSpaceWarServer::RunFrame() function, and you'll find examples of handling individual callbacks and registering them inside the CSpaceWarServer constructor code and header file.
    • Multi-Player Authentication (VAC Ban handling) -- If your game is an online multi-player game then you'll want to confirm that users own the game before you let them join an online server. You'll find callback handlers and calls to the ISteamGameServer API used within SpaceWarServer.cpp for these purposes. You'll also see how to handle deny and kick responses that Steam may send you due to users not owning your product, or due to users being banned or needing to be kicked for cheating.
    • Networking API -- If you are building an online game you may want to utilize Steam's built in networking APIs. You'll find examples of their usage server side in game servers via ISteamNetworking API calls using the SteamGameServerNetworking() accessor and callbacks within SpaceWarServer.cpp.
    • Matchmaking and Master Server communication -- If you are building a multi-player game and wish to utilize the Steam server browser, then your game server will need to communicate with the Steam Master Servers. You'll find examples of doing this in the CSpaceWarServer constructor and in the CSpaceWarServer::SendUpdatedServerDetailsToSteam() method.
  • SpaceWarClient.cpp/h -- Client side code for the example game.
    API Usage shown:
    • Matchmaking via Lobbies -- In your online games you may wish to include matchmaking via lobbies in addition to, or instead of, the Server Browser. You'll find examples of using the lobby code and callbacks via the ISteamMatchmaking interface inside of SpaceWarClient.cpp. You'll also want to look at Lobby.cpp/h which include some of the code for handling state and callbacks once inside a given lobby.
    • Friends & Community Integration -- Steam allows you to use rich identity information for players, including their persona name and personal avatar, within your game. You'll find an example of integrating persona names and avatars into scoreboards via the ISteamFriends interface inside of SpaceWarClient.cpp
    • Networking API -- You'll find an example of client side usage of the Steam Networking API inside of SpaceWarClient.cpp (see SpaceWarServer.cpp for the server side implementation).
  • StatsAndAchievements.cpp/h -- Stats and Achievement handling for the example game.
    API Usage shown:
    • Stats & Achievements -- You'll find an implementation of both Stats and Achievements handling within StatsAndAchievements.cpp. The file contains the CStatsAndAchievements class, which is called with updated state information from CSpaceWarClient. Once CStatsAndAchievements has received state change information from the game client, it handles notifying Steam of changes to user stats or achievements obtained via the ISteamUserStats interface.
  • Lobby.cpp/h -- Matchmaking via Lobbies
    API Usage shown:
    • Matchmaking via Lobbies -- You'll find part of the example game's lobby-based matchmaking implementation in Lobby.cpp. Lobby.cpp works closely with SpaceWarClient.cpp to handle matchmaking so you'll want to look at both of them. When examining the lobby code, take special note of the callbacks and calls to ISteamMatchmaking interface methods.
  • ServerBrowser.cpp/h -- In-game Server Browser
    API Usage shown:
    • Matchmaking via ServerBrowser -- If you support matchmaking via the Server Browser then you'll probably want to provide a server browser listing directly inside your game to supplement the listing provided by the Steam UI. You'll find an example of getting the list of Internet servers for your game and displaying it to the user inside ServerBrowser.cpp.
  • Inventory.cpp/h -- Steam Inventory Service
    API Usage shown:
    • Steam Inventory -- Integrates with the Steam Inventory which provides access to the Steam Economy. This allows you to easily integrate items into your game.

If your game has an existing authentication and matchmaking engine that you will keep using then you may want to remove the USE_GS_AUTH_API define from Spacewars.h. When you remove this define it will cause the sample to NOT use Steam authentication or matchmaking but you will still be able to access other Steam functionality such as achievements and friends information, look at the code for details.