Steam no es un netcode: es una plataforma#
Steam no sustituye a Netcode o Mirror: los complementa. Lo que aporta:
- Lobbies: salas para reunir jugadores antes de la partida.
- Amigos e invitaciones: unirse a la partida de un amigo desde el overlay de Steam.
- Red P2P con relay (SDR): conecta a los jugadores sin abrir puertos ni compartir IP, enrutando por los servidores de Valve. Gratis para desarrolladores de Steam.
La arquitectura típica: tu framework de red (Mirror/NGO) hace la lógica, y Steam es el transporte + el sistema de lobbies.
Para hablar con la API de Steam desde C# tienes dos envoltorios: Steamworks.NET (fino, pegado a la API de C++) y Facepunch.Steamworks (más moderno y cómodo en C#, con async/await). Los ejemplos de aquí usan Facepunch. Para el transporte con Mirror, el más usado es FizzySteamworks.
Requisitos para probar#
Para que la API funcione: el cliente de Steam debe estar ejecutándose y logueado, y tu proyecto necesita un archivo steam_appid.txt en la raíz con el App ID. Para pruebas se usa el App ID 480 (Spacewar, el juego de ejemplo de Valve). Publicar de verdad requiere una cuenta Steamworks (100 $ una vez) y tu propio App ID.
Inicializar Steam#
using Steamworks; // Facepunch.Steamworks
using UnityEngine;
public class SteamGestor : MonoBehaviour
{
void Awake()
{
try
{
SteamClient.Init(480); // 480 = Spacewar (pruebas)
Debug.Log("Steam listo. Jugador: " + SteamClient.Name);
}
catch (System.Exception e)
{
Debug.LogError("No se pudo iniciar Steam: " + e.Message);
}
}
void Update() => SteamClient.RunCallbacks(); // procesar eventos de Steam
void OnApplicationQuit() => SteamClient.Shutdown();
}Crear y unirse a un lobby#
using System.Threading.Tasks;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
public class LobbySteam : MonoBehaviour
{
public async Task CrearLobby()
{
// Sala para 4 jugadores
Lobby? lobby = await SteamMatchmaking.CreateLobbyAsync(4);
if (lobby.HasValue)
{
lobby.Value.SetPublic();
lobby.Value.SetData("nombre", "Partida de " + SteamClient.Name);
Debug.Log("Lobby creado: " + lobby.Value.Id);
}
}
void OnEnable()
{
// El jugador acepta una invitación desde el overlay de Steam
SteamMatchmaking.OnLobbyEntered += LobbyEntrado;
SteamFriends.OnGameLobbyJoinRequested += UnirseDesdeInvitacion;
}
void OnDisable()
{
SteamMatchmaking.OnLobbyEntered -= LobbyEntrado;
SteamFriends.OnGameLobbyJoinRequested -= UnirseDesdeInvitacion;
}
void LobbyEntrado(Lobby lobby)
{
Debug.Log("Has entrado al lobby: " + lobby.Id);
// Aquí arrancas tu red (host si eres el dueño, cliente si no)
}
async void UnirseDesdeInvitacion(Lobby lobby, SteamId id)
{
await lobby.Join();
}
}El flujo habitual: el host crea el lobby y arranca su servidor (Mirror/NGO); los invitados entran al lobby, leen la SteamId del host y se conectan a él mediante el transporte de Steam. El lobby es la "sala de espera"; la partida la lleva tu framework de red.
Combinarlo con tu framework#
- Con Mirror: instala el transporte FizzySteamworks y ponlo como Transport del NetworkManager. Mirror mandará sus mensajes por la red P2P de Steam en vez de por IP.
- Con Netcode for GameObjects: existen transportes de comunidad (basados en Facepunch o Steamworks.NET) que hacen el mismo papel para NGO.
Así tu código de red no cambia: solo cambias por dónde viajan los bytes.
Cuándo usar Steam#
- ¿Publicas en Steam y quieres invitaciones de amigos y "unirse a partida"? → sí, Steam
- ¿Quieres P2P sin abrir puertos ni pagar servidores? → sí, la red de Steam (SDR) lo da gratis
- ¿Tu juego no sale en Steam (móvil, web)? → no; usa Relay de Unity, Photon, etc.
- ¿Aún estás aprendiendo la red? → primero haz que funcione en LAN; añade Steam al final
Errores frecuentes#
- Probar sin el cliente de Steam abierto o sin
steam_appid.txt(la init falla). - Olvidar
SteamClient.RunCallbacks()cada frame (los eventos no llegan). - No llamar a
SteamClient.Shutdown()al salir. - Intentar meter Steam antes de que el juego funcione en LAN: depura una capa cada vez.
- Creer que Steam sustituye al netcode (sigue necesitando Mirror/NGO para la lógica).
Ponte a prueba#
Resumen#
Steam es plataforma + transporte, no un netcode: aporta lobbies, invitaciones de amigos y P2P con relay (sin abrir puertos), y se combina con Mirror (FizzySteamworks) o NGO. Usa Facepunch.Steamworks o Steamworks.NET, ten el cliente de Steam abierto con steam_appid.txt (480 para pruebas), inicializa con SteamClient.Init, llama a RunCallbacks cada frame, y añade Steam cuando el juego ya funcione en LAN. Elige según tu caso en la comparativa.