What's the point?
#51
Posté 08 février 2013 - 11:13
#52
Posté 08 février 2013 - 11:19
One of the things he suggests to lower problems with silent shouts is to make your hostile creatures members of custom factions rather than the standard Hostile one, so they're not all spamming each other with shouts.
Edit: Too slow!
Modifié par Squatting Monk, 08 février 2013 - 11:19 .
#53
Posté 08 février 2013 - 11:24
From the Omnibus:
OldMansBeard wrote...
It means, roughly, that you have a script somewhere that is using up too much processor time and locking out some other scripts that are trying to run. Many objects in the game will have heartbeat scripts that are automatically run every 6 seconds. But if it takes more than 6 seconds to run through them all once, the system has a problem and this is what it is trying to tell you.
<snip>
You might have an area with too many placeables and NPCs, each with a reasonable heartbeat script that takes only a little time to run but in total they are too much. But the engine will degrade gracefully in this situation and you would have seen the game get very laggy as you added more and more objects, before you started to get the error message.
Modifié par Squatting Monk, 08 février 2013 - 11:33 .
#54
Posté 09 février 2013 - 12:14
area-wideffbj wrote...
I think one thing I did was limit the call to a range, because isn't the normal call server wide?
what I did to solve this issue was to create a custom AI that uses only 4 events for monsters that dont have to be smart and that are being butchered by hordes such as spiderlings and other tiny vermins. They dont shout, they dont receive shouts and have no spellcast at script and these four scripts consist of few instructions to attack nearest seen enemy.
Still it doesnt solve much when player uses AOE spells agains them. Druid spamming SoVs, entangle, grease, stonehold still lock up CPU usage over 90% and causes module-wide lags. In fact just spawning around 100 these vermins increased CPU usage over 50%.
Due to this i believe there must be some hardcoded stuff like try to call the onspellcastat script even the creature has no assigned. Or players perception list being updated... dont know exactly, I can only recommend not to spawn so many creatures at once. If anyone interested I can release my low AI for situations like this, but like I said it doesnt help much.
#55
Posté 09 février 2013 - 12:22
I figure while I'm doing that I might as well optimize DetermineCombatRound, which is a disaster, to put it kindly.
Funky
Modifié par FunkySwerve, 09 février 2013 - 12:24 .
#56
Posté 09 février 2013 - 12:42
seems I have forgotten however, I was 4scripts in the beginning but later I had to add other events including heatbeat because creatures in certain situations weren't active
Keep in mind this is specifically designed for stupid creatures with no special abilities. Its not a generic low CPU AI. And due to the missing scripts it might misfunction (creature will not do anything) in certain cases such as casting spells onto target from corner where he cannot see you. This AI also wont call other creatures nearby to fight so creatures in group can be lured away.
There is a few lines of module specific code in OnSpawn such as variable based stealth spawn and despawn, and OnDeath is executing my 2DA xp system so you have to replace it with your own.
BTW: to optimize DetermineCombatRound is definitely good idea. I wanted to do it in my unofficial patch as well, but so far trying to keep the original code as close to default as possible for comparing reasons. Maybe later...
Modifié par ShaDoOoW, 09 février 2013 - 12:50 .
#57
Posté 09 février 2013 - 06:53
pope_leo wrote...
Lightfoot8 wrote...
The recursion level level is 0x100 or 256, It applies to all recersive function calls not just scripts. Extending it is a little more difficult then increasing the instruction count counter because its limit is based on the size of the buffer originally allocated for the storage of the return pointers.
I went back and double checked... there is a separate script execution recursion level that has a hard coded limit of 8.
Script a:void main() { object mod = GetModule(); int recurse_lvl = GetLocalInt(mod, "RECURSION_LEVEL"); SpeakString("Recursion Level: " + IntToString(recurse_lvl), TALKVOLUME_SHOUT); SetLocalInt(mod, "RECURSION_LEVEL", ++recurse_lvl); ExecuteScript("b", mod); }
Script b:void main() { object mod = GetModule(); int recurse_lvl = GetLocalInt(mod, "RECURSION_LEVEL"); SpeakString("Recursion Level: " + IntToString(recurse_lvl), TALKVOLUME_SHOUT); SetLocalInt(mod, "RECURSION_LEVEL", ++recurse_lvl); ExecuteScript("a", mod); }
The final print would be "Recursion Level: 7". There will be no feedback if it throws an error.
I found this interesting indeed, Though I do hate being the one proven wrong. I was planning on tracing the script through to learn a little more about how this is handled in the VM. I just have not found the time yet and do not know when I will, So I setteled for a different test for the moment. Unlike the TMI error that just stops every thing from running, This limit still allows the scripts that where ran to finish running, It just blocks the 9 script from running. I modified your script just a tad for the test.
void main()
{
object mod = GetModule();
int recurse_lvl = GetLocalInt(mod, "RECURSION_LEVEL");
SpeakString("Recursion Level: " + IntToString(recurse_lvl), TALKVOLUME_SHOUT);
SetLocalInt(mod, "RECURSION_LEVEL", ++recurse_lvl);
ExecuteScript("b", mod);
SetLocalInt(mod, "RECURSION_LEVEL", --recurse_lvl);
SpeakString("Recursion Level: " + IntToString(recurse_lvl), TALKVOLUME_SHOUT);
}The final print was "Recursion Level: 0".
EDIT: Due to request, here is the full Log Report.
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 0
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 1
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 2
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 3
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 4
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 5
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 6
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 7
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 7
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 6
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 5
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 4
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 3
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 2
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 1
[CHAT WINDOW TEXT] [Sat Feb 09 01:44:46] SERVER : [Shout] Recursion Level: 0
Modifié par Lightfoot8, 09 février 2013 - 02:59 .
#58
Posté 13 février 2013 - 05:01
Modifié par ffbj, 13 février 2013 - 05:06 .
#59
Posté 18 février 2013 - 04:58
{
object oSelf = OBJECT_SELF;
object oKill = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oSelf);
object oCheat = GetNearestObjectByTag("ZombieScan", oKill, 2);
if(!GetLocalInt(oSelf, "bash") && GetAttackTarget() == OBJECT_INVALID)
{
if(GetObjectSeen(oKill))
{
ActionAttack(oKill, FALSE);
}
else if(GetLocalInt(oSelf, "RUSH") == FALSE)
{
DelayCommand(60.0, SetLocalInt(oSelf, "RUSH", TRUE));
ActionAttack(oKill, FALSE);
}
else if(GetLocalInt(oSelf, "RUSH") == TRUE)
{
JumpToObject(oCheat);
DelayCommand(0.5, ActionAttack(oKill, TRUE));
SetLocalInt(oSelf, "RUSH", FALSE);
}
}
}
A few important notes, bash is used to make the zombies attack barriers when blocked by them(they are triggered to hit the barrier by a trigger on the barriers location which sets bash to true, upon the barriers destruction it sets bash to false and they continue, if the barrier doesn't exist then it won't set bash to true[I typed this out in case some players get any ideas from my server >.>]). The majority of the time only the very first parts of the code are -ever- used.
Modifié par Highv Priest, 18 février 2013 - 04:59 .
#60
Posté 18 février 2013 - 02:59
The general gist seems to be that zoombies don't care if the see you or not, which I do something similar to that. Sort of the detect life idea, so they will come at you regardless if you are in stealth invisible, etc..
As long as we are sharing zombie scripts here is one of mine:
redundant conditional checks.
zombie hb wander around attack chickens if available. ffbj
*/
//:://////////////////////////////////////////////////
//:: Copyright © 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 12/22/2002
//:://////////////////////////////////////////////////
#include "nw_i0_generic"
void main()
{
if (GetIsInCombat()) return;
//group with others and attack pc
object oEnemy = GetNearestSeenEnemy();
object oPC = GetLastPerceived();
int iTalentHR = TalentSpellAttack(oEnemy);
string sWPTag1 = "wp_random";//seed tag of wp. wp's must be placed.
string sRan = IntToString(d6()); //change dsize for more wp
string sWPTag = sWPTag1 + sRan; //selects wp_random1-6
location lWP = GetLocation(GetNearestObjectByTag(sWPTag));
float fWait = StringToFloat(sRan);
if (GetAlignmentGoodEvil(oEnemy) != ALIGNMENT_EVIL)
{
TalentBuffSelf();
DelayCommand (fWait,ActionAttack (oEnemy, iTalentHR));
DelayCommand (6.0, ActionAttack (oEnemy));//slow, methodical, thoughtful, zombies
}
else
DelayCommand (1.0,ActionMoveToLocation(lWP,TRUE));
object oTarget;
oTarget = GetNearestObjectByTag("Chicken");
location lWP1 = GetLocation(oTarget);
location lWP2 = GetLocation(oEnemy);
if (GetIsObjectValid(oTarget))
{
ActionMoveToLocation(lWP1,TRUE);
ActionAttack (oTarget);
return;
}
else if ((GetIsObjectValid(oEnemy) && GetDistanceToObject(oEnemy) < 15.0) && !(GetIsInCombat()))
{
ActionMoveToLocation(lWP2,TRUE);
ActionAttack (oEnemy, iTalentHR);
}
else if (GetTag(oPC) == ("Zombie"))
ActionMoveToObject(oPC,FALSE);//group with other zombies
}
#61
Posté 18 février 2013 - 06:27
EDIT= The "RUSH" is simply so they don't CONSTANTLY teleport. This prevents them from -always- being right on your tail no matter how fast you are. They can teleport, but they can only do it once every minute and outrunning them in that sense does infact work(for a brief period of time). The reason why "RUSH" isn't deleted using DeleteLocalInt is because that variable is likely to be constantly getting set/unset and since the zombies have only a few variables being assigned to them it's more economical to prevent the computer having to recreate the "RUSH" instance as opposed to simply changing it's definition.
Modifié par Highv Priest, 18 février 2013 - 06:34 .





Retour en haut







