Skip to main content

Incompatibilities

This page contains a list of incompatibilities between source 1 and source 2 that plugin developers should be aware of.

Players are split between a player controller and a pawn

Unlike source 1 where CBasePlayer was both the player on the server and the character in the world, source 2 splits these apart. A player controller holds all the information about the player itself, e.g. m_steamID, m_iszPlayerName, every controller has a m_hPawn attached to retrieve the player pawn. Pawn has your normal CBaseCombatCharacter properties set, e.g. m_iHealth, a pawn also includes a m_hController property to retrieve the player controller.

info

CBasePlayerController inherits from CBaseEntity and still behaves as any other entity, it will always use an entity index between 1 and MAXPLAYERS+1 as in source 1, however ordinary entity properties will not be set or used at all. Pawns do not use reserved entity indices.

A player controller still exists after a player disconnects

A controller holds a PlayerConnectedState m_iConnected value that represents the current state of the player. If a player disconnects, the controller will still exist but the state will be set to PlayerConnectedState::PlayerDisconnected. This could be a problem if you are passing controllers through timers where you'd normally only check if the entity handle is still valid, now the state has to be checked as well.

Not confirmed

Disconnected controllers should only be replaced by new players if the server is full

enum class PlayerConnectedState : uint32_t
{
PlayerNeverConnected = 0xffffffffffffffff,
PlayerConnected = 0x0,
PlayerConnecting = 0x1,
PlayerReconnecting = 0x2,
PlayerDisconnecting = 0x3,
PlayerDisconnected = 0x4,
PlayerReserved = 0x5,
};