Home / Walkthroughs / Steam Publishing
 Game Development

Shipping Your First Game on Steam
with Godot 4 & GodotSteam

End-to-end walkthrough of publishing an indie game on Steam — from Steamworks App setup and Godot GDNative integration through achievements, leaderboards, build pipeline, store page creation, and release day checklist. Based on real experience shipping Grave Endeavors with Dog Water Development.

Intermediate ~2–3 hours setup Steamworks SDK required
Godot 4 GodotSteam Steamworks GDScript Steam SDK CI/CD
📖
Overview

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.

One-time cost: Valve charges a $100 USD app fee per game on Steam. This is recouped once your game earns $1,000 in revenue. Budget this into your launch plan — it's non-refundable regardless of sales.

Dog Water Development shipped Grave Endeavors through this process using Godot 4 + GodotSteam. The game is available on Steam at store.steampowered.com.

⚙️
Steamworks App Setup
  1. 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. 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. 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. 4

    Download the Steamworks SDK

    From Steamworks → SDK. Extract it locally. You'll need sdk/redistributable_bin/ and sdk/public/steam/ for GodotSteam.

🎮
GodotSteam Integration

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. 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. 2

    Place the steam_appid.txt File

    Create a file named steam_appid.txt in the same directory as the GodotSteam editor executable. Its contents should be just your AppID number on a single line:

    1234560

    This is required during development so Steam knows which app to initialize. Remove or update it before shipping.

  3. 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. 4

    Call Steam.runCallbacks() Every Frame

    func _process(_delta: float) -> void: Steam.runCallbacks()

    Without this, achievements, stats, and overlay events won't fire.

Steam must be running on the developer's machine when launching through the GodotSteam editor. If Steam isn't open, Steam.steamInit() will fail and the game will close immediately.
🏆
Achievements & Stats
  1. 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. 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. 3

    Reset Achievements During Testing

    Steam.resetAllStats(true) # true = also reset achievements
📊
Leaderboards
  1. 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. 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)
🔧
Build Pipeline

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. 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. 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. 3

    Upload with SteamCMD

    steamcmd +login your_username +run_app_build app_build.vdf +quit

    SteamCMD will upload changed files only (delta uploads). New build appears in Steamworks → Build History.

🛒
Store Page & Assets

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
Valve reviews your store page before it can go public. Submit early — review can take 3–5 business days. You can make edits after approval, but major changes may require re-review.
Release Checklist
  • 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
🚀
Post-Launch
  • 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
Dog Water Development shipped Grave Endeavors through this exact process. Check it out on the Dog Water Dev Steam page.