S PreserveEnts: Difference between revisions
Jump to navigation
Jump to search
Note:
Note:Some entities don't exist in the given games despite being in s_preservedEnts list. (for example info_node* entities in 
)
m ("From code dump" --> "Dissembler" for trimming characters) |
SirYodaJedi (talk | contribs) No edit summary |
||
| (45 intermediate revisions by 12 users not shown) | |||
| Line 1: | Line 1: | ||
{{ | {{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'' [[classname]]s match 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]]. | ||
{{note| | |||
* Some games might not have any way to reset the round (even through {{mono|mp_forcewin}} or {{mono|mp_restartgame}} commands). | |||
* [[Contexts]] aren't preserved between round restart even for preserved entities {{todotest|Left 4 Dead 2}} | |||
* Entities with the entity flag {{code|EFL_KEEP_ON_RECREATE_ENTITIES}} are preserved, even if they aren't in the s_PreserveEnts array. This can be set via [[Vscript]] in supported games, to preserve entities that aren't normally preserved.{{confirm}} | |||
}} | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Games | ! Games !! Has Whitelist !! Has Rounds !! Notes | ||
|- | |||
|{{css|2}} || {{style|color:green|Yes}} || Yes || | |||
|- | |||
|{{hls|2}} || {{style|color:red|No}} || - || | |||
|- | |||
|{{hldms|2}} || {{style|color:red|No}} || - || | |||
|- | |||
|{{hl2|2}} || {{style|color:red|No}} || - || | |||
|- | |||
|{{hl2dm|2}} || {{style|color:green|Yes}} || No || Round can be reset using mp_restartgame | |||
|- | |||
|{{dods|2}} || {{style|color:green|Yes}} || Yes || | |||
|- | |||
|{{hl2ep1|2}} || {{style|color:red|No}} || - || | |||
|- | |||
|{{hl2ep2|2}} || {{style|color:red|No}} || - || | |||
|- | |||
|{{portal|2}} || {{style|color:red|No}} || - || Whitelist exists, but is not included in the compiled DLLs. | |||
|- | |||
|{{tf2|2}} || {{style|color:green|Yes}} || Yes || | |||
|- | |||
|{{l4d|2}} || {{style|color:green|Yes}} || Yes || | |||
|- | |||
|{{l4d2|2}} || {{style|color:green|Yes}} || Yes || | |||
|- | |||
|{{as|2}}{{asrd|2}} || {{style|color:green|Yes}} || No || <code>asw_instant_restart 1</code> should allow for round reset without full map reload but seems to always crash the game instead in {{as}}. It's the default behavior in {{asrd}} and works properly.<br>Uses {{mono|m_MapResetFilter.AddKeepEntity()}} function instead of {{mono|s_PreserveEnts[]}} array. | |||
|- | |||
|{{portal2|2}} || {{style|color:green|Yes}} || No || Can round be reset in coop?{{confirm}} | |||
|- | |||
|{{csgo|2}} || {{style|color:green|Yes}} || Yes || | |||
|- | |- | ||
|} | |} | ||
== Source Code == | == Behavior == | ||
==={{ | If the game has round restart mechanics, a preserved entity may not behave as expected: | ||
{{ | * On a new round entities with this classname will '''intentionally not reset'''. You can use {{ent|logic_auto}} to emulate resetting it. | ||
* [[Kill]]ing it removes it forever, as '''it is not respawned''' on a new round. | |||
* It cannot be spawned with a {{ent|point_template}}. | |||
* Parenting this with non-preserved entities may have [[Counter-Strike Source Entity Overview#Counter-Strike Round Restarts|undesirable effects]]. | |||
== Lists == | |||
{{note|Some entities don't exist in the given games despite being in s_preservedEnts list. (for example info_node* entities in {{l4ds}})}} | |||
===Source Code=== | |||
===={{as|4}}==== | |||
{{expand|title={{mono|swarm/asw_gamerules.cpp}}| | |||
<syntaxhighlight lang="cpp"> | |||
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"); | |||
} | |||
</syntaxhighlight> | |||
}} | |||
==== {{asrd|4}} ==== | |||
{{expand|title={{mono|swarm/asw_gamerules.cpp}}| | |||
<syntaxhighlight lang="cpp"> | |||
// 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" ); | |||
m_MapResetFilter.AddKeepEntity( "ai_hint" ); | |||
m_MapResetFilter.AddKeepEntity( "info_node" ); | |||
m_MapResetFilter.AddKeepEntity( "info_hint" ); | |||
m_MapResetFilter.AddKeepEntity( "info_node_hint" ); | |||
m_MapResetFilter.AddKeepEntity( "info_node_air" ); | |||
m_MapResetFilter.AddKeepEntity( "info_node_air_hint" ); | |||
m_MapResetFilter.AddKeepEntity( "info_node_climb" ); | |||
m_MapResetFilter.AddKeepEntity( "info_marine_hint" ); | |||
m_MapResetFilter.AddKeepEntity( "info_node_marine_hint" ); | |||
m_MapResetFilter.AddKeepEntity( "infodecal" ); | |||
// riflemod: keep health regen entity all the time | |||
m_MapResetFilter.AddKeepEntity( "asw_health_regen" ); | |||
</syntaxhighlight>}} | |||
===={{csgo|4}}==== | |||
{{expand|title={{mono|cstrike15/cs_gamerules.cpp}}| | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
| Line 47: | Line 116: | ||
"ai_network", | "ai_network", | ||
"ai_hint", | "ai_hint", | ||
" | "cs_gamerules", | ||
" | "cs_team_manager", | ||
" | "cs_player_manager", | ||
"env_soundscape", | "env_soundscape", | ||
"env_soundscape_proxy", | "env_soundscape_proxy", | ||
| Line 56: | Line 125: | ||
"env_wind", | "env_wind", | ||
"env_fog_controller", | "env_fog_controller", | ||
"env_tonemap_controller", | |||
"env_cascade_light", | |||
"func_brush", | "func_brush", | ||
"func_wall", | "func_wall", | ||
"func_buyzone", | "func_buyzone", | ||
"func_illusionary", | "func_illusionary", | ||
"func_hostage_rescue", | |||
"func_bomb_target", | |||
"infodecal", | "infodecal", | ||
"info_projecteddecal", | "info_projecteddecal", | ||
| Line 65: | Line 138: | ||
"info_target", | "info_target", | ||
"info_node_hint", | "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", | "info_map_parameters", | ||
"keyframe_rope", | "keyframe_rope", | ||
| Line 74: | Line 150: | ||
"player", | "player", | ||
"point_viewcontrol", | "point_viewcontrol", | ||
"point_viewcontrol_multiplayer", | |||
"scene_manager", | "scene_manager", | ||
"shadow_control", | "shadow_control", | ||
| Line 83: | Line 160: | ||
"worldspawn", | "worldspawn", | ||
"point_devshot_camera", | "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 | "", // END Marker | ||
}; | }; | ||
| Line 88: | Line 176: | ||
}} | }} | ||
==={{ | ===={{css|4}}==== | ||
{{ | {{expand|title={{mono|cstrike/cs_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
| Line 95: | Line 183: | ||
"ai_network", | "ai_network", | ||
"ai_hint", | "ai_hint", | ||
" | "cs_gamerules", | ||
" | "cs_team_manager", | ||
" | "cs_player_manager", | ||
"env_soundscape", | "env_soundscape", | ||
"env_soundscape_proxy", | "env_soundscape_proxy", | ||
| Line 108: | Line 196: | ||
"func_buyzone", | "func_buyzone", | ||
"func_illusionary", | "func_illusionary", | ||
"func_hostage_rescue", | |||
"func_bomb_target", | |||
"infodecal", | "infodecal", | ||
"info_projecteddecal", | "info_projecteddecal", | ||
| Line 113: | Line 203: | ||
"info_target", | "info_target", | ||
"info_node_hint", | "info_node_hint", | ||
" | "info_player_counterterrorist", | ||
" | "info_player_terrorist", | ||
"info_map_parameters", | "info_map_parameters", | ||
"keyframe_rope", | "keyframe_rope", | ||
| Line 136: | Line 225: | ||
}} | }} | ||
==={{ | ===={{dods|4}}==== | ||
{| | {{expand|title={{mono|dod/dod_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | |||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
{ | { | ||
| Line 149: | Line 236: | ||
"ai_network", | "ai_network", | ||
"ai_hint", | "ai_hint", | ||
"dod_gamerules", | |||
"dod_team_manager", | |||
"dod_player_manager", | |||
"dod_objective_resource", | |||
"env_soundscape", | "env_soundscape", | ||
"env_soundscape_proxy", | "env_soundscape_proxy", | ||
| Line 156: | Line 247: | ||
"env_wind", | "env_wind", | ||
"env_fog_controller", | "env_fog_controller", | ||
"func_brush", | |||
"func_wall", | "func_wall", | ||
"func_illusionary", | "func_illusionary", | ||
| Line 161: | Line 253: | ||
"info_target", | "info_target", | ||
"info_node_hint", | "info_node_hint", | ||
" | "info_player_allies", | ||
"info_player_axis", | |||
"point_viewcontrol", | "point_viewcontrol", | ||
"shadow_control", | "shadow_control", | ||
"sky_camera", | "sky_camera", | ||
"scene_manager", | "scene_manager", | ||
"trigger_soundscape", | "trigger_soundscape", | ||
" | "info_dod_detect", | ||
"dod_team_allies", | |||
"dod_team_axis", | |||
"point_commentary_node", | "point_commentary_node", | ||
" | "dod_round_timer", | ||
" | "func_precipitation", | ||
" | "func_team_wall", | ||
"", // END Marker | "", // END Marker | ||
};</syntaxhighlight> | }; | ||
</syntaxhighlight> | |||
}} | |||
} | |||
==={{ | ===={{hl2dm|4}}==== | ||
{{ | {{Expand|title={{mono|hl2mp/hl2mp_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
| Line 224: | Line 279: | ||
"ai_network", | "ai_network", | ||
"ai_hint", | "ai_hint", | ||
" | "hl2mp_gamerules", | ||
" | "team_manager", | ||
" | "player_manager", | ||
"env_soundscape", | "env_soundscape", | ||
"env_soundscape_proxy", | "env_soundscape_proxy", | ||
| Line 237: | Line 292: | ||
"func_buyzone", | "func_buyzone", | ||
"func_illusionary", | "func_illusionary", | ||
"infodecal", | "infodecal", | ||
"info_projecteddecal", | "info_projecteddecal", | ||
| Line 244: | Line 297: | ||
"info_target", | "info_target", | ||
"info_node_hint", | "info_node_hint", | ||
" | "info_player_deathmatch", | ||
" | "info_player_combine", | ||
"info_player_rebel", | |||
"info_map_parameters", | "info_map_parameters", | ||
"keyframe_rope", | "keyframe_rope", | ||
| Line 266: | Line 320: | ||
}} | }} | ||
==={{ | ===={{portal2|4}}==== | ||
{{ | {{Expand|title={{mono|portal/portal_mp_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
{ | { | ||
"ai_network", | "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 | |||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
}} | }} | ||
==={{ | ===={{tf2|4}}==== | ||
{{ | {{Expand|title={{mono|teamplayroundbased_gamerules.cpp}}| | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
// Classnames of entities that are preserved across round restarts | |||
static const char *s_PreserveEnts[] = | static const char *s_PreserveEnts[] = | ||
{ | { | ||
| Line 344: | Line 380: | ||
"ai_network", | "ai_network", | ||
"ai_hint", | "ai_hint", | ||
"env_soundscape", | "env_soundscape", | ||
"env_soundscape_proxy", | "env_soundscape_proxy", | ||
| Line 355: | Line 387: | ||
"env_wind", | "env_wind", | ||
"env_fog_controller", | "env_fog_controller", | ||
"func_wall", | "func_wall", | ||
"func_illusionary", | "func_illusionary", | ||
| Line 361: | Line 392: | ||
"info_target", | "info_target", | ||
"info_node_hint", | "info_node_hint", | ||
" | "point_commentary_node", | ||
"point_viewcontrol", | "point_viewcontrol", | ||
"func_precipitation", | |||
"func_team_wall", | |||
"shadow_control", | "shadow_control", | ||
"sky_camera", | "sky_camera", | ||
"scene_manager", | "scene_manager", | ||
"trigger_soundscape", | "trigger_soundscape", | ||
" | "commentary_auto", | ||
"point_commentary_node", | "point_commentary_node", | ||
" | "point_commentary_viewpoint", | ||
" | "bot_roster", | ||
" | "info_populator", | ||
"", // END Marker | "", // END Marker | ||
}; | };</syntaxhighlight>}} | ||
</syntaxhighlight> | |||
}} | |||
{{expand|title={{mono|tf/tf_gamerules.cpp}}| | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
// 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", | ||
</syntaxhighlight> | "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 | |||
};</syntaxhighlight>}} | |||
===Code Dumps=== | |||
To find the {{mono|S_PreserveEnts}} whitelist in the Left 4 Dead games in IDA: | |||
# Search for the {{ent|ai_network}} string reference. | |||
# Bring up all applicable XREFs. | |||
# Search for the list that includes {{ent|survivor_bot}} and {{ent|logic_versus_random}}. | |||
= | ===={{l4d|4}}==== | ||
=== {{l4d}} | {{expand| | ||
{{ | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
; "ai_network", | ; "ai_network", | ||
| Line 457: | Line 505: | ||
}} | }} | ||
=== {{l4d2}} | ===={{l4d2|4}}==== | ||
{{expand| | |||
{{ | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
; "ai_network", | ; "ai_network", | ||
Latest revision as of 17:19, 5 December 2025
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 match 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.
- Some games might not have any way to reset the round (even through mp_forcewin or mp_restartgame commands).
- Contexts aren't preserved between round restart even for preserved entities (tested in: Left 4 Dead 2)
- Entities with the entity flag
EFL_KEEP_ON_RECREATE_ENTITIESare preserved, even if they aren't in the s_PreserveEnts array. This can be set via Vscript in supported games, to preserve entities that aren't normally preserved.[confirm]
| Games | Has Whitelist | Has Rounds | Notes |
|---|---|---|---|
| Yes | Yes | ||
| No | - | ||
| No | - | ||
| No | - | ||
| Yes | No | Round can be reset using mp_restartgame | |
| Yes | Yes | ||
| No | - | ||
| No | - | ||
| No | - | Whitelist exists, but is not included in the compiled DLLs. | |
| Yes | Yes | ||
| Yes | Yes | ||
| Yes | Yes | ||
| Yes | No | asw_instant_restart 1 should allow for round reset without full map reload but seems to always crash the game instead in Uses m_MapResetFilter.AddKeepEntity() function instead of s_PreserveEnts[] array. | |
| Yes | No | Can round be reset in coop?[confirm] | |
| Yes | Yes |
Behavior
If the game has round restart mechanics, a preserved entity may not behave as expected:
- On a new round entities with this classname will intentionally not reset. You can use logic_auto to emulate resetting it.
- Killing it removes it forever, as it is not respawned on a new round.
- It cannot be spawned with a point_template.
- Parenting this with non-preserved entities may have undesirable effects.
Lists
Source Code
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");
}
|
Alien Swarm: Reactive Drop
// 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" );
m_MapResetFilter.AddKeepEntity( "ai_hint" );
m_MapResetFilter.AddKeepEntity( "info_node" );
m_MapResetFilter.AddKeepEntity( "info_hint" );
m_MapResetFilter.AddKeepEntity( "info_node_hint" );
m_MapResetFilter.AddKeepEntity( "info_node_air" );
m_MapResetFilter.AddKeepEntity( "info_node_air_hint" );
m_MapResetFilter.AddKeepEntity( "info_node_climb" );
m_MapResetFilter.AddKeepEntity( "info_marine_hint" );
m_MapResetFilter.AddKeepEntity( "info_node_marine_hint" );
m_MapResetFilter.AddKeepEntity( "infodecal" );
// riflemod: keep health regen entity all the time
m_MapResetFilter.AddKeepEntity( "asw_health_regen" );
|
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
};
|
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
};
|
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
};
|
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 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
};
|
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",
|