Table of Contents
Publishing on Steam as an indie developer involves more than just uploading a build. You need to configure your Steamworks App, integrate the Steam SDK into your game engine, set up achievements and cloud saves, create store assets, pass through Steam's review process, and manage the release. This walkthrough covers the full journey using Godot 4 as the engine.
Dog Water Development shipped Grave Endeavors through this process using Godot 4 + GodotSteam. The game is available on Steam at store.steampowered.com.
-
1
Create a Steamworks Account & Pay the Fee
Go to partner.steamgames.com, sign in with your Steam account, and pay the $100 app fee. Your account must be in good standing (no recent bans).
-
2
Create a New App
In Steamworks → App Admin → Create New App. Enter your game name. Valve assigns you an AppID — note this down, it's used everywhere in your SDK integration.
-
3
Configure App Details
Under your AppID → General → fill in:
- Default language
- Supported OSes (Windows, Mac, Linux)
- Content descriptors (age ratings, content type)
- Release date (can be "Coming Soon" to start)
-
4
Download the Steamworks SDK
From Steamworks → SDK. Extract it locally. You'll need
sdk/redistributable_bin/andsdk/public/steam/for GodotSteam.
GodotSteam is the community-maintained Steamworks binding for Godot. The recommended approach for Godot 4 is to use the pre-compiled GodotSteam editor binary — it requires no compilation and includes all Steam API bindings as built-in nodes.
-
1
Download GodotSteam Editor
From the GodotSteam GitHub releases, download the pre-compiled Godot editor build matching your Godot 4 version. This replaces your standard Godot editor — open your project with it instead.
-
2
Place the steam_appid.txt File
Create a file named
steam_appid.txtin the same directory as the GodotSteam editor executable. Its contents should be just your AppID number on a single line:1234560This is required during development so Steam knows which app to initialize. Remove or update it before shipping.
-
3
Initialize Steam in Your Game
In your main scene or autoload singleton:
extends Node func _ready() -> void: var init = Steam.steamInit() if init["status"] != 1: push_error("Steam init failed: " + str(init)) return print("Steam initialized. AppID: " + str(Steam.getAppID())) -
4
Call Steam.runCallbacks() Every Frame
func _process(_delta: float) -> void: Steam.runCallbacks()Without this, achievements, stats, and overlay events won't fire.
Steam.steamInit() will fail and the game will close immediately.-
1
Define Achievements in Steamworks
Steamworks → App Admin → Stats & Achievements. Add achievements with an API name (e.g.
ACH_FIRST_KILL), display name, description, and icon (64×64 and 32×32 PNG). Publish the changes — they take a few minutes to propagate. -
2
Unlock Achievements in GDScript
func unlock_achievement(api_name: String) -> void: if Steam.getAchievement(api_name)["achieved"]: return # already unlocked Steam.setAchievement(api_name) Steam.storeStats() # must call storeStats() to persist -
3
Reset Achievements During Testing
Steam.resetAllStats(true) # true = also reset achievements
-
1
Create Leaderboard in Steamworks
Steamworks → App Admin → Stats & Achievements → Leaderboards. Add a leaderboard with a unique name, sort order (ascending/descending), and display type (numeric or time). Publish.
-
2
Find & Submit Score in GDScript
var leaderboard_handle: int = 0 func _ready() -> void: Steam.leaderboard_find_result.connect(_on_leaderboard_found) Steam.findLeaderboard("HighScores") func _on_leaderboard_found(handle: int, found: int) -> void: if found == 1: leaderboard_handle = handle func submit_score(score: int) -> void: if leaderboard_handle == 0: return Steam.uploadLeaderboardScore(score, Steam.LEADERBOARD_UPLOAD_METHOD_KEEP_BEST, leaderboard_handle)
Steam distributes builds through SteamPipe — a content delivery system with depot-based versioning. You upload depots (file sets) and assign them to branches (default, beta, etc.).
-
1
Export Your Godot Build
In Godot → Project → Export. Create a Windows Desktop (and/or Linux/Mac) preset. Point the export path to a local
builds/windows/folder. Make sure to use the GodotSteam export template (not the standard Godot one) — download the matching GodotSteam export templates from the same release page as the editor. -
2
Set Up SteamPipe VDF Files
Create a
steamcmd/folder with two VDF files:app_build.vdf
"appbuild" { "appid" "1234560" "desc" "v1.0.0 release" "buildoutput" "../output/" "contentroot" "../builds/" "setlive" "default" "depots" { "1234561" "depot_build_windows.vdf" } }depot_build_windows.vdf
"DepotBuildConfig" { "DepotID" "1234561" "ContentRoot" "windows/" "FileMapping" { "LocalPath" "*" "DepotPath" "." "recursive" "1" } } -
3
Upload with SteamCMD
steamcmd +login your_username +run_app_build app_build.vdf +quitSteamCMD will upload changed files only (delta uploads). New build appears in Steamworks → Build History.
Your store page is your game's landing page on Steam. It needs to be complete and approved before you can go live. Required assets:
| Asset | Size / Format |
|---|---|
| Capsule (main) | 616×353 px, JPG/PNG |
| Capsule (small) | 231×87 px, JPG/PNG |
| Library header | 460×215 px |
| Screenshots | Min 5, max 20, 1280×720 minimum |
| Trailer | H.264 MP4, recommended 1920×1080 |
| Short description | Max 300 characters |
- ☐ Store page approved by Valve
- ☐ Build uploaded to default branch and tested via Steam client
- ☐ Achievements visible in Steam overlay in-game
- ☐ Cloud saves working (if configured)
- ☐ Pricing set in all target regions
- ☐ Release date set (or launch immediately)
- ☐ Trailer and screenshots uploaded and ordered
- ☐ Tags selected (up to 20 — choose carefully for visibility)
- ☐ System requirements filled in
- Monitor Steam Reviews — respond professionally, even to negative ones
- Watch the Steam Discussion board for bug reports
- Use Steamworks → Sales & Activations for revenue and unit data
- Schedule a launch discount (15–25%) to improve visibility in New Releases
- Participate in Steam sales events (Summer Sale, Winter Sale) — Valve invites you once you're live
- Ship updates frequently early on — Steam's algorithm rewards active games