terminalCode Example

GameManager INetworkListener Pattern

calendar_today May 3, 2026 schedule ~1 min read person patrickjr verified 50

GameManager INetworkListener Pattern

Game manager implementing connection lifecycle with player spawning and cleanup.

CSHARP
public sealed partial class GameManager : GameObjectSystem<GameManager>, Component.INetworkListener
{
    void ISceneStartup.OnHostInitialize()
    {
        if (!Networking.IsActive)
        {
            Networking.CreateLobby(new Sandbox.Network.LobbyConfig()
            {
                Privacy = Sandbox.Network.LobbyPrivacy.Public,
                MaxPlayers = 32,
                Name = "Sandbox",
                DestroyWhenHostLeaves = true
            });
        }
    }

    void Component.INetworkListener.OnActive(Connection channel)
    {
        channel.CanSpawnObjects = false;

        var playerData = CreatePlayerInfo(channel);
        SpawnPlayer(playerData);

        Scene.Get<Chat>()?.AddSystemText($"{channel.DisplayName} has joined", "👋");
    }

    void Component.INetworkListener.OnDisconnected(Connection channel)
    {
        var pd = PlayerData.For(channel);
        if (pd is not null) pd.GameObject.Destroy();

        UndoSystem.Current?.RemovePlayer(channel.SteamId);

        if (BanSystem.Current?.IsBanned(channel.SteamId) ?? false) return;

        Scene.Get<Chat>()?.AddSystemText($"{channel.DisplayName} has left", "👋");
    }

    public void SpawnPlayer(PlayerData playerData)
    {
        Assert.True(Networking.IsHost, "Only host can spawn");

        // Check for existing player
        if (Scene.GetAll<Player>().Any(x => x.Network.Owner?.Id == playerData.PlayerId))
            return;

        // Find spawn location
        var startLocation = FindSpawnLocation().WithScale(1);

        // Fire pre-respawn event
        var respawnEvent = new PlayerRespawnEvent
        {
            PlayerData = playerData,
            SpawnLocation = startLocation
        };
        Global.IPlayerEvents.Post(x => x.OnPlayerRespawning(respawnEvent));
        startLocation = respawnEvent.SpawnLocation;

        // Spawn player prefab
        var playerGo = GameObject.Clone("/prefabs/engine/player.prefab",
            new CloneConfig { Name = playerData.DisplayName, StartEnabled = false, Transform = startLocation });

        var player = playerGo.Components.Get<Player>(true);
        player.PlayerData = playerData;

        playerGo.NetworkSpawn(Connection.Find(playerData.PlayerId));

        Local.IPlayerEvents.PostToGameObject(player.GameObject, x => x.OnSpawned());
        Global.IPlayerEvents.Post(x => x.OnPlayerSpawned(player));
    }
}

Implemented Interfaces

  • INetworkListener - Connection lifecycle events
  • ISceneStartup - Scene initialization
  • IScenePhysicsEvents - Physics step hooks
  • ICleanupEvents - Cleanup notifications
  • ISaveEvents - Save/load persistence
Was this helpful?