S PreserveEnts: Difference between revisions
Jump to navigation
Jump to search
Note:Some games might not have any way to reset the round (even through mp_forcewin or mp_restartgame commands).
SirYodaJedi (talk | contribs) (Add HLS and HLDMS to list of whether there's a whitelist (they don't preserve)) |
SirYodaJedi (talk | contribs) No edit summary |
||
Line 1: | Line 1: | ||
{{LanguageBar|title=s_PreserveEnts}} | {{LanguageBar|title=s_PreserveEnts}} | ||
In multiplayer {{source|4}} games, all [[entity|entities]] are set back to their defaults during a round reset by removing and immediately respawning them, unless their ''current'' classnames matches an entry in the | In multiplayer {{source|4}} games, all [[entity|entities]] are set back to their defaults during a round reset by removing and immediately respawning them, unless their ''current'' classnames matches an entry in the {{mono|s_PreserveEnts}} whitelist. Whitelisted entities either have special code to handle the reset process or none at all, and the entity is therefore considered not ideal for removal. | ||
Some whitelisted entities may not properly account for round resets and are likely to carry their previous properties over to the next round, such as their [[Coordinates|origins]]. | Some whitelisted entities may not properly account for round resets and are likely to carry their previous properties over to the next round, such as their [[Coordinates|origins]]. | ||
{{note|Some games might not have any way to reset the round (even through | {{note|Some games might not have any way to reset the round (even through {{mono|mp_forcewin}} or {{mono|mp_restartgame}} commands).}} | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Line 44: | Line 44: | ||
==Source Code== | ==Source Code== | ||
==={{hl2dm|4}}=== | ==={{hl2dm|4}}=== | ||
{{Expand|title= | {{Expand|title={{mono|hl2mp/hl2mp_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
Line 92: | Line 92: | ||
==={{portal|4}}=== | ==={{portal|4}}=== | ||
{{Expand|title= | {{Expand|title={{mono|portal/portal_mp_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
Line 140: | Line 140: | ||
==={{portal2|4}}=== | ==={{portal2|4}}=== | ||
{{Expand|title= | {{Expand|title={{mono|portal/portal_mp_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
Line 188: | Line 188: | ||
==={{tf2|4}}=== | ==={{tf2|4}}=== | ||
{{Expand|title= | {{Expand|title={{mono|teamplayroundbased_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
// Classnames of entities that are preserved across round restarts | // Classnames of entities that are preserved across round restarts | ||
Line 227: | Line 227: | ||
};</syntaxhighlight>}} | };</syntaxhighlight>}} | ||
{{expand|title= | {{expand|title={{mono|tf/tf_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
// Classnames of entities that are preserved across round restarts | // Classnames of entities that are preserved across round restarts | ||
Line 268: | Line 268: | ||
==={{css|4}}=== | ==={{css|4}}=== | ||
{{expand|title= | {{expand|title={{mono|cstrike/cs_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
Line 317: | Line 317: | ||
==={{csgo|4}}=== | ==={{csgo|4}}=== | ||
{{expand|title= | {{expand|title={{mono|cstrike15/cs_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
Line 384: | Line 384: | ||
==={{dods|4}}=== | ==={{dods|4}}=== | ||
{{expand|title= | {{expand|title={{mono|dod/dod_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
Line 431: | Line 431: | ||
==={{as|4}}=== | ==={{as|4}}=== | ||
{{expand|title= | {{expand|title={{mono|swarm/asw_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
CAlienSwarm::CAlienSwarm() | CAlienSwarm::CAlienSwarm() | ||
Line 452: | Line 452: | ||
==Code Dumps== | ==Code Dumps== | ||
To find the | To find the {{mono|S_PreserveEnts}} whitelist in the Left 4 Dead games in IDA: | ||
# Search for the {{ent|ai_network}} string reference. | # Search for the {{ent|ai_network}} string reference. | ||
# Bring up all applicable XREFs. | # Bring up all applicable XREFs. |
Revision as of 13:00, 4 December 2024
In multiplayer Source games, all entities are set back to their defaults during a round reset by removing and immediately respawning them, unless their current classnames matches an entry in the s_PreserveEnts whitelist. Whitelisted entities either have special code to handle the reset process or none at all, and the entity is therefore considered not ideal for removal.
Some whitelisted entities may not properly account for round resets and are likely to carry their previous properties over to the next round, such as their origins.

Games | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Has Whitelist | Yes | No | No | No | Yes | Yes | No | No | Yes | Yes | Yes (Disassembly) | Yes | Yes | Yes |
Source Code
Half-Life 2: Deathmatch
static const char *s_PreserveEnts[] =
{
"ai_network",
"ai_hint",
"hl2mp_gamerules",
"team_manager",
"player_manager",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sun",
"env_wind",
"env_fog_controller",
"func_brush",
"func_wall",
"func_buyzone",
"func_illusionary",
"infodecal",
"info_projecteddecal",
"info_node",
"info_target",
"info_node_hint",
"info_player_deathmatch",
"info_player_combine",
"info_player_rebel",
"info_map_parameters",
"keyframe_rope",
"move_rope",
"info_ladder",
"player",
"point_viewcontrol",
"scene_manager",
"shadow_control",
"sky_camera",
"soundent",
"trigger_soundscape",
"viewmodel",
"predicted_viewmodel",
"worldspawn",
"point_devshot_camera",
"", // END Marker
};
|
Portal
static const char *s_PreserveEnts[] =
{
"ai_network",
"ai_hint",
"hl2mp_gamerules",
"team_manager",
"player_manager",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sun",
"env_wind",
"env_fog_controller",
"func_brush",
"func_wall",
"func_buyzone",
"func_illusionary",
"infodecal",
"info_projecteddecal",
"info_node",
"info_target",
"info_node_hint",
"info_player_deathmatch",
"info_player_combine",
"info_player_rebel",
"info_map_parameters",
"keyframe_rope",
"move_rope",
"info_ladder",
"player",
"point_viewcontrol",
"scene_manager",
"shadow_control",
"sky_camera",
"soundent",
"trigger_soundscape",
"viewmodel",
"predicted_viewmodel",
"worldspawn",
"point_devshot_camera",
"", // END Marker
};
|
Portal 2
static const char *s_PreserveEnts[] =
{
"ai_network",
"ai_hint",
"hl2mp_gamerules",
"team_manager",
"player_manager",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sun",
"env_wind",
"env_fog_controller",
"func_brush",
"func_wall",
"func_buyzone",
"func_illusionary",
"infodecal",
"info_projecteddecal",
"info_node",
"info_target",
"info_node_hint",
"info_player_deathmatch",
"info_player_combine",
"info_player_rebel",
"info_map_parameters",
"keyframe_rope",
"move_rope",
"info_ladder",
"player",
"point_viewcontrol",
"scene_manager",
"shadow_control",
"sky_camera",
"soundent",
"trigger_soundscape",
"viewmodel",
"predicted_viewmodel",
"worldspawn",
"point_devshot_camera",
"", // END Marker
};
|
Team Fortress 2
// Classnames of entities that are preserved across round restarts
static const char *s_PreserveEnts[] =
{
"player",
"viewmodel",
"worldspawn",
"soundent",
"ai_network",
"ai_hint",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sprite",
"env_sun",
"env_wind",
"env_fog_controller",
"func_wall",
"func_illusionary",
"info_node",
"info_target",
"info_node_hint",
"point_commentary_node",
"point_viewcontrol",
"func_precipitation",
"func_team_wall",
"shadow_control",
"sky_camera",
"scene_manager",
"trigger_soundscape",
"commentary_auto",
"point_commentary_node",
"point_commentary_viewpoint",
"bot_roster",
"info_populator",
"", // END Marker
};
|
// Classnames of entities that are preserved across round restarts
static const char *s_PreserveEnts[] =
{
"tf_gamerules",
"tf_team_manager",
"tf_player_manager",
"tf_team",
"tf_objective_resource",
"keyframe_rope",
"move_rope",
"tf_viewmodel",
"tf_logic_training",
"tf_logic_training_mode",
"tf_powerup_bottle",
"tf_mann_vs_machine_stats",
"tf_wearable",
"tf_wearable_demoshield",
"tf_wearable_robot_arm",
"tf_wearable_vm",
"tf_logic_bonusround",
"vote_controller",
"monster_resource",
"tf_logic_medieval",
"tf_logic_cp_timer",
"tf_logic_tower_defense", // legacy
"tf_logic_mann_vs_machine",
"func_upgradestation",
"entity_rocket",
"entity_carrier",
"entity_sign",
"entity_saucer",
"tf_halloween_gift_pickup",
"tf_logic_competitive",
"tf_wearable_razorback",
"entity_soldier_statue",
"", // END Marker
};
|
Counter-Strike: Source
static const char *s_PreserveEnts[] =
{
"ai_network",
"ai_hint",
"cs_gamerules",
"cs_team_manager",
"cs_player_manager",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sun",
"env_wind",
"env_fog_controller",
"func_brush",
"func_wall",
"func_buyzone",
"func_illusionary",
"func_hostage_rescue",
"func_bomb_target",
"infodecal",
"info_projecteddecal",
"info_node",
"info_target",
"info_node_hint",
"info_player_counterterrorist",
"info_player_terrorist",
"info_map_parameters",
"keyframe_rope",
"move_rope",
"info_ladder",
"player",
"point_viewcontrol",
"scene_manager",
"shadow_control",
"sky_camera",
"soundent",
"trigger_soundscape",
"viewmodel",
"predicted_viewmodel",
"worldspawn",
"point_devshot_camera",
"", // END Marker
};
|
Counter-Strike: Global Offensive
static const char *s_PreserveEnts[] =
{
"ai_network",
"ai_hint",
"cs_gamerules",
"cs_team_manager",
"cs_player_manager",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sun",
"env_wind",
"env_fog_controller",
"env_tonemap_controller",
"env_cascade_light",
"func_brush",
"func_wall",
"func_buyzone",
"func_illusionary",
"func_hostage_rescue",
"func_bomb_target",
"infodecal",
"info_projecteddecal",
"info_node",
"info_target",
"info_node_hint",
"info_player_counterterrorist",
"info_player_terrorist",
"info_enemy_terrorist_spawn",
"info_deathmatch_spawn",
"info_armsrace_counterterrorist",
"info_armsrace_terrorist",
"info_map_parameters",
"keyframe_rope",
"move_rope",
"info_ladder",
"player",
"point_viewcontrol",
"point_viewcontrol_multiplayer",
"scene_manager",
"shadow_control",
"sky_camera",
"soundent",
"trigger_soundscape",
"viewmodel",
"predicted_viewmodel",
"worldspawn",
"point_devshot_camera",
"logic_choreographed_scene",
"cfe_player_decal",
"info_bomb_target_hint_A",
"info_bomb_target_hint_B",
"info_hostage_rescue_zone_hint",
"generic_actor",
"vote_controller",
"wearable_item",
"point_hiding_spot",
"game_coopmission_manager",
"chicken",
"", // END Marker
};
|
Day of Defeat: Source
static const char *s_PreserveEnts[] =
{
"player",
"viewmodel",
"worldspawn",
"soundent",
"ai_network",
"ai_hint",
"dod_gamerules",
"dod_team_manager",
"dod_player_manager",
"dod_objective_resource",
"env_soundscape",
"env_soundscape_proxy",
"env_soundscape_triggerable",
"env_sprite",
"env_sun",
"env_wind",
"env_fog_controller",
"func_brush",
"func_wall",
"func_illusionary",
"info_node",
"info_target",
"info_node_hint",
"info_player_allies",
"info_player_axis",
"point_viewcontrol",
"shadow_control",
"sky_camera",
"scene_manager",
"trigger_soundscape",
"info_dod_detect",
"dod_team_allies",
"dod_team_axis",
"point_commentary_node",
"dod_round_timer",
"func_precipitation",
"func_team_wall",
"", // END Marker
};
|
Alien Swarm
CAlienSwarm::CAlienSwarm()
{
// set which entities should stay around when we restart the mission
m_MapResetFilter.AddKeepEntity("worldspawn");
m_MapResetFilter.AddKeepEntity("soundent");
m_MapResetFilter.AddKeepEntity("asw_gamerules");
m_MapResetFilter.AddKeepEntity("player");
m_MapResetFilter.AddKeepEntity("asw_player");
m_MapResetFilter.AddKeepEntity("player_manager");
m_MapResetFilter.AddKeepEntity("predicted_viewmodel");
m_MapResetFilter.AddKeepEntity("sdk_team_manager");
m_MapResetFilter.AddKeepEntity("scene_manager");
m_MapResetFilter.AddKeepEntity("event_queue_saveload_proxy");
m_MapResetFilter.AddKeepEntity("ai_network");
}
|
Code Dumps
To find the S_PreserveEnts whitelist in the Left 4 Dead games in IDA:
- Search for the ai_network string reference.
- Bring up all applicable XREFs.
- Search for the list that includes survivor_bot and logic_versus_random.
Left 4 Dead
; "ai_network",
; "ai_hint",
; "cs_team_manager",
; "terror_gamerules",
; "terror_player_manager",
; "survivor_bot",
; "env_tonemap_controller",
; "env_tonemap_controller_infected",
; "env_tonemap_controller_ghost",
; "vote_controller",
; "env_soundscape",
; "env_soundscape_proxy",
; "env_soundscape_triggerable",
; "env_sun",
; "env_wind",
; "env_fog_controller",
; "func_wall",
; "func_buyzone",
; "func_illusionary",
; "func_hostage_rescue",
; "func_bomb_target",
; "infodecal",
; "info_projecteddecal",
; "info_node",
; "info_target",
; "info_node_hint",
; "info_player_counterterrorist",
; "info_player_terrorist",
; "info_map_parameters",
; "info_map_parameters_versus",
; "info_ladder",
; "func_simpleladder",
; "player",
; "point_viewcontrol",
; "scene_manager",
; "shadow_control",
; "sky_camera",
; "soundent",
; "trigger_soundscape",
; "viewmodel",
; "predicted_viewmodel",
; "worldspawn",
; "point_devshot_camera",
; "info_survivor_position",
; "logic_versus_random",
|
Left 4 Dead 2
; "ai_network",
; "ai_hint",
; "cs_team_manager",
; "terror_gamerules",
; "terror_player_manager",
; "survivor_bot",
; "env_tonemap_controller",
; "env_tonemap_controller_infected",
; "env_tonemap_controller_ghost",
; "vote_controller",
; "env_soundscape",
; "env_soundscape_proxy",
; "env_soundscape_triggerable",
; "env_sun",
; "env_wind",
; "env_fog_controller",
; "func_wall",
; "infodecal",
; "info_projecteddecal",
; "info_node",
; "info_node_hint",
; "info_map_parameters",
; "info_map_parameters_versus",
; "info_ladder",
; "func_simpleladder",
; "player",
; "point_viewcontrol",
; "scene_manager",
; "shadow_control",
; "sky_camera",
; "soundent",
; "trigger_soundscape",
; "viewmodel",
; "predicted_viewmodel",
; "worldspawn",
; "point_devshot_camera",
; "weapon_scavenge_item_spawn",
; "logic_versus_random",
|