Full Version : How Do I - Use SmartSpawning?
xmlspawner >>XMLSpawner - How do I? >>How Do I - Use SmartSpawning?
<< Prev | Next >>
ArteGordon- 12-29-2005
What is SmartSpawning?
SmartSpawning is a system to reduce mob/item counts and memory load by regulating spawning based on player activity.
In areas where there is no player activity (no active sectors within the spawn range of the spawner, or in the spawning region if defined), all spawns will be removed and the spawner will be placed in an inactive state until it is activated by a player entering its active range (an active sector in its spawn range).
To use this feature, just set the SmartSpawning property on a spawner to true. When the spawner is fully respawned and no players are detected, it will remove all spawns. When it detects player activity in range, it will fully respawn again making it appear as though it had simply been left in the fully respawned state.
It is somewhat similar, but complementary, to the PlayerRangeSensitive mod which reduced cpu load by regulating mob ai.
SmartSpawning reduces memory load by regulating spawns.
In testing, use of this feature resulted in a 20-50% reduction in memory usage, total mob/item counts, and save times. This will vary based upon player activity, total number of spawns, an proportion of spawners set to use the feature.
To see what the best-case improvement might be, you can do a "[global set smartspawning true where xmlspawner" and then watch as the item/mob count drops (or if you are impatient you can also do a "[global set nextspawn 0 where xmlspawner" to see the effects immediately).
To undo it just set them back with "[global set smartspawning false where xmlspawner".
This can also reduce cpu load if a shard is using PlayerRangeSensitive=false since it reduces the number of mobs with active ai. In testing, I was able to run with PlayerRangeSensitive set to false (i.e. all mob ai active all the time) and only 5% cpu load on server that otherwise would be running at 50% load without smartspawning set.
How should I set it up?
To quickly configure your spawners for smartspawning, the easiest thing to do is to use the command
[OptimalSmartSpawning [max home/spawnrange diff]
You can simply call it with no arguments, like
[OptimalSmartSpawning
This is a convenient way to quickly set up spawners for smart spawning in a way that will be most transparent to players. This will evaluate all xmlspawners and set the SmartSpawning property to true on those that look like good candidates based on several criteria. First, it looks to see whether there are any basevendors being spawned on it. This includes things like wandering healers. If they are found, then smartspawning is not set. If the homerange exceeds the spawnrange by more than the default of 1 tile (this can be changed by passing it an integer value), smartspawning will not be set. It will not be set on any proximity triggered spawner.
Note, there is no harm in setting smart spawning on spawners other than the ones selected by [optimalsmartspawning, or on all spawners for that matter. The optimal setting is simply what will make the smart spawning look as transparent as possible. When smart spawning is set up using [optimalsmartspawning, it is unlikely that anyone will be able to tell that the feature is being used, other than the fact that memory use, item/mob count, and save times will all be reduced.
If you wish to increase the number of spawners that get set to smartspawn with this command you can try increasing the homerange/spawnrange difference allowed with something like
[optimalsmartspawning 100
This just means for a given spawner that if the homerange is larger than the spawnrange by up to 100 tiles, it will still set it to smartspawn.
The reason it uses this test is that if the homerange is larger than the spawnrange, it is possible that existing spawns could have wandered beyond the initial spawnrange when the spawner despawns them, and so when they are smartspawned back into that spawnrange, distribution of creatures would be slightly different than the distribution when it was despawned and players may notice this.
It is just a cosmetic thing.
You can check on the status of your smartspawned configuration with the command
[SmartStat
This will give you statistics on how many spawners are configured for smartspawning, and your current savings due to smartspawning.
By default, all players and staff will activate smartspawned spawners. If you wish to change that behavior so that staff do not active them, you can call the [smartstat command with an additional argument, like this
[SmartStat [accesslevel Player/Counselor/GameMaster/Seer/Administrator]
Players with an AccessLevel above the level specified will not activate smartspawned spawners.
So, for example, using the command
[smartstat accesslevel player
Will change the smartspawning access level to Player so that only players will activate smartspawned spawners.
Note, this setting will not be saved across server restarts. For permanent change in the accesslevel setting, change the value of the static SmartSpawnAccessLevel variable in xmlspawner.cs
Additional configuration options
You can also prevent individual mobs from being despawned during smartspawning by adding the HoldSmartSpawning method to their class and having it return true.
For example, I suggest adding this to your BaseCreature.cs

CODE
public virtual bool HoldSmartSpawning { get { // dont smartspawn paragons
if(IsParagon) return true;
// dont smartspawn rummaging mobs
if(CanRummageCorpses) return true;
return false;
}
}

and make sure that you have added this to the top of the script as well

CODE
using Server.Engines.XmlSpawner2;

This will prevent paragons and rummaging mobs from being despawned during smartspawning, that way if a player finds a paragon mob, and then leaves and comes back to kill it, the same mob will be there.
Also, with rummaging mobs, you might not want them to be despawned since they might have picked up things from player corpses.
An even better solution is to flag mobs that have actually rummaged instead of just blocking all mobs that are capable of rummaging. This will further optimize your smartspawning.
You can do do this by making the following changes in your basecreature.cs. In the OnThink method, flag mobs that have rummaged by tagging them with an attachment (XmlData is handy for this) and giving it the name "HasRummaged".

CODE
public virtual void OnThink() { if ( EnableRummaging && CanRummageCorpses && !Summoned && !Controled && DateTime.Now >= m_NextRummageTime ) { double min, max;
if ( ChanceToRummage > Utility.RandomDouble() && Rummage() )
{
min = MinutesToNextRummageMin;
max = MinutesToNextRummageMax;
// ARTEGORDONMOD
// flag mobs that have rummaged
XmlAttach.AttachTo(this, new XmlData("HasRummaged"));
}
else
{
min = MinutesToNextChanceMin;
max = MinutesToNextChanceMax;
}

Then in your HoldSmartSpawning method, test for the XmlData attachment with that name.

CODE
public virtual bool HoldSmartSpawning { get { // dont smartspawn paragons
if(IsParagon) return true;
// dont smartspawn mobs that have rummaged
if(XmlAttach.FindAttachment(this, typeof(XmlData), "HasRummaged") != null) return true;
return false;
}
}

This way, only mobs that have actually rummaged will be prevented from despawning.
djkee- 11-23-2007
I am sorry if i am wrong or i should not post this here.
When i was doing those changes i got a error and i realized that i have to change the "using" on top of basecreature.cs
Here is the original

CODE
using System; using System.Collections; using System.Collections.Generic; using Server; using Server.Regions;
using Server.Targeting;
using Server.Network;
using Server.Spells;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Engines.Quests;
using Server.Factions;
using Server.Spells.Bushido;

This is how it should look like.

CODE
using System; using System.Collections; using System.Collections.Generic; using Server; using Server.Regions;
using Server.Targeting;
using Server.Network;
using Server.Spells;
using Server.Misc;
using Server.Items;
using Server.Mobiles;
using Server.ContextMenus;
using Server.Engines.Quests;
using Server.Factions;
using Server.Spells.Bushido;
using System.Xml;
using Server.Engines.XmlSpawner2;

Please delete this post if i am wrong or i should not be posting this for any reason.
Thank you
ArteGordon- 11-23-2007
you just need to add this
using Server.Engines.XmlSpawner2;
you dont need
using System.Xml;