Publicar Jogo Unity na Steam: Steamworks e Build

Como publicar jogo Unity na Steam: Steamworks.NET ou Facepunch, steam_appid.txt, conquistas em C#, build Windows e upload com SteamPipe e SteamCMD.
Publicar Jogo Unity na Steam: Steamworks e Build
Para publicar jogo Unity na Steam você precisa de três peças separadas: pagar o Steam Direct e configurar o app no Steamworks, integrar a API da Steam no projeto Unity (por Steamworks.NET ou Facepunch.Steamworks), e enviar a build Windows pelo SteamPipe. A Unity cuida só da build; conquistas, overlay e upload são do Steamworks.
Separar o que é de quem evita a maior parte da confusão. Este post mostra o caminho completo com código C# que compila no Unity 6.3 LTS, os arquivos de script do SteamPipe e os erros de SteamAPI_Init com a causa de cada um.
Publicar jogo Unity na Steam: Steam Direct, Steamworks e build
A sequência real:
- Conta no Steamworks (partner.steamgames.com), com dados fiscais e bancários. A verificação leva alguns dias.
- Steam Direct: US$ 100 por jogo, segundo a documentação do Steamworks consultada em outubro de 2026. Não é reembolsável, mas é devolvido no pagamento seguinte depois que o jogo passa de US$ 1.000 de receita bruta ajustada. Os detalhes estão no post sobre a taxa de 100 dólares do Steam Direct.
- Pago o Steam Direct, você recebe um AppID (ex.: 1234560) e um Depot ID (normalmente AppID + 1).
- Integração no Unity usando esse AppID.
- Build e upload pelo SteamPipe.
- Página da loja, revisão da Valve e lançamento.
A parte de página, revisão e prazos está no guia de como publicar jogo na Steam. Aqui o foco é a ligação Unity e Steam.
Steamworks.NET vs Facepunch.Steamworks
As duas são bibliotecas C# gratuitas que chamam a steam_api64.dll da Valve.
Steamworks.NET: espelha a API oficial quase função por função (SteamUserStats.SetAchievement, SteamFriends.ActivateGameOverlay). Vantagem: a documentação da Valve vale direto, e qualquer exemplo em C++ se traduz fácil. A versão mais recente no GitHub do projeto, conferida em outubro de 2026, é a 2025.164.1, baseada no SDK 1.64 do Steamworks. Instala pelo Package Manager com URL Git.
Facepunch.Steamworks: API reescrita no estilo C# (SteamUserStats.SetAchievement vira new Achievement("ID").Trigger(), com async e eventos). Mais agradável de ler, linha 2.x, e as notas de versão citam correções específicas para IL2CPP. Funciona na Unity com a pasta de plugins incluída no release.
Para um primeiro jogo, use Steamworks.NET: há mais material e a ponte com a documentação oficial é direta. É o que o resto do post usa. Se você também usa Godot, o equivalente é o GodotSteam, explicado em integrar Steam no Godot.
O que é da Unity e o que é do Steamworks
Quando algo dá errado, a primeira pergunta é de quem é o problema. A divisão:
| Tarefa | Onde se resolve |
|---|---|
Gerar o .exe, a pasta _Data e as DLLs | Unity (Build Profiles) |
| Chamar a API da Steam no código | Biblioteca C# (Steamworks.NET) |
| Criar conquistas, estatísticas e Steam Cloud | Painel do Steamworks |
Definir qual .exe abre ao clicar em Jogar | Steamworks, em Installation > General |
| Enviar arquivos e escolher a build ativa | SteamPipe |
| Página, preço, revisão e data de lançamento | Painel do Steamworks |
Repare na quarta linha: se o jogador clica em Jogar e nada acontece, o problema costuma ser a Launch Option apontando para um nome de executável diferente do que a Unity gerou. Isso se corrige no painel, sem nova build. Do mesmo jeito, conquista que não aparece raramente é bug de código: quase sempre falta publicar a alteração no painel.
Integrar a Steam na Unity: inicialização e AppID
Instalar
- Window > Package Management > Package Manager, botão +, Install package from git URL.
- Cole
https://github.com/rlabrecque/Steamworks.NET.git?path=/com.rlabrecque.steamworks.net#2025.164.1. - Na raiz do projeto (ao lado da pasta
Assets, não dentro), criesteam_appid.txtcontendo só o seu AppID. Antes de ter AppID próprio, a Valve oferece o 480 (Spacewar) para testes.
O steam_appid.txt diz à API qual jogo você é quando roda fora da Steam (no editor ou numa build aberta direto). Ele não vai para o jogador.
Script de inicialização
Arquivo SteamBootstrap.cs, num objeto da primeira cena:
using Steamworks;
using UnityEngine;
public class SteamBootstrap : MonoBehaviour
{
[SerializeField] private uint appId = 480;
public static bool Initialized { get; private set; }
private static SteamBootstrap instance;
private void Awake()
{
if (instance != null)
{
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
#if !UNITY_EDITOR
if (SteamAPI.RestartAppIfNecessary(new AppId_t(appId)))
{
Application.Quit();
return;
}
#endif
ESteamAPIInitResult result = SteamAPI.InitEx(out string errorMessage);
Initialized = result == ESteamAPIInitResult.k_ESteamAPIInitResult_OK;
if (!Initialized)
{
Debug.LogError("SteamAPI_Init falhou: " + result + " " + errorMessage);
}
}
private void Update()
{
if (Initialized)
{
SteamAPI.RunCallbacks();
}
}
private void OnApplicationQuit()
{
if (Initialized)
{
SteamAPI.Shutdown();
Initialized = false;
}
}
}
O que cada parte faz:
RestartAppIfNecessary: se o jogador abriu o.exedireto, sem a Steam, a função relança pelo cliente Steam e você fecha esta instância. Fica fora do editor para não fechar o Play Mode.InitEx: conecta ao cliente Steam e devolve um resultado com mensagem. É melhor que oInit()antigo porque diz por que falhou.RunCallbacksem todo frame: sem ele, nenhum evento da Steam chega ao jogo (overlay, conquistas, estatísticas).Shutdownao sair.
Conquistas e overlay
Conquistas são criadas no Steamworks, em App Admin > Stats & Achievements: você define o API Name (ex.: ACH_PRIMEIRA_FASE), nome, descrição e ícones. Depois de salvar, clique em Publish nas alterações do app, senão elas não existem para a API.
No jogo, arquivo SteamAchievements.cs:
using Steamworks;
using UnityEngine;
public class SteamAchievements : MonoBehaviour
{
private Callback<GameOverlayActivated_t> overlayCallback;
private void OnEnable()
{
if (SteamBootstrap.Initialized)
{
overlayCallback = Callback<GameOverlayActivated_t>.Create(OnOverlayChanged);
}
}
public void Unlock(string apiName)
{
if (!SteamBootstrap.Initialized)
{
return;
}
if (SteamUserStats.GetAchievement(apiName, out bool alreadyUnlocked) && alreadyUnlocked)
{
return;
}
SteamUserStats.SetAchievement(apiName);
SteamUserStats.StoreStats();
}
private void OnOverlayChanged(GameOverlayActivated_t data)
{
bool overlayOpen = data.m_bActive != 0;
Time.timeScale = overlayOpen ? 0f : 1f;
}
}
SetAchievement marca localmente; StoreStats envia ao servidor e mostra a notificação. O callback do overlay pausa o jogo quando o jogador abre o overlay com Shift+Tab, o que a Valve recomenda e os jogadores esperam. Para testar de novo uma conquista, use SteamUserStats.ClearAchievement(apiName) numa build de desenvolvimento.
Integrar Steam é uma tarde de trabalho. O que leva meses é ter um jogo que justifique a página: progressão, menus, opções de vídeo e controle, salvamento confiável e um loop que segura o jogador por horas. É essa construção de jogo completo, e não a API, que costuma travar quem aprende sozinho.
Build Windows pronta para a Steam
- File > Build Profiles > Windows. Architecture: x86_64 (Intel 64-bit).
- Desmarque Development Build para a versão de loja.
- Project Settings > Player: nome da empresa, nome do produto, ícone, e em Resolution and Presentation o modo de tela padrão (Fullscreen Window costuma ser a escolha segura).
- Clique em Build e escolha uma pasta como
SteamBuild/content.
Confira na pasta gerada:
steam_api64.dllprecisa estar na pastaNomeDoJogo_Data/Plugins/x86_64. Sem ela,SteamAPI_Initfalha só na build.- Não coloque o
steam_appid.txtaqui. - Apague as pastas
*_BurstDebugInformation_DoNotShipe*_BackUpThisFolder_ButDontShipItInYourBuildse existirem, ou exclua no script do SteamPipe (abaixo).
Upload com SteamPipe (ContentBuilder ou SteamCMD)
Baixe o Steamworks SDK no site de parceiros e abra sdk/tools/ContentBuilder. A estrutura é content/ (seus arquivos), output/ (logs) e scripts/ (configuração).
Crie scripts/app_build_1234560.vdf, trocando os IDs pelos seus:
"AppBuild"
{
"AppID" "1234560"
"Desc" "Build 0.1.0"
"ContentRoot" "..\content\"
"BuildOutput" "..\output\"
"Depots"
{
"1234561"
{
"FileMapping"
{
"LocalPath" "*"
"DepotPath" "."
"recursive" "1"
}
"FileExclusion" "*_DoNotShip*"
"FileExclusion" "*_ButDontShipItInYourBuild*"
}
}
}
Copie a build da Unity para ContentBuilder/content e rode, de dentro de ContentBuilder:
builder\steamcmd.exe +login SEU_USUARIO +run_app_build ..\scripts\app_build_1234560.vdf +quit
Na primeira vez o SteamCMD pede o código do Steam Guard. Use uma conta dedicada a builds, com permissão só de upload no Steamworks, em vez da sua conta principal. O SDK também traz o SteamPipeGUI, uma ferramenta só para Windows que gera esses arquivos por interface, mas o formato de script vale a pena aprender porque é o que você vai automatizar depois.
Terminado o upload, a build aparece em Steamworks > App Admin > SteamPipe > Builds. Ali você escolhe em qual branch (default é o que o público baixa) ela fica ativa.
Testar como jogador antes do lançamento
- Coloque a build num branch privado (ex.:
betacom senha) e instale pela sua biblioteca Steam. - Peça chaves de desenvolvedor em Steamworks e mande para dois ou três testadores.
- Teste: abrir pelo cliente, abrir pelo
.exe(tem que relançar pela Steam), conquista desbloqueando, overlay pausando, Steam Cloud se usar, desinstalar e reinstalar. - Nas propriedades do jogo na biblioteca, use Arquivos instalados > Verificar integridade dos arquivos para conferir que nada do depot falta.
Se você tem acesso a um Steam Deck, rode a build Windows nele também: a Steam executa pela camada de compatibilidade Proton sem você gerar build Linux. Teste controle (o jogo precisa funcionar sem mouse), texto legível na tela pequena e o teclado virtual em campos de nome. Isso pesa na avaliação de compatibilidade que a Valve exibe na loja.
Erros comuns: SteamAPI_Init falhando
NoSteamClient: o cliente Steam não está aberto, ou está aberto com outra conta de usuário do Windows.- Falha genérica no editor: falta
steam_appid.txtna raiz do projeto, ou a conta logada não tem o jogo (ou o 480) na biblioteca. - Funciona no editor, falha na build:
steam_api64.dllnão foi copiada para a pasta de plugins, ou a arquitetura da build não é x86_64. VersionMismatch: cliente Steam desatualizado. Atualize e reinicie.- Conquista não aparece: não publicou as mudanças no Steamworks, API Name digitado diferente, ou esqueceu o
StoreStats. - "Tried to initialize twice" ou comportamento estranho ao trocar de cena: dois objetos de inicialização na cena. O
instancedo script acima evita isso.
Próximo passo
Faça o caminho completo com o AppID 480 hoje: instale o Steamworks.NET, rode o SteamBootstrap no editor e veja o overlay abrir com Shift+Tab. Quando pagar o Steam Direct, troque o número, crie uma conquista e faça o primeiro upload para um branch privado. Ter a build subindo meses antes do lançamento tira a pressão da semana final.
Perguntas frequentes
Quanto custa publicar um jogo Unity na Steam?
A Steam cobra 100 dólares de Steam Direct por jogo, segundo a documentação do Steamworks consultada em outubro de 2026. A taxa não é reembolsável, mas volta para você no pagamento seguinte depois que o jogo atinge 1.000 dólares de receita bruta ajustada. A licença da Unity tem regras próprias e não depende da Steam.
Steamworks.NET ou Facepunch.Steamworks: qual usar?
Steamworks.NET espelha a API oficial da Valve quase um para um e tem documentação da própria Valve valendo para ela. Facepunch.Steamworks tem uma API mais idiomática em C#, com async e propriedades. Para um primeiro jogo com conquistas e overlay, qualquer uma serve; Steamworks.NET tem mais exemplos espalhados por aí.
Por que SteamAPI_Init falha na Unity?
As causas mais comuns são o cliente Steam fechado, falta do arquivo steam_appid.txt com o AppID ao rodar fora da Steam, conta que não possui o jogo na biblioteca, ou a biblioteca nativa steam_api64.dll ausente na build. O InitEx devolve uma mensagem de erro que aponta qual é.
Preciso mandar o steam_appid.txt junto com o jogo?
Não. Ele serve para desenvolvimento, quando você roda o jogo fora do cliente Steam. Na build enviada pela Steam, o cliente já informa o AppID. Mantenha o arquivo na raiz do projeto Unity e fora da pasta que vai para o depot.


