Table of Contents
29. Module steam¶
The steam plugin integrates Steamworks SDK into mini-mbm games, exposing achievements, stats, leaderboards, cloud saves, overlay dialogs, and DLC detection to Lua.
Important
Steam is a desktop platform. This plugin is supported on Windows, Linux, and macOS only. It is not available on Android or iOS.
Note
Load the plugin with require "steam" (or require "libsteam") inside onInitScene().
Always check steam.isReady() before calling any other function —
it returns false if the Steam client is not running or the user does not own the game.
29.1. Prerequisites¶
Steamworks Partner Account — enrol here. Each title uses its own App ID; the plugin never hard-codes it.
Steamworks SDK — download from the partner portal under Developer Tools → Steamworks SDK. Extract it locally (e.g.
/home/user/steamworks_sdkorC:\steamworks_sdk).Steam client — must be running on the development machine during testing.
steam_appid.txt — create a plain-text file containing only your App ID (e.g.
480) and place it next to themini-mbmexecutable for development runs. Retail builds launched via the Steam client receive the App ID automatically.
29.2. Building¶
29.2.1. Linux / macOS (CMake)¶
mkdir -p build/linux_debug && cd build/linux_debug
cmake ../.. \
-DPLAT=Linux \
-DUSE_ALL=1 \
-DUSE_STEAM=1 \
-DSTEAMWORKS_SDK_PATH=/path/to/steamworks_sdk \
-DCMAKE_BUILD_TYPE=Debug
make -j$(nproc)
Replace Linux with MacOs for macOS, and Debug with Release for distribution builds.
29.2.2. Windows (Visual Studio 2022)¶
Open
platform-msvs/mini-mbm.slnin Visual Studio 2022.Set the
STEAMWORKS_SDK_PATHenvironment variable before opening Visual Studio:Open the Start menu and search for “Edit the system environment variables”.
Click Environment Variables…, then under User variables click New.
Name:
STEAMWORKS_SDK_PATHValue:C:\steamworks_sdk(your actual path).Click OK on all dialogs, then restart Visual Studio.
The steam project is disabled by default in Configuration Manager (no SDK headers available without the SDK). Enable it: go to Build → Configuration Manager and check the Build checkbox for the steam project.
Build the steam project.
copy-steam-dll.batruns automatically after a successful build and copies the correct Steam DLL (steam_api64.dllorsteam_api.dll) into the output folder.Place
steam_appid.txt(containing only your App ID number, e.g.480) next tomini-mbm.exe.
29.2.3. Windows (CMake + MinGW)¶
mkdir build\mingw_debug && cd build\mingw_debug
cmake ..\.. -G "MinGW Makefiles" ^
-DPLAT=Windows ^
-DUSE_ALL=1 ^
-DUSE_STEAM=1 ^
-DSTEAMWORKS_SDK_PATH=C:\steamworks_sdk ^
-DCMAKE_BUILD_TYPE=Debug
mingw32-make -j%NUMBER_OF_PROCESSORS%
29.3. Runtime Deployment¶
The Steam shared library is copied to the output directory automatically as a post-build step. For final distribution, include the Steam library in your shipped game folder:
Platform |
Library to ship |
|---|---|
Windows x64 |
|
Windows x86 |
|
Linux x64 |
|
macOS |
|
29.4. Lua API¶
29.4.1. Lifecycle & Info¶
- steam.isReady¶
Returns
trueif the Steam client is running and the plugin initialised successfully. Call this first — all other functions returnnil(orfalse) when Steam is not ready.- Returns
boolean
Example:
local steam = require "steam" function onInitScene() if not steam.isReady() then print("Steam not available") return end print("Steam OK, player:", steam.getPlayerName()) end
- steam.getPlayerName¶
Returns the logged-in Steam user’s display name.
- Returns
string
- steam.getAppId¶
Returns the game’s unique Steam App ID.
- Returns
integer
- steam.getCurrentLanguage¶
Returns the user’s game language preference (e.g.
"english").- Returns
string
29.4.2. Achievements¶
- steam.setAchievement(id)¶
Unlocks an achievement and immediately syncs it to Steam (no manual
storeStats()call needed).- Parameters
string – id — achievement API name as defined in the Steamworks partner dashboard (e.g.
"ACH_WIN_FIRST_GAME").- Returns
boolean—trueif the unlock and store succeeded.
Example:
steam.setAchievement("ACH_WIN_FIRST_GAME")
- steam.clearAchievement(id)¶
Clears (locks) an achievement. Intended for testing only.
- Parameters
string – id — achievement API name.
- Returns
boolean—trueif the clear and store succeeded.
- steam.isAchievementAchieved(id)¶
Checks whether an achievement is already unlocked.
- Parameters
string – id — achievement API name.
- Returns
boolean—trueif unlocked.
29.4.3. Stats¶
Note
setStatInt and setStatFloat update the stat locally.
Call steam.storeStats() afterwards to flush all pending changes to the Steam servers.
- steam.setStatInt(name, value)¶
Sets an integer stat locally.
- Parameters
string – name — stat name as defined in the Steamworks partner dashboard.
number – value — integer value to set.
- Returns
boolean—trueif the set call succeeded.
- steam.setStatFloat(name, value)¶
Sets a float stat locally.
- Parameters
string – name — stat name.
number – value — float value to set.
- Returns
boolean—trueif the set call succeeded.
- steam.getStatInt(name)¶
Retrieves a cached integer stat value.
- Parameters
string – name — stat name.
- Returns
integer— cached value (0if not yet set).
- steam.getStatFloat(name)¶
Retrieves a cached float stat value.
- Parameters
string – name — stat name.
- Returns
number— cached value (0.0if not yet set).
- steam.storeStats¶
Flushes all pending stat changes to the Steam servers. Call this after a batch of
setStatInt/setStatFloatcalls.- Returns
boolean—trueif the store call succeeded.
Example:
steam.setStatInt("NumWins", steam.getStatInt("NumWins") + 1) steam.setStatFloat("FarthestDistance", 1234.5) steam.storeStats()
29.4.4. Leaderboards (async)¶
All leaderboard operations are asynchronous. Results are delivered via a Lua callback function;
SteamAPI_RunCallbacks() is called automatically each frame inside onLoop.
- steam.findLeaderboard(name, callback)¶
Asynchronously finds a leaderboard by name.
- Parameters
string – name — leaderboard name as defined in the Steamworks partner dashboard (e.g.
"HighScores").function – callback(handle) — called when the result is ready.
handleis an integer (SteamLeaderboard_tcast to int) on success, ornilon failure.
- Returns
nil
- steam.uploadScore(handle, score[, callback])¶
Uploads a score to a leaderboard using the KeepBest method (only improves the player’s stored score).
- Parameters
number – handle — leaderboard handle returned by the
steam.findLeaderboardcallback.number – score — integer score to submit.
function – callback(success) — (optional) called when the upload finishes;
successis aboolean.
- Returns
nil
- steam.downloadScores(handle, dataType, startRank, endRank, callback)¶
Downloads leaderboard entries asynchronously.
- Parameters
number – handle — leaderboard handle returned by the
steam.findLeaderboardcallback.string – dataType — one of
"global","friends", or"around_user".number – startRank — 1-based rank to start from.
number – endRank — 1-based rank to end at.
function – callback(entries) — called with a table of
{rank, score, name}records, ornilon failure.
- Returns
nil
Example:
steam.findLeaderboard("HighScores", function(handle) if not handle then return end -- upload current score steam.uploadScore(handle, 9999, function(ok) print("Upload succeeded:", ok) end) -- download top-10 global scores steam.downloadScores(handle, "global", 1, 10, function(entries) if entries then for _, e in ipairs(entries) do print(string.format("#%d %s %d", e.rank, e.name, e.score)) end end end) end)
29.4.5. Cloud Storage (Steam Remote Storage)¶
- steam.cloudWrite(filename, data)¶
Writes a file to Steam cloud storage.
- Parameters
string – filename — e.g.
"save.dat".string – data — file contents as a Lua string (may be binary).
- Returns
boolean—trueif the write succeeded.
- steam.cloudRead(filename)¶
Reads a file from Steam cloud storage.
- Parameters
string – filename — e.g.
"save.dat".- Returns
stringon success,nilif the file does not exist.
- steam.cloudDelete(filename)¶
Deletes a file from Steam cloud storage.
- Parameters
string – filename
- Returns
boolean—trueif the delete succeeded.
- steam.cloudFileExists(filename)¶
Checks whether a file exists in Steam cloud storage.
- Parameters
string – filename
- Returns
boolean
- steam.isCloudEnabled¶
Returns
trueonly when both the user’s account setting and the game’s cloud setting are enabled.- Returns
boolean
Example:
if steam.isCloudEnabled() then steam.cloudWrite("save.dat", savegame_data) end
29.4.6. Overlay¶
- steam.activateOverlay(dialog)¶
Opens a built-in Steam overlay dialog.
- Parameters
string – dialog — one of:
"achievements","community","friends","store","stats","leaderboards","officialgamegroup".- Returns
nil
Example:
steam.activateOverlay("achievements")
- steam.activateOverlayURL(url)¶
Opens the Steam overlay with a web page.
- Parameters
string – url — e.g.
"https://steamcommunity.com/games/480".- Returns
nil
- steam.showStore(appId)¶
Opens the Steam store page for the given App ID inside the overlay.
- Parameters
number – appId — Steam App ID.
- Returns
nil
29.4.7. DLC¶
- steam.isDlcInstalled(appId)¶
Checks whether a DLC is currently installed.
- Parameters
number – appId — the DLC’s Steam App ID.
- Returns
boolean—trueif the DLC is installed.
29.5. Full usage example¶
local steam = require "steam"
function onInitScene()
if not steam.isReady() then
print("Steam not available — skipping Steam features")
return
end
-- Player info
print("Player :", steam.getPlayerName())
print("App ID :", steam.getAppId())
print("Language:", steam.getCurrentLanguage())
-- Achievements
steam.setAchievement("ACH_WIN_FIRST_GAME")
print("Achieved:", steam.isAchievementAchieved("ACH_WIN_FIRST_GAME"))
-- Stats
steam.setStatInt("NumWins", steam.getStatInt("NumWins") + 1)
steam.setStatFloat("FarthestDistance", 1234.5)
steam.storeStats()
-- Leaderboards (async)
steam.findLeaderboard("HighScores", function(handle)
if not handle then return end
steam.uploadScore(handle, 9999)
steam.downloadScores(handle, "global", 1, 10, function(entries)
if entries then
for _, e in ipairs(entries) do
print(e.rank, e.name, e.score)
end
end
end)
end)
-- Cloud saves
if steam.isCloudEnabled() then
steam.cloudWrite("save.dat", "my save data")
local data = steam.cloudRead("save.dat")
print("Cloud data:", data)
end
-- Overlay
-- steam.activateOverlay("achievements")
-- DLC
print("DLC installed:", steam.isDlcInstalled(1234567))
end
29.6. Security¶
Warning
Never embed secret keys, server endpoints, or internal API keys in Lua scripts distributed with your game.
Use mini-mbm’s built-in AES encryption (mbm.encrypt / mbm.decrypt) to protect
sensitive scripts before shipping. See the editor/asset_packager.lua tool for details.
The following Steam data is not sensitive and safe to reference in Lua scripts:
App ID (public — visible in Steam URLs)
Achievement / stat API names (defined in the Steamworks partner dashboard)
Leaderboard names (public)
Steam handles user authentication transparently. Players never enter credentials in the game.
steam.isReady() returns false and fails gracefully if the client is not running or the user does not own the game.
29.7. Troubleshooting¶
Symptom |
Likely cause |
|---|---|
|
Steam client not running, or |
Plugin fails to load |
|
Build fails — SDK headers not found |
|
Achievements not appearing in Steam |
Call |
Leaderboard callback never fires |
|