Aller au contenu

Photo

What's the point?


  • Veuillez vous connecter pour répondre
60 réponses à ce sujet

#51
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Here's the link to the webpage:
Lexicon Lyceum, Lagbusting

Funky

#52
Squatting Monk

Squatting Monk
  • Members
  • 444 messages
Funky's Lag Busting Tutorial

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
Squatting Monk

Squatting Monk
  • Members
  • 444 messages
Prediction: HP's problem with many NPCs in one area is not a TMI error but an AI Update Time Overflow error.

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
Shadooow

Shadooow
  • Members
  • 4 465 messages

ffbj wrote...

I think one thing I did was limit the call to a range, because isn't the normal call server wide?

area-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
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
I'm interested. One of my upcoming projects is a revamping of my ai, which is still basically a dressed-up x2 ai with some performance tweaks (other than onspawn, where we run a seperate script to apply all sorts of item props and effects based on local vars). I want to add more complex target selection, in part so I can add new item props ala Dragon Age which draw aggro. We already do a little more targeting than the bioware default, which is just plain silly (they REALLY hate druids, for no particular reason), but nothing to write home about.

I figure while I'm doing that I might as well optimize DetermineCombatRound, which is a disaster, to put it kindly. :P

Funky

Modifié par FunkySwerve, 09 février 2013 - 12:24 .


#56
Shadooow

Shadooow
  • Members
  • 4 465 messages
ok here it is: LINK

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
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

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
ffbj

ffbj
  • Members
  • 593 messages
Informative thread. Thanks all.

Modifié par ffbj, 13 février 2013 - 05:06 .


#59
Highv Priest

Highv Priest
  • Members
  • 93 messages
void main()
{
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
ffbj

ffbj
  • Members
  • 593 messages
This seems a bit non-sequitor, but anyway I like idea of zombies smashing through barriers. I always got annoyed when flyers would be stopped by gates in the open, why not just fly over them, or cliffs, or tower etc... So I have mine do that. So the above seems to say if you can see the enemy attack them. If not and rush is not set it, wait for 60 seconds then attack. Finally if rush is set then jump to an object "Zombie Scan" I have no idea where that is, and attack the PC.
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
Highv Priest

Highv Priest
  • Members
  • 93 messages
"ZombieScan" are waypoints positioned around the map the zombies will teleport to. Because it's going by the second waypoint(and they are fairly spaced apart) it makes the zombies only appear to catch up to the players as opposed to directly teleporting to them.(Teleporting zombies is pretty lame when you can actually see it happening and although players can by being positioned in various positions around the map weirdly at least it's not blatant). Suffice it to say that basically "oCheat" is the zombies making certain the player didn't just outrun them like the black team in a foot race against a bunch of overweight white guys. The threat of the zombies -always- being nearby is there and you will never have a moment where you simply outran them and can just rest knowing you're completely safe.

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 .