Export your game for Steam and upload it to your own Steamworks app — App ID, depots, branches and updates.
Publishing on Steam
You can sell or give away the game you built on Steam, under your own Steamworks account. You are the publisher: Valve pays you, the store page is yours, and ED5 is never in the middle. The studio's part is to hand you a build Steam can install and the scripts that upload it.
Steam is not a separate export target. It is a way of delivering the Windows, macOS and Linux exports you already have: instead of an installer, you get the game exactly as Steam will install it. It is available on every licence tier.
Before you start
You do these once, on Valve's side:
1. Join Steamworks at partner.steamgames.com and pay Valve's app fee for your game. That gives you an App ID.
2. In Steamworks, open your app → SteamPipe → Depots. Create one depot per operating system you plan to ship, and set each depot's operating system. Note each Depot ID.
3. In Installation → General, add a launch option per operating system pointing at the game's executable. Export once first (below) and look in the exported folder for the exact file name — on Windows it is your game's name followed by .exe.
4. Install steamcmd. It ships inside the Steamworks SDK under tools/ContentBuilder/builder, or you can install it on its own. Make sure steamcmd runs from a terminal.
Where to author it
Build → Export Game → Build tab → pick Windows, macOS or Linux → tick Build for Steam.
Set it up
1. Open Build → Export Game and choose the desktop platform you are shipping.
2. Tick Build for Steam. Three fields and one option appear underneath.
3. Enter your Steam App ID and the Depot ID for the platform you picked. Switch platform to enter the other depots — each operating system has its own.
4. Leave Set live on branch as beta for your first uploads (see the gotchas for why).
5. Pick your Production profile and click Build. Pre-flight stops you here if an id is missing or two platforms share a depot.
6. When the build finishes, open the export folder, go into steam, and run upload.cmd (Windows) or upload.sh (macOS / Linux). Type your Steamworks build account name; steamcmd asks for the password and Steam Guard code itself.
7. In Steamworks → SteamPipe → Builds, your build is live on beta. Test it from your Steam library, then set it live on default when you are happy.
The fields
| Field | What it does |
|---|---|
| Build for Steam | Switches this desktop export from an installer to a Steam build. Untick it to go back to a normal installer — your ids are kept. |
| Steam App ID | The number Steamworks gave your game. It is also the number in your store page's URL. |
| Depot ID | The depot this platform uploads into. One per operating system; the field shows the depot for whichever platform is selected. A new app's first depot is usually its App ID plus one. |
| Set live on branch | The Steam branch a finished upload goes live on. Use a testing branch such as beta. Enter default to upload without going live anywhere. |
| Skip the launcher screen | Pressing Play in Steam goes straight into your game instead of stopping on your launcher. Players still see your terms the first time, and a required game update still finishes first. They will not see your launcher's news, carousel or links — leave this off if you rely on them. |
| Upload to Steam when the build finishes | Studio plan or above. Runs the upload for you as the last step of the export, using steamcmd's own saved sign-in. |
| Steam build account | The account name you upload builds with. Only shown when upload is on. Your password is never asked for or stored. |
| Steam overlay (experimental) | Lets Shift+Tab open the Steam overlay on top of your game. Off by default: it changes how the game talks to the graphics card, so play-test a build with it on before you ship it. |
What the export produces
win-unpacked/ the game, exactly as Steam will install it
steam/
app_build_<appid>.vdf which depots this upload carries
depot_build_<depot>.vdf one per operating system built so far
upload.cmd, upload.sh the one command you run
output/ steamcmd's own logsExport Windows and then Linux for the same game version, and the upload carries both in one build. Change the version (or the App ID) and the set starts fresh, so last month's Linux build can never ride along with today's Windows one.
One-click upload
On the Studio plan or above, the export can finish by uploading the build for you.
1. Build for Steam once and run upload.cmd / upload.sh yourself. Sign in when steamcmd asks — this is the one time you type your password, and it is steamcmd that remembers it, not the studio.
2. Back in Build → Export Game, tick Upload to Steam when the build finishes and enter your Steam build account name.
3. Build. The log ends with Uploaded to Steam, and the build is live on your testing branch.
Gotchas:
- If steamcmd has no saved sign-in, the upload stops at once and the log tells you to run the upload script once. It never waits at a hidden password prompt.
- A failed upload does not fail the export. Your build is complete either way, and the upload script in the
steamfolder still works. - Steam Guard may ask for a code again after some weeks; run the upload script once more to refresh the sign-in.
- On a lower plan the log says which plan one-click upload needs, and everything else works as before.
Updating your game on Steam
Most changes never need a new upload. Your world is served by your game server, and the game client keeps itself current — exactly as described in Desktop, Web & Mobile Exports. You only upload again when the desktop app itself changes (a new studio version, a new icon, a new name):
1. Raise Game version in Config. 2. Export with Build for Steam still ticked. 3. Run the upload script again. Steam sends players only the files that changed.
Steam sign-in
A player who launched your game from Steam is already signed in to Steam — so they should not have to make another account. With Steam sign-in set up, your Steam build signs them in automatically the first time it opens, and shows a Continue with Steam button after that. Available on every licence tier.
Where to author it: Settings → Auth in the studio (the two Steam fields), and World → Features → Steam Sign-In.
1. In Steamworks, open Users & Permissions → Manage Groups, pick (or create) a group that contains your game, and create a Web API key for it. This is a publisher key — a personal key from your Steam profile will not work. 2. In the studio, open Settings → Auth and fill in Steam App ID and Steam Web API Key. Save. 3. Make sure World → Features → Steam Sign-In is on (it is by default). 4. Publish, so your game server picks up the settings. 5. Export with Build for Steam, upload, and launch the game from your Steam library. You land on character select without ever seeing a login form.
| Field | What it does |
|---|---|
| Steam App ID | Your game's App ID — the same number you entered in Build for Steam. |
| Steam Web API Key | Your publisher Web API key. Stored as a secret on your game server and only ever sent to Valve, to check that a sign-in is genuine. It is never sent to players and never appears in an export. |
How it behaves:
- It sits alongside your other sign-in methods. Email accounts, social sign-in and guests all keep working; Steam is one more way in, whichever auth setup your game uses.
- One Steam account, one game account. The same Steam player always gets the same characters, on any machine. A player using Steam Family Sharing gets their own account, not the library owner's.
- Bans still apply. A Steam player you ban in the studio is refused exactly like any other account, and a player Valve has publisher-banned from your game cannot sign in.
- Signing out works. After signing out, the player sees your normal login screen with a Continue with Steam button, so they can choose a different account.
- It only appears inside a Steam build, with Steam running. Browser players, your normal installers, and a Steam build started while Steam is closed all see your usual login screen.
- Your server needs a session secret. If Settings → Auth has neither a JWT Secret nor a Supabase JWT secret, the server has nothing to sign a session with and Steam sign-in stays off. Set JWT Secret (fallback) to a long random value.
- A Steam account and an email account are separate accounts unless the player links them (below).
Linking an existing account to Steam
A player who already has an email account in your game can attach their Steam account to it, so your Steam build opens that account — with all its characters — instead of a new Steam-only one.
1. They open your Steam build and, on the login screen, tick Link this account to my Steam account. 2. They sign in with their email and password as usual. 3. From then on, Steam signs them straight into that account, in the Steam build and in the browser.
Gotchas:
- The option only appears in a Steam build, with Steam running, when your game has email sign-in.
- A Steam account that already has characters cannot be linked. Linking would leave those characters unreachable, and accounts are never merged — so the player is told, and nothing changes. Link before playing on the Steam-only account.
- One to one. A Steam account links to one game account, and a game account to one Steam account.
- The sign-in still succeeds if linking is refused; the player is told why Steam was not linked.
- Needs your game server updated to the release that includes it (it adds one small table).
Steam sign-in in the browser
Steam players can reach the same account from your web version. Your browser login screen gets a Sign in through Steam button: it sends the player to Steam's own sign-in page and brings them back signed in, with the same characters they have in the Steam build.
1. Set up Steam sign-in (above).
2. In Settings → Server, fill in Game Server Public URL — the https:// address players' browsers reach your game server on, for example https://game.yourgame.com.
3. Make sure Client URL in the same section is your web client's address. Players are only ever sent back there.
4. Publish.
| Field | What it does |
|---|---|
| Game Server Public URL | Your game server's public https address. Steam sends the player back to it, and your server checks the answer was meant for exactly this address. Leave it blank to keep browser Steam sign-in off. |
Gotchas:
- It must be
https, except on your own machine. A sign-in is never sent in clear text. - The button does not appear until the URL is set. Your server will not guess its own address — doing so would let a sign-in a player approved for some other site be replayed against your game.
- Players are only sent back to your Client URL. A sign-in link pointing anywhere else is refused.
- "This sign-in link has expired" — the player took longer than ten minutes on Steam's page. They just try again.
- "Steam sign-in is unavailable right now" means your server could not reach Valve, or Valve refused your Web API key. Check the key belongs to a group that includes this App ID; the exact reason is in your game server's log.
Selling for real money: Steam Wallet
Valve requires purchases made inside a game on Steam to go through the player's Steam Wallet. So a Steam build never offers card or PayPal checkout. With Steam Wallet set up, your Item Shop's USD prices get a Pay with Steam Wallet button instead; without it, a Steam build simply shows gold prices only. Studio plan or above.
Where to author it: Settings → Payments in the studio, and World → Features → Steam Wallet Checkout.
1. Set up Steam sign-in first (above). A player can only pay with a Steam Wallet on an account that signed in with Steam. 2. In Steamworks, make sure your app has microtransactions enabled and your bank and tax details are complete. 3. In Settings → Payments, turn on Steam Wallet Checkout. Leave Steam Wallet Sandbox on. 4. Publish, export a Steam build, and buy something. In the sandbox the whole flow runs — Steam's approval page, delivery to the bag — but no real money moves. 5. When you are ready to take real payments, turn Steam Wallet Sandbox off and publish again.
| Field | What it does |
|---|---|
| Steam Wallet Checkout | Turns Steam Wallet purchases on for your Steam build. Uses the Steam App ID and Web API Key from Settings → Auth. |
| Steam Wallet Sandbox | On = Valve's test environment, no real money. Off = live payments. Anything other than a clear "off" is treated as on, so a slip can never start charging players. |
| Steam Wallet Currency Rates | Optional regional pricing. A list of CODE=units per US dollar, separated by commas: EUR=0.92, GBP=0.79, BRL=5.20, JPY=150. A player whose Steam Wallet is in a listed currency pays your USD price times that rate, in their own currency. Blank = everyone pays in US dollars. |
How a purchase works: the player clicks Pay with Steam Wallet, Steam's own page opens in their browser, they approve, and when they come back to the game the purchase is confirmed and delivered — to the bag, or by mail if the bag is full. Your game server only hands the item over after Valve confirms the player approved; nothing the game client says can make it deliver.
Gotchas:
- Prices are charged in US dollars unless you list currency rates. You choose the rates, so you decide the regional price — they are not live exchange rates and do not update by themselves. A player whose wallet currency you did not list pays in US dollars, and so does everyone if Steam cannot tell your server the player's currency; a sale is never blocked over it.
- Small-unit currencies are charged in whole units. Where one unit is worth under five US cents (yen, won, rupees, roubles…), the price is rounded to a whole number — ¥749, never ¥748.50.
- Your shop records stay in US dollars, the price you set. The amount actually charged in a local currency is in your Steamworks sales reports.
- An account Valve has locked cannot buy. With currency rates on, your server asks Valve about the buyer first, and a locked account is told it cannot make purchases right now.
- A player who did not sign in with Steam sees "Sign in with Steam to pay with your Steam Wallet." Email and guest accounts in a Steam build can still buy with gold.
- Gold is sold through the Steam Wallet too. With Steam Wallet on, the Buy Gold tab works in your Steam build with a Pay with Steam Wallet button, and your daily purchase limit applies exactly as it does to card payments. With Steam Wallet off, the tab is hidden in a Steam build.
- On a lower plan the two settings refuse to save, with a message saying which plan is needed. Publishing on Steam and Steam sign-in are included in every plan.
- Refunds are handled in Steamworks, and your game server follows them. Steam does not notify your server, so it checks Valve's sales report about every half hour (and looks a month back whenever it restarts). When a gold purchase was refunded or charged back, the gold is taken back from the account — as much of it as is still there, never below zero — and a player who is online is told. When an item purchase was refunded, the order is marked refunded in your shop records and the item stays with the player, exactly as with card payments.
- Refunds are still followed after you turn Steam Wallet Checkout off, for as long as your server has Steam Wallet sales on record and the Steam App ID and Web API Key stay filled in. A server that never sold anything through Steam never asks Valve.
Selling DLC on Steam
Sell extra content as DLC on your Steam store page, and players who own it simply have it in game. There is no checkout inside your game: Steam sells the DLC, and your game server hands over the content. Studio plan or above.
Where to author it: Database → Economy → Item Shop → Products, the Steam DLC section of the product form.
1. In Steamworks, create the DLC for your game and note its App ID. 2. Set up Steam sign-in (above) — your server uses the same App ID and Web API Key to check ownership. 3. In the studio, create an Item Shop product, add the items the DLC should give, and enter the DLC's App ID under Steam DLC App ID. It needs no price. 4. Set the product Active and publish. 5. A player who owns the DLC gets the items the next time they enter your world — in their bag, or by mail if it is full.
| Field | What it does |
|---|---|
| Steam DLC App ID | The App ID of the DLC in Steamworks. Makes this product the in-game side of that DLC. Leave blank for a normal product. |
Gotchas:
- A DLC product is never listed in the Item Shop. It is something players already own, not something on sale, so it needs no price.
- It is given once per account, however many times the player logs in or on how many machines — and once per Steam account, so linking the same Steam account to a second game account does not give the content again.
- Steam accounts only. Ownership is checked for the account the player signed in to with Steam.
- Family Sharing does not count. Only the account that actually owns the DLC gets the content, because what is given is permanent and a loan is not.
- A refund on Steam takes the items back. Steam does not announce refunds, so your server re-checks a player's DLC when they log in (at most every few hours). If they no longer own it, whatever is still in their bag is removed, the order is marked refunded in your shop records, and they are told why. Items already used, traded, banked or still in the mail are not chased. If they buy the DLC again, it is delivered again.
- If Steam cannot be reached, nothing is given and nothing is recorded — the check simply runs again at the player's next login.
- On a lower plan, saving a product with a Steam DLC App ID is refused with a message saying which plan is needed.
Steam achievements and rich presence
Your game's achievements can unlock on Steam too, and a player's Steam friends can see where they are in your world. Studio plan or above.
Where to author it: Settings → Integrations → Steam Achievements & Rich Presence, plus your achievements in Database → Achievements and their twins in Steamworks.
1. Turn on Steam Achievements & Rich Presence in Settings → Integrations, and publish.
2. For each achievement you want on Steam, open it in Database → Achievements and note its ID.
3. In Steamworks → Stats & Achievements, create an achievement whose API Name is that ID, with any character that is not a letter, digit or underscore replaced by an underscore. So first-blood becomes first_blood. Add its name, description and icons there, and publish the Steamworks change.
4. Export a Steam build. From then on, earning the achievement in game unlocks it on Steam at the same moment.
5. Optional — progress bars. For an achievement that counts towards a total ("Defeat 100 enemies"), create a Steam stat in Steamworks → Stats & Achievements → Stats: type INT, API Name = the achievement's API Name followed by _PROGRESS (so kill_100_PROGRESS), default 0. Then edit the Steam achievement and set that stat as its Progress Stat, with a max equal to the achievement's required count. Steam now shows "37 / 100" on the achievement.
| What | How it works |
|---|---|
| Which achievements are mirrored | Every one that has a Steam achievement with the matching API Name. Ones with no twin on Steam are simply skipped. |
| Progress (Steam stats) | Each achievement's progress is written to the Steam stat named <API Name>_PROGRESS, if you made one. It only ever goes up. |
| Catching up | Whenever a player opens your Steam build, Steam is brought up to date with everything they earned elsewhere — in the browser, or on another machine. |
| Rich presence | Steam friends see In <map name> beside the player, updated as they move between maps. Steam clears it when they quit the game. |
| Who decides | Your game server. The game client only mirrors an unlock your server actually granted. |
Gotchas:
- The API Name has to match exactly, including capital letters. A mismatch is not an error anywhere — the Steam achievement just never unlocks.
- Only in a Steam build, with Steam running. Browser players and normal installers are unaffected.
- Already-earned achievements catch up by themselves. The next time the player opens your Steam build, anything they earned before you turned this on — or earned in the browser — unlocks on Steam too.
- Steam progress belongs to the Steam account; your achievements belong to a character. A player with two characters sees the higher of the two on Steam, and it never goes back down.
- A stat you have not made in Steamworks is skipped, exactly like an achievement with no twin. Stats are optional.
- To show it in the friends list itself, upload one file, once. Every Steam export writes
steam/rich_presence.vdf. In Steamworks open Community → Rich Presence, upload that file, and publish. Until you do, the status still shows under a friend's View Game Info, just not beside their name.
What is different inside a Steam build
- Steam delivers updates. The game's own updater is switched off and the launcher's Check for Updates button is hidden. Any Update URL on the profile is ignored, and pre-flight tells you so.
- No installer, no code-signing prompt. Steam installs the folder directly, so the Windows SmartScreen advice does not apply and is not shown.
- It carries the Steam connection. A Steam build includes the small native library that talks to the Steam client; your normal installers do not, so they stay the size they were. If a player starts the game while Steam is closed, the game still runs — Steam features are simply off for that session.
- Everything else is the same game. The same launcher, the same bundled client, the same server profile. Run the game server on the player's machine works in a Steam build too.
Gotchas
- Steam will not let an upload publish itself to
default. That is Valve's rule, not a setting. Uploads go live on a testing branch automatically; promoting a build to everyone is always a button you press in Steamworks → Builds. - One depot per operating system. Two platforms pointed at the same Depot ID are refused at pre-flight — one would silently replace the other.
- The Depot ID is not the App ID. Pre-flight warns if they match.
- macOS builds still need a Mac, exactly like the normal macOS export.
- A signed macOS Steam build is set up for Steam automatically. Apple's hardened runtime (required for notarization) would otherwise refuse Steam's overlay and Steam library, because Valve signs them rather than you. A macOS Steam export carries the two permissions Valve asks Steam games to have; your normal macOS export does not.
- Your Steam password is never stored. The upload script asks for the account name only, and steamcmd prompts for the rest. Use a dedicated Steamworks build account rather than your personal login.
- Never add
steam_appid.txtto the exported folder. It is a developer file that lets the game start without Steam; the upload excludes it if it is there. - Card and PayPal checkout are never offered inside a Steam build. Valve requires purchases made inside a game on Steam to go through the Steam Wallet. With Steam Wallet set up (above) your USD prices — and the Buy Gold tab — get a Steam Wallet button; without it the Item Shop shows gold prices only, products that can only be bought with money are not listed, and the Buy Gold tab is hidden. Buying with in-game gold works exactly as before, and none of this changes for your browser players or your normal installers.
- A Linux build that will not start from Steam usually needs
--no-sandboxadded to that depot's launch option arguments in Steamworks. Steam does not keep the file permissions Chromium's sandbox needs. - There is no feature flag for this. It is a build option, off until you tick it, and it changes nothing about how your game runs anywhere else.