Spawning of World Zombies and Animals in Dedicated Servers

From 7 Days to Die Wiki
Jump to navigation Jump to search

It is a long running issue in the dedicated servers where default settings do not produce the feel of zombie apocalypse enough due to performance problems of 7 Day To Die. Here are the instructions to make most of the Dedicated Server entity spawning.

Spawning more Entities in Dedicated Server

One of the first options to increase zombies in a dedicated server is to adjust the FPS rate of the Dedicated Server. By default the Dedicated Server is limited by 20 Fps lock that keeps zombies and entities from being spawned due to auto-adjustment for performance, done by the server.

Disable Dedicated Server Fps lock

This can be achieved by setting game preference after the Dedicated Server starts:

To set the Fps lock to disabled you have to connect to the Dedicated Server via a telnet client and execute command:

settargetfps 0

Notice: This needs to be done everytime you launch the dedicated server


After this change, In the server log you should see higher FPS than FPS: 20 according to your server hardware. As you can see in this example it is now FPS: 499.56

2024-05-23T20:52:08 428.410 INF Time: 6.94m FPS: 499.56 Heap: 2644.3MB Max: 2792.3MB Chunks: 298 CGO: 53 Ply: 1 Zom: 5 Ent: 10 (55) Items: 0 CO: 1 RSS: 3842.4MB

Note: This information can be seen by issuing a command mem after connecting to the game server using telnet.

Trivia Note: On a regular single player client of the game, Fps lock is already disabled, therefore for single player/coop game this action is not needed. But usually would be done by pressing F1 keyboard key followed by typing settargetfps 0 and pressing enter keyboard key.

While this previous method increases the amount of zombies. There are other limits placed in the game and server that prevent more zombies to be spawned.

Max Spawned Zombies and Max Spawned Animals (in the serverconfig.xml file)

<property name="MaxSpawnedZombies" value="364"/>
<property name="MaxSpawnedAnimals" value="350"/>

This is the first goto option for most Dedicated Servers owners to increase the zombie amount in their server. Althought it seems like it should do something, it only lifts the overall limit of zombies in the server. Meaning it does not increase the amount of zombies, but only regulates the amount, these properties are only making sure the zombie amount is not higher than the number specified. This setting is overall zombies on the server, and not how many each player will get zombies.

Increasing MaxSpawnedZombies property is a good idea even if you are using only vanilla spawning settings. Since It's only a regulatory property, you can try to increase it to an absurd value like 100000.

Keep in mind that even the best player computers today can not handle more than some 100 zombies around player. The player in-game FPS drops too low to have anything playable. However this MaxSpawnedZombies is not about that and you should be able to adjust it to absurd levels that meet your Hosting Resources. (Single core CPU frequency, RAM is most likely not affected by amount of zombies and is not the first issue when it comes to problems)

Beyond the vanilla spawning settings

This is where the interesting part comes, as we are actually going to modify the zombie spawning amount instead of removing the limits imposed by Fun Pimps. This part requires XML modlet modding that is completely safe and works on single player, coop multiplayer, dedicated servers.

Right now we start by making a new folder Mods

Example path:

C:\Program Files (x86)\Steam\steamapps\common\7 Days To Die\Mods

Inside this folder we will place our modlets that will load up and adjust the zombie amount on the server.

Biome Spawning XML modlet

The first modlet is going to be known as mods\World_Set_Biome_Spawning

To begin create new World_Set_Biome_Spawning empty subfolder inside mods folder.This folder will have to have ModInfo.xml file and Config folder.The Config folder is where the spawning adjustments file resides that is spawning.xml.

Here is an overview of the modlet file and folder structure.

mods\World_Set_Biome_Spawning
mods\World_Set_Biome_Spawning\ModInfo.xml
mods\World_Set_Biome_Spawning\Config
mods\World_Set_Biome_Spawning\Config\spawning.xml

Now that we have the modlet structure created. (empty files and folders) It's time to make it work. First the ModInfo.xml (mods\World_Set_Biome_Spawning\ModInfo.xml) Needs to follow this format.

<xml>
<Name value="Set_Biome_Spawning"/>
<DisplayName value="Set Biome Spawning"/>
<Version value="21.0"/>
<Description value="Set Biome spawning for A21.2 B30 inside 7DTD Dedicated Server and Single Player. Sets Zombies and Animal Biome Spawning for all major biomes."/>
<Author value="Vanilla Server"/>
<Website value="https://7daystodie.fandom.com/wiki/Mod_Structure"/>
</xml>


Next we will need to make the core part of the modlet that is spawning.xml. (mods\World_Set_Biome_Spawning\Config\spawning.xml)


After this, the modlet should be all ready to be loaded and is compliant.

<configs>
	<!-- *** General changes that need testing and might be useless  -->
	<!--<set xpath="/spawning/entityspawner/day/property[@name='ResetToday']/@value">true</set>-->
	<set xpath="/spawning/entityspawner/day/property[@name='DaysToRespawnIfPlayerLeft']/@value">1</set>
	
	<!-- Appends burned zombies to  the pine forest biome for testing -->
	<!--
	<append xpath="/spawning/biome[@name='pine_forest']">
		<spawn maxcount="8" respawndelay="0.15" time="Day" entitygroup="ZombiesBurntForest" />
	</append>
	-->
	
	<!-- Appends non-snow zombies to the snow biome for testing -->
	<append xpath="/spawning/biome[@name='snow']">
		<spawn maxcount="5" respawndelay="0.15" time="Day" entitygroup="ZombiesAll" />
		<spawn maxcount="5" respawndelay="0.15" time="Day" entitygroup="ZombiesForestDowntown" />
		<spawn maxcount="5" respawndelay="0.15" time="Day" entitygroup="ZombiesAll" notags="commercial,industrial,downtown" />
		<spawn maxcount="5" respawndelay="0.15" time="Day" entitygroup="ZombiesAll" tags="commercial,industrial" notags="downtown" />
	</append>
	
	<!-- Appends non-snow zombies to the PINE_FOREST biome for testing to resolve towns being empty -->
	<append xpath="/spawning/biome[@name='pine_forest']">
		<spawn maxcount="2" respawndelay="0.15" time="Any" entitygroup="ZombiesAll" />
		<spawn maxcount="2" respawndelay="0.15" time="Any" entitygroup="ZombiesForestDowntown" />
	</append>
	

	<!-- *** PINE_FOREST_SPAWNS 7 didn't work and 16, 14, 10,9 worked and nighttime from 10 to 7 reduced, the 5 was great for night time vanilla feel. -->
	<!-- *** PINE_FOREST_SPAWNS     The maxcount: 8 for day and and 5 for night felt normal. Now that zombies attack animals, the zombie amount might need to increase as they can die. -->
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Day' and @entitygroup='ZombiesAll']/@maxcount">5</set>  <!-- For Navezgane map 11 is enough -->
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Day' and @entitygroup='ZombiesAll']/@respawndelay">0.15</set>
		
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@maxcount">6</set> <!-- For Navezgane map 8 is enough -->
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@respawndelay">0.05</set>
	
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Day' and @entitygroup='ZombiesForestDowntown']/@maxcount">5</set> <!-- For Navezgane map 7 is enough -->
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Day' and @entitygroup='ZombiesForestDowntown']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='ZombiesForestDowntownNight']/@maxcount">5</set> <!-- For Navezgane map 7 is enough -->
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='ZombiesForestDowntownNight']/@respawndelay">0.05</set>
	
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Any' and @entitygroup='WildGameForest']/@maxcount">5</set> <!-- For Navezgane map 12 is enough -->
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Any' and @entitygroup='WildGameForest']/@respawndelay">0.15</set>

	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='WildGameForestNight']/@maxcount">1</set>
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='WildGameForestNight']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='EnemyAnimalsForest']/@maxcount">1</set>
	<set xpath="/spawning/biome[@name='pine_forest']/spawn[@time='Night' and @entitygroup='EnemyAnimalsForest']/@respawndelay">0.15</set>
	
	<!-- *** BURNT_FOREST_SPAWNS -->
	
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Day' and @entitygroup='ZombiesBurntForest']/@maxcount">6</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Day' and @entitygroup='ZombiesBurntForest']/@respawndelay">0.15</set>
		
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@maxcount">7</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@respawndelay">0.15</set>
	
		
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Day' and @entitygroup='ZombiesAll']/@maxcount">5</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Day' and @entitygroup='ZombiesAll']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Day' and @entitygroup='ZombiesDowntown']/@maxcount">5</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Day' and @entitygroup='ZombiesDowntown']/@respawndelay">0.15</set>
	

	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Night' and @entitygroup='ZombiesDowntown']/@maxcount">5</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Night' and @entitygroup='ZombiesDowntown']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Any' and @entitygroup='WildGameForest']/@maxcount">1</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Any' and @entitygroup='WildGameForest']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Night' and @entitygroup='EnemyAnimalsBurntForest']/@maxcount">4</set>
	<set xpath="/spawning/biome[@name='burnt_forest']/spawn[@time='Night' and @entitygroup='EnemyAnimalsBurntForest']/@respawndelay">0.15</set>
	
	<!-- *** DESERT_SPAWNS -->
	
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Any' and @entitygroup='ZombiesAll']/@maxcount">6</set>
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Any' and @entitygroup='ZombiesAll']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@maxcount">10</set>
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@respawndelay">0.15</set>

	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Day' and @entitygroup='ZombiesDowntown']/@maxcount">7</set>
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Day' and @entitygroup='ZombiesDowntown']/@respawndelay">0.15</set>

	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Night' and @entitygroup='ZombiesDowntown']/@maxcount">7</set>
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Night' and @entitygroup='ZombiesDowntown']/@respawndelay">0.15</set>

	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Any' and @entitygroup='WildGameForest']/@maxcount">1</set>
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Any' and @entitygroup='WildGameForest']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Any' and @entitygroup='EnemyAnimalsDesert']/@maxcount">4</set>
	<set xpath="/spawning/biome[@name='desert']/spawn[@time='Any' and @entitygroup='EnemyAnimalsDesert']/@respawndelay">0.15</set>
	
	<!-- *** SNOW_SPAWNS -->
	
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Any' and @entitygroup='SnowZombies']/@maxcount">3</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Any' and @entitygroup='SnowZombies']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@maxcount">4</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Night' and @entitygroup='ZombiesNight']/@respawndelay">0.15</set>
	
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Day' and @entitygroup='ZombiesAll']/@maxcount">5</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Day' and @entitygroup='ZombiesAll']/@respawndelay">0.15</set>
		
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Day' and @entitygroup='ZombiesDowntown']/@maxcount">5</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Day' and @entitygroup='ZombiesDowntown']/@respawndelay">0.15</set>
			
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Night' and @entitygroup='ZombiesDowntown']/@maxcount">5</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Night' and @entitygroup='ZombiesDowntown']/@respawndelay">0.15</set>
	
			
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Any' and @entitygroup='WildGameForest']/@maxcount">1</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Any' and @entitygroup='WildGameForest']/@respawndelay">0.15</set>
				
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Any' and @entitygroup='EnemyAnimalsSnow']/@maxcount">4</set>
	<set xpath="/spawning/biome[@name='snow']/spawn[@time='Any' and @entitygroup='EnemyAnimalsSnow']/@respawndelay">0.15</set>
	
	<!-- *** WASTELAND_SPAWNS -->
	
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Day' and @entitygroup='ZombiesWasteland']/@maxcount">40</set>
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Day' and @entitygroup='ZombiesWasteland']/@respawndelay">0.25</set>
	
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Night' and @entitygroup='ZombiesWastelandNight']/@maxcount">14</set>
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Night' and @entitygroup='ZombiesWastelandNight']/@respawndelay">0.15</set>
		
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Day' and @entitygroup='ZombiesWastelandDowntown']/@maxcount">55</set>
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Day' and @entitygroup='ZombiesWastelandDowntown']/@respawndelay">0.25</set>
	
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Night' and @entitygroup='ZombiesWastelandDowntown']/@maxcount">55</set>
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Night' and @entitygroup='ZombiesWastelandDowntown']/@respawndelay">0.25</set>
	
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Any' and @entitygroup='EnemyAnimalsWasteland']/@maxcount">4</set>
	<set xpath="/spawning/biome[@name='wasteland']/spawn[@time='Any' and @entitygroup='EnemyAnimalsWasteland']/@respawndelay">0.15</set>	

</configs>


Now you can either start Dedicated Server or Play in a game world and the amount of zombies should be increased.

Additional tweak: Add more different animals to the world biomes.

By creating a file C:\Program Files (x86)\Steam\steamapps\common\7 Days To Die\Mods\entitygroups.xml You can also adjust the kinds of animals spawned.

entitygroups.xml

<configs>
<!-- Try to Increase the none for more sparse animal distribution -->
<set xpath="entitygroups/entitygroup[@name='WildGameForest']">
			animalRabbit, 30
			animalChicken, 30
			animalStag, 2.5
			animalDoe, 2.5
			animalBoar, 5
			animalWolf, 2
			animalDireWolf, 1
			animalMountainLion, 0.5
			animalBear, 0.5
			animalSnake, 1
			none, 25
</set>
</configs>

Bloodmoon Spawning XML modlet

This modlet fullfills BloodMoonEnemyCount  of serverconfig.xml:

"Also note that your game stage sets the max number of zombies PER PARTY. Low game stage values can result in lower number of zombies than the BloodMoonEnemyCount setting."[1]

Set serverconfig.xml: BloodMoonEnemyCount to highest amount possible and this modlet will handle the rest.

BloodMoonEnemyCount should be also set equal to MaxSpawnedZombies setting or more.

All this just to not let MaxSpawnedZombies override BloodMoonEnemyCount which would override maxAlive="125" in the gamestages.xml

Mods\World_More_BloodMoon_Zombies\ModInfo.xml
<?xml version="1.0" encoding="UTF-8" ?>
<xml>
    <Name value="World_More_BloodMoon_Zombies" /> 
    <DisplayName value="World_More_BloodMoon_Zombies" /> 
    <Version value="21.0" /> 
    <Description value="World_More_BloodMoon_Zombies for A21.2 B30 inside 7DTD Dedicated Server and Single Player" /> 
    <Author value="VanillaServer" /> 
    <Website value="https://7daystodie.fandom.com/wiki/Mod_Structure" /> 
</xml>
Mods\World_More_BloodMoon_Zombies\generate.py

This is simple standalone program I've wrote that generates modlet file that modifies gamestages of the bloodmoon.

Generator of the bloodmoon gamestages that parses 7 Days To Die\Data\Config\gamestages.xml.

Generates a new gamestages.xml modlet xml file inside Mods\World_More_BloodMoon_Zombies\Config folder.

import xml.etree.ElementTree as ET

# Load the original XML file
tree = ET.parse("C:\\Program Files (x86)\\Steam\\steamapps\\common\\7 Days To Die\\Data\\Config\\gamestages.xml")
root = tree.getroot()

# Define the path where the new XML file will be saved
new_xml_file_path = "./Config/gamestages.xml"

# Create a new root element for the new XML structure
configs = ET.Element("configs")
configs.text = "\n\t"  # Add a newline character at the beginning

# Keep track of processed spawn groups
processed_spawn_groups = set()

# Iterate through each <gamestage> element
for spawner in root.findall(".//spawner[@name='BloodMoonHorde']"):
    for gamestage in spawner.findall("./gamestage"):
        for spawn in gamestage.findall("./spawn"):
            spawn_group = spawn.attrib['group']
            if spawn_group not in processed_spawn_groups:
                # Get the current maxAlive value
                max_alive = int(spawn.attrib["maxAlive"])
                # Calculate the new maxAlive value (half of the current value)
                new_max_alive = max(max_alive // 6, 1)
                # Construct the XPath expression for the <set> element
                xpath = f"//spawner[@name='BloodMoonHorde']/gamestage/spawn[@group='{spawn_group}']/@maxAlive"
                # Create a new <set> element with the constructed XPath and new maxAlive value
                set_element = ET.SubElement(configs, "set", {"xpath": xpath})
                set_element.text = str(new_max_alive)
                # Append a newline character after each <set> element
                if spawn_group != list(root.findall(".//spawner[@name='BloodMoonHorde']")[-1].findall("./gamestage/spawn"))[-1].attrib['group']:
                    set_element.tail = "\n\t"  # Add a newline and a tab for indentation
                # Add the spawn group to the processed set
                processed_spawn_groups.add(spawn_group)

# Append a newline to the tail of the last <set> element
configs[-1].tail = "\n"

# Create a new XML tree with the configs element as the root
new_tree = ET.ElementTree(configs)

# Write the new XML tree to a file with pretty formatting
new_tree.write(new_xml_file_path, encoding="utf-8", xml_declaration=True, method="xml", short_empty_elements=False)

print("New XML file created successfully at:", new_xml_file_path)
  1. serverconfig.xml file contains this comment on the BloodMoonEnemyCount