Integrating Steamworks
Overview
The purpose of this guide is for game makers to integrate Steamworks IAP (in-app purchasing) into Beamable.
Integration
Beamable integrates with this technology.
Valve's Steamworks is a set of tools and services that help game developers and publishers build their games and get the most out of distributing on Steam.
Feature | Beamable Support? | Detail |
---|---|---|
Steamworks' Microtransactions | ✔️ | See the steps below |
Game Maker User Experience
During development, the game maker's user experience is as follows:
Steps
Follow these steps to get started: This process will integrate Steamworks IAP into Beamable.
Step 1. Setup 3rd Party
Name | Detail |
---|---|
1. Sign-in / Register to Steamworks | • See partner.steamgames.com for more info Note: Choose partnership type of "Game Developer or Publisher" |
2. Complete Steamworks' "Getting Started" | • See partner.steamgames.com/doc/gettingstarted for more info Note: Complete all the steps |
3. Capture Account Details | Locate the following account details values which are needed for subsequent steps below... • AppId - The value is located by selecting the application on your homepage in Steamworks• Web API - The value is located at steamcommunity.com/dev/apikey |
Step 2. Import SDK
Name | Detail |
---|---|
1. Set Unity's Target Platform to Standalone | • See Unity's docs.unity3d.com/Manual/BuildSettings.html for more info Note: Steamworks for Unity works only for this target platform |
2. Download Steamworks.NET's SDK | • See steamworks.github.io for more info Note: Steamworks.NET is a C# Wrapper for Valve’s Steamworks API and is completely free and open source under the permissive MIT license. It makes it easy to get started with Unity-based projects |
3. Complete Steamworks.NET's "Installation" | • See steamworks.github.io/installation for more info Note: Complete all the "Unity Instructions" steps |
4. Configure Steamworks' Appid | • Create/open the steam_appid.txt which now resides in the root of your Unity project and replace the contents with your own AppId value (e.g. 480) |
Step 3. Setup Beamable
Name | Detail |
---|---|
1. Complete Beamable's "Getting Started" Guide | • See Getting Started for more info Note: Complete all steps |
2. Optional, Complete Beamable's "Using Store" Guide | • See Stores - Guide for more info Note: For game makers who are new to Beamable, all steps are recommended. However, advanced game makers make skip this step entirely |
3. Configure Beamable's Content | • Open the Content Manager • For each SkuContent item, populate each Product IDs → Steam value with any unique integer value desired (e.g. '1') |
4. Open Beamable's Portal | • See db-portal-prod.disruptorbeam.com for more info • Populate all values and click "Save"... • cid - See the config-defaults.txt file in Unity's Project Window• email - Use your own value• password - Use your own valueNote: The specific url above is required for this usage of Beamable Portal |
5. Configure Beamable's Portal | • Click "+Config" and choose "Steam" • Populate all values and click "Save" • sandbox - Use true for development and false for production• appid - Use the Steamworks AppId from Step 1 above• key - Use the Steamworks Web API from Step 1 above |
Example
Here are examples which cover common programming needs.
Beamable SDK Examples
• The following example code is available for download at GitHub.com/Beamable_Steamworks_Examples
Project Window
This /Steamworks/
folder demonstrates a complete integration solution including;
SteamworksProvider.cs
- Adds a new service to the Beamable 'ServiceManager`SteamworksService.cs
- Defines the new Beamable serviceSteamworksExample.cs
- Demonstrates successful usage of Beamable with Steamworks integration
Scene Hierarchy
This SteamworksExample.unity
scene contains;
- The setup for Steamworks integration
- The Beamable Store Flow prefab
Code
1. SteamworksProvider
This SteamworksProvider.cs
demonstrates adding a new ISteamService
to the Beamable ServiceManager
.
Note: Game makers can use this class as-is or as inspiration to create a custom solution.
using UnityEngine;
#if USE_STEAMWORKS
using Beamable.Common.Steam;
using Beamable.Service;
using Steamworks;
#endif
namespace Beamable.Examples.Integrations.Steamworks
{
/// <summary>
/// Provider for <see cref="Steamworks"/>.
/// </summary>
public class SteamworksProvider : MonoBehaviour
{
#if USE_STEAMWORKS
// Unity Methods --------------------------------
private void Awake()
{
ServiceManager.ProvideWithDefaultContainer<ISteamService>(new SteamworksService());
DontDestroyOnLoad(this.gameObject);
}
public void Start()
{
if(SteamManager.Initialized)
{
string personaName = SteamFriends.GetPersonaName();
var appId = SteamUtils.GetAppID();
Debug.Log($"Steam User Name = {personaName}, Steam App ID = {appId.m_AppId}");
}
}
#endif
}
}
2. SteamworksService
This SteamworksService.cs
demonstrates the implementation of the needed Beamable service.
Note: Game makers can use this class as-is.
#if USE_STEAMWORKS
using System;
using System.Collections.Generic;
using UnityEngine;
using Beamable.Common;
using Beamable.Common.Steam;
using Steamworks;
namespace Beamable.Examples.Integrations.Steamworks
{
/// <summary>
/// Service for <see cref="Steamworks"/>.
/// </summary>
public class SteamworksService : ISteamService
// Fields ---------------------------------------
private bool _transactionRegistered = false;
private List<Action<SteamTransaction>> _callbacks;
// Methods --------------------------------------
Promise<Unit> ISteamService.RegisterAuthTicket()
{
var promise = new Promise<Unit>();
if (!SteamManager.Initialized)
{
promise.CompleteError(new Exception("Steamworks not initialized."));
return promise;
}
byte[] steamAuthTicketBuffer = new byte[1024];
uint steamAuthTicketBufferSize = 1024;
Callback<GetAuthSessionTicketResponse_t>.Create(_ =>
{
byte[] usedBytes = new List<byte>(steamAuthTicketBuffer).GetRange(0, (int) steamAuthTicketBufferSize)
.ToArray();
string ticket = BitConverter.ToString(usedBytes).Replace("-", string.Empty);
Beamable.API.Instance.FlatMap(beamable =>
{
return beamable.Requester.Request<Beamable.Common.Api.EmptyResponse>(
Beamable.Common.Api.Method.POST,
$"/basic/payments/steam/auth",
new SteamTicketRequest(ticket));
})
.Then(f => promise.CompleteSuccess(PromiseBase.Unit))
.Error(ex => promise.CompleteError(ex));
});
SteamUser.GetAuthSessionTicket(steamAuthTicketBuffer, (int) steamAuthTicketBufferSize,
out steamAuthTicketBufferSize);
return promise;
}
Promise<SteamProductsResponse> ISteamService.GetProducts()
{
if (!SteamManager.Initialized)
{
var promise = new Promise<SteamProductsResponse>();
promise.CompleteError(new Exception("Steamworks not initialized."));
return promise;
}
long steamID = (long) SteamUser.GetSteamID().m_SteamID;
return Beamable.API.Instance.FlatMap(beamable =>
{
return beamable.Requester.Request<SteamProductsResponse>(
Beamable.Common.Api.Method.GET,
$"/basic/payments/steam/products?steamId={steamID}");
});
}
void ISteamService.RegisterTransactionCallback(Action<SteamTransaction> callback)
{
if (!SteamManager.Initialized)
{
Debug.LogError("Steamworks not initialized.");
return;
}
if (callback != null)
{
if (_callbacks == null)
{
_callbacks = new List<Action<SteamTransaction>>();
}
_callbacks.Add(callback);
if (!_transactionRegistered)
{
Callback<MicroTxnAuthorizationResponse_t>.Create(OnTransactionAuthorized);
_transactionRegistered = true;
}
}
}
private void OnTransactionAuthorized(MicroTxnAuthorizationResponse_t data)
{
if (_callbacks != null)
{
var authorized = Convert.ToBoolean(data.m_bAuthorized);
var steamTransaction = new SteamTransaction(authorized, data.m_ulOrderID.ToString());
foreach (var callback in _callbacks)
{
callback?.Invoke(steamTransaction);
}
}
}
}
}
#endif
3. SteamworksExample
This SteamworksExample.cs
demonstrates successful usage of Beamable with Steamworks integration.
Note: Game makers can use this class as inspiration to create a custom solution.
using UnityEngine;
using Steamworks;
namespace Beamable.Examples.Integrations.Steamworks
{
/// <summary>
/// Demonstrates <see cref="Steamworks"/>.
/// </summary>
public class SteamworksExample : MonoBehaviour
{
// Unity Methods --------------------------------
protected void Start()
{
Debug.Log($"Start() Instructions...\n" +
" * Complete steps: https://docs.beamable.com/docs/integrating-steamworks\n" +
" * Run The Scene\n" +
" * See Unity Console Window for success\n");
SetupBeamable();
}
// Methods --------------------------------------
private async void SetupBeamable()
{
var beamableAPI = await Beamable.API.Instance;
Debug.Log($"beamableAPI.User.id = {beamableAPI.User.id}");
if(SteamManager.Initialized)
{
// Successfully fetch arbitrary Steamworks data
string personaName = SteamFriends.GetPersonaName();
Debug.Log($"Success! SteamFriends.GetPersonaName = {personaName}");
}
else
{
Debug.Log($"Failure! SteamManager.Initialized = {SteamManager.Initialized}");
}
}
}
}
Game Window
Advanced
This section contains any advanced configuration options and workflows.
Updated about 1 year ago