I got this working by looking at the CSGO deathmatch plugin and extracting just the parts that handle respawing.
I am not trying to take credit for something I didn't write, or publish a new plugin.
I just wanted a simple respawn for bot game play on my server.
Total credit and thanks to Maxximou5.
I updated the code from my original post to this working code from the CSGO deathmatch plugin.
I did notice one weirdness.
After a couple of minutes and numerous respawns some bot would respawn and just stand still at the spawn until a human came up to them and interacted with them and only then started to engage. Weird...
If anyone is looking for a simple respawn that is all this does and it adds 5 seconds to the respawn time after every respawn.
This simple respawn makes playing with a lot of bots a lot more fun!
I plan on more tweaks where the chance to respawn decreases as the round time increases and other things like all bots respwn after the bomb is planted if humans are on as t!
I am trying to create a simple CSGO respawn for playing with bots.
To get started I am trying to just respawn the bots 9 seconds after they die.
The following sort of works on the first map.
Most of the time they respawn but not always and after a map change they never respawn because the client ids are always 0.
I am not using the built in respawn commands because I want more control over when and if the bots respawn.
Once I get the basics working I plan on limiting the respawns based on round time left which I have figured out.
It seems like this should be very simple.
#pragma newdecls required
#define PLUGIN_VERSION "1.0.0"
#define PLUGIN_NAME "[CS:GO] Respawn"
#define PLUGIN_AUTHOR ""
#define PLUGIN_DESCRIPTION ""
#define PLUGIN_URL "https://"
public Plugin myinfo =
name = PLUGIN_NAME,
author = PLUGIN_AUTHOR,
description = PLUGIN_DESCRIPTION,
version = PLUGIN_VERSION,
url = PLUGIN_URL
bool g_bRoundEnded = false;
public void OnPluginStart()
HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post);
HookEvent("round_prestart", Event_RoundPrestart, EventHookMode_PostNoCopy);
HookEvent("round_end", Event_RoundEnd, EventHookMode_PostNoCopy);
g_respawn_time = CreateConVar("abs_respawn_time", "9.0", "Respawn time.");
public Action Event_RoundEnd(Event event, const char name, bool dontBroadcast)
g_bRoundEnded = true;
public void Event_CvarChange(ConVar cvar, const char oldValue, const char newValue)
if (g_respawn_time.FloatValue < 0.0)
g_respawn_time.FloatValue = 0.0;
public Action Event_RoundPrestart(Event event, const char name, bool dontBroadcast)
g_bRoundEnded = false;
public void Event_PlayerTeam(Event event, const char name, bool dontBroadcast)
int client = GetClientOfUserId(event.GetInt("userid"));
/* If the player joins spectator, close any open menu, and remove their ragdoll. */
if ((client != 0) && (GetClientTeam(client) == CS_TEAM_SPECTATOR))
CreateTimer(g_respawn_time.FloatValue, Timer_Respawn, GetClientSerial(client));
public Action Event_PlayerDeath(Event event, const char name, bool dontBroadcast)
int victim = GetClientOfUserId(event.GetInt("userid"));
CreateTimer(g_respawn_time.FloatValue, Timer_Respawn, GetClientSerial(victim));
public Action Timer_Respawn(Handle timer, any serial)
int client = GetClientFromSerial(serial);
if (!g_bRoundEnded && IsValidClient(client) && (GetClientTeam(client) != CS_TEAM_SPECTATOR) && !IsPlayerAlive(client))
// each respawn increases the respawn time
g_respawn_time.FloatValue += 5.0;
bool IsValidClient(int client)
if (!(0 < client <= MaxClients))
void RemoveRagdoll(int client)
int ragdoll = GetEntPropEnt(client, Prop_Send, "m_hRagdoll");
if (ragdoll != -1)