Voltar para o Blog
Quest Log

Publicar Jogo Unity na Steam: Steamworks e Build

Monitor de computador com um jogo rodando, um troféu de conquista brilhando e um cano de vapor levando caixas para uma nuvem

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:

  1. Conta no Steamworks (partner.steamgames.com), com dados fiscais e bancários. A verificação leva alguns dias.
  2. 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.
  3. Pago o Steam Direct, você recebe um AppID (ex.: 1234560) e um Depot ID (normalmente AppID + 1).
  4. Integração no Unity usando esse AppID.
  5. Build e upload pelo SteamPipe.
  6. 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:

TarefaOnde se resolve
Gerar o .exe, a pasta _Data e as DLLsUnity (Build Profiles)
Chamar a API da Steam no códigoBiblioteca C# (Steamworks.NET)
Criar conquistas, estatísticas e Steam CloudPainel do Steamworks
Definir qual .exe abre ao clicar em JogarSteamworks, em Installation > General
Enviar arquivos e escolher a build ativaSteamPipe
Página, preço, revisão e data de lançamentoPainel 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

  1. Window > Package Management > Package Manager, botão +, Install package from git URL.
  2. Cole https://github.com/rlabrecque/Steamworks.NET.git?path=/com.rlabrecque.steamworks.net#2025.164.1.
  3. Na raiz do projeto (ao lado da pasta Assets, não dentro), crie steam_appid.txt contendo 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 .exe direto, 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 o Init() antigo porque diz por que falhou.
  • RunCallbacks em todo frame: sem ele, nenhum evento da Steam chega ao jogo (overlay, conquistas, estatísticas).
  • Shutdown ao 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.

Curso de Unity
Quer fazer seu primeiro jogo na Unity?

No curso de Unity 6 da CursoGame.Dev você vai do zero ao primeiro jogo, com um desafio prático em cada level e suporte individual no WhatsApp quando travar.

Conhecer o curso de Unity
Suporte no WhatsAppAcesso vitalícioGarantia de 7 dias

Build Windows pronta para a Steam

  1. File > Build Profiles > Windows. Architecture: x86_64 (Intel 64-bit).
  2. Desmarque Development Build para a versão de loja.
  3. 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).
  4. Clique em Build e escolha uma pasta como SteamBuild/content.

Confira na pasta gerada:

  • steam_api64.dll precisa estar na pasta NomeDoJogo_Data/Plugins/x86_64. Sem ela, SteamAPI_Init falha só na build.
  • Não coloque o steam_appid.txt aqui.
  • Apague as pastas *_BurstDebugInformation_DoNotShip e *_BackUpThisFolder_ButDontShipItInYourBuild se 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.: beta com 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.txt na 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.dll nã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 instance do 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.