"Turning run away script off

Here you can post threads requesting help on the official POL Ultima Online Emulator Core 098.

Moderator: POL Developer

Post Reply
phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

"Turning run away script off

Post by phao » Mon Dec 20, 2010 9:58 pm

Is there any value I can set in pol.cfg to turn runaway scripts off?

Currently, I have it set up to a really big value (2^31-1, since it's a long). But I'd like to turn it off.

does setting it to 0 or -1 turns it off?

xeon
Forum Regular
Posts: 333
Joined: Fri Oct 31, 2008 3:18 am
Location: Italy

Re: "Turning run away script off

Post by xeon » Tue Dec 21, 2010 1:43 am

Changing pol.cfg runaway value is a bad practice.

I suggest you to set it back to its default value, and instead use in your scripts the SetScriptOpt(SCRIPTOPT_NO_RUNAWAY, 1);

http://docs.polserver.com/pol096/single ... e=osem.xml

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Tue Dec 21, 2010 6:18 am

Why is it a bad practice, specifically for the run away script configuration?

xeon
Forum Regular
Posts: 333
Joined: Fri Oct 31, 2008 3:18 am
Location: Italy

Re: "Turning run away script off

Post by xeon » Wed Dec 22, 2010 1:07 am

Because the solution to a bad coded script is not change the system on which it runs on, but to fix the script, or, when not possible, make it not complain.

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Wed Dec 22, 2010 3:42 am

From the POL Performance Guide.
If your scripts go runaway like this, it means something is wrong. If you have to perform very long loops, you should add some sleeps. Let me repeat, there is never a good reason to let scripts go runaway.
The funny thing is that, as you didn't, the guide doesn't tell me why runaway scripts are bad. Performing long loops is a common practice in all kinds of program. Imagine in a game, which is normally much more complex than many more other types of programs (even excluding many parts of the development, as we do here). For example, AI is not done by the UO Client, or by POL core: it's done by the scripter, and AI is very complex - it may require long loops.

But even not so long loops (let's put it 5000 repetitions). Sleeping 1ms per reptition would cause a wait of 5 seconds. Imagine that in the middle of the combat (searching for ammonition could do that: a really full bag would have that many items in some servers). Looping through all online players could do that (I belive that's rare for today, but it's a possibility).

Those cases I mentioned are extreme: a bag with 5000 items (that's not allowed in most shards), 5000 players online. However, waiting 5s doesn't only come from sleeping 1ms each repetition in a loop that repeats 5000 times. It could come from 10 loops that repeat 500 times each, and that's not rare. It could come from 100 loops that repeat 50 times each, which is actually common.

Look. Some people don't sleep 1ms. Some do 3ms or 4ms. I've seen 10ms. Imagine in a combat. Casting a spell. The script has to spend 3 regs. Supposing the regs are all stacked in one item, and a bag can hold 125 items, that could lead to a wait of 1s (for the 3ms sleep), or 1.5 seconds (4ms), or 3.7s (10ms). I can't see how that is not "bad code". Even waiting 1ms, could lead to a wait of 0.4s (almost), which makes some difference during combat. It's not hard to actually see how much time can be wasted by sleeping around.

I really don't like making this comparison, but I cannot let it out. Go tell another programmer developing something that he should put sleep calls to sleep 1ms or 2ms for each repetition of a loop, in a C program, or C++, or Java, or any other program, or any other language.

I'm guessing some things here:

1. You don't know why runaway scripts are bad.
2. Runaway scripts were made to prevent some kind of long loops running on critical scripts, which would cause the whole server to freeze.
3. Most people who add the sleeps don't know why it's done.

And, by suggesting that programs with long loops are "bad code", you have no clue how dumb you made yourself look like. Not to mention the suggestion to make the code not send a warning about the bug (for a moment I thought you were thinking that long loops were a signs bugs). Are you hiding bugs from the other scripters of your shard? :)

Now, if someone knows why runaway scripts are bad, plz, tell me. I'd like to know. I couldn't find anywhere why they are bad. It seems that the POL Performance Guide on the docs doesn't tell why they're bad: it just says they are.

xeon
Forum Regular
Posts: 333
Joined: Fri Oct 31, 2008 3:18 am
Location: Italy

Re: "Turning run away script off

Post by xeon » Wed Dec 22, 2010 4:05 am

A runaway script is just a script which occupies too many cycles at once on POL. The setting in the .cfg tells POL when alert you that a script is burdening it.

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Wed Dec 22, 2010 4:10 am

Sorry. I still don't see why that is a bad thing.

And, I thought that if a script is spotted as runaway, it'd stop executing. Is that right?

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Wed Dec 22, 2010 6:23 am

Talking to kevin, on the IRC channel, I found out that the script is not stopped if it's spotted as runaway. This whole thing is just a warning.

I thought that the script was actually killed if it got marked as runaway. It's not.

Now I see the point in the whole thing.

I still don't get why they are considered a bad thing though. I see that there aren't many reasons why a loop would repeat more than 5000 times or so, but I don't think I see the danger you see.

Turley
POL Developer
Posts: 654
Joined: Sun Feb 05, 2006 4:45 am

Re: "Turning run away script off

Post by Turley » Fri Dec 24, 2010 3:04 am

The reason runaway scripts are bad is simple.
Pol has one scriptthread this thread loops through all currently running scripts and iters through the instructions.
So far so good, but it keeps executing one script till the script is somehow blocked.
Blocked means program exit, breakpoint, sleep, WaitForEvents,....
I think this should explain the problem with runaways.

e.g.: Your problem with looping through a bag: simply use FindSubstance or ConsumeSubstance, faster search cause the loop is 100% coreside plus no problem with runaways since its only one instruction.

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Fri Dec 24, 2010 3:12 am

Aren't new scripts started on their own threads, so each thread runs a different script?

I wasn't expecting POL to implement its own threads.

--

And, I don't need to sleepms(1) then... I could just wait_for_event(0) then, and I'd not waste any aditional time. Right?

Turley
POL Developer
Posts: 654
Joined: Sun Feb 05, 2006 4:45 am

Re: "Turning run away script off

Post by Turley » Fri Dec 24, 2010 4:35 am

One thread foreach client, but only one for scripts.

Nope Wait_For_Events(0) doesnt work sorry :)
And you dont need to add a sleep inside the "root" of the loop eg you could do something like
foreach blubb in blah
...
if (!(_blubb_iter%100))
sleepms(1);
endif
endforeach
this way you only sleep every 100 times.

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Fri Dec 24, 2010 12:29 pm

Before posting this thread, I was testing stuff about this, and I actually tried this solution you suggested.

Don't you think this could be added to the core? Maybe to be set on/off on pol.cfg... I mean, "CallSleep1Every=100" would do what you just described, but for all loops in all scripts.

User avatar
*Edwards
Forum Regular
Posts: 301
Joined: Fri Dec 28, 2007 11:19 pm
Location: Montreal, Canada

Re: "Turning run away script off

Post by *Edwards » Fri Dec 24, 2010 1:00 pm

Agreed with the internal core function SleepMS(1) every 100 loops. Or a custom value.

That would help a lot.

phao
Grandmaster Poster
Posts: 129
Joined: Fri Aug 31, 2007 2:25 pm
Location: Brazil

Re: "Turning run away script off

Post by phao » Sat Dec 25, 2010 2:37 am

Another suggestion would be to create a ForceBlockPoint(), to force one of those block points, like you mentioned, without wasting miliseconds or having to add those constructions to sleep once each 100, or anyother number, repetitions. But I prefer the configuration in pol.cfg file.

User avatar
CWO
POL Expert
Posts: 1148
Joined: Sat Feb 04, 2006 5:49 pm
Location: Chicago, IL USA

Re: "Turning run away script off

Post by CWO » Tue Dec 28, 2010 2:37 am

I had a pretty good conversation in IRC with you about this but for anyone searching this thread in the future, here's the highlights of the way I do things in POL.

A lot of scripters have this mentality of "I need to get everything done and I need to get it done now." But remember this is UO, this is a slower paced game that isn't time critical. Things can be slowed down just a bit. Here's some things that in my opinion, should be on scripters' minds when developing a shard. I've also put quite a few examples of things I've done on my shard in here mainly to explain my points better.

Players can wait a half a second
There is ALMOST NEVER a need to give an instant reaction to a player. This goes for things like generating gumps and iterating over items in the player's backpack. This isn't a First Person Shooter where what I need, needed to be done 10 seconds ago. A half a second is a good amount of time to slow your scripts down to. I'm not saying go into all of your scripts now and put a sleepms(500) or a sleepms(100) in a 5 iteration loop, but you can slow things down to the point where your sleepms's can add up to 500 and the player simply won't even notice. Half a second isn't rushing it to completion and it's also not a really noticeable amount of time to wait.


Put as much as you can in backhaul that sleeps a lot (BUT ONLY IF IT SHOULD SLEEP!)
This is hard to explain, its better to look at my next highlight to get a better example of what I'm trying to say.

Don't do things in very frequently called scripts that don't have a direct effect on the result you're trying to achieve.
One example of this is skillcheck. Skillcheck does skillgain. Why? Well sure when you're checking the skill, you're probably using it and should gain but why does the check have to wait for the gain to complete when the gain doesn't directly affect the result of this check. It could affect later checks but not this current one. I made my skillgain a separate script that's event based and made skillcheck just send the event with the info to skillgain. Skillcheck was designed for one purpose, check the skill, not specifically to gain the skill. Let another script worry about gains and lets get the check done so the calling script can move on. Now Skillgain shouldn't have to have enough instructions to sleep so this is an example of a backhaul script that SHOULDN'T sleep.

Script priority, learn it!
Yes the default script priorities for the different script types in POL make sense but defaults can never account for every situation. Learn the priority system and set the number low for scripts that don't need to be done quickly and give a few other scripts a bump if needed. Priority in POL is the number of instructions a script executes before switching and doing instructions in another script. POL is doing every single script at once and only has one script thread so it can only execute one instruction in one script at a time.

Making your scripts run away can cause everything to be slower.
Script lag is a very real thing. Its when all scripts run slower because every script is trying to do too much too fast. Once you learn about how the priorities work, the fact that POL has only one script thread for all scripts, and the limits to how many instructions your computer can do in a period of time, you'll learn exactly how monumental sleep/sleepms is on those instructions that can seriously wait until later.

In a cause/effect relationship, calculate everything on the one that runs the least amount of times...
Oh boy, medcheck/medloss on my shard comes to mind for this one. Equipping an item like plate armor of course makes mediation run slower. Well, meditation is entirely run in the regen but I saw at least on my shard that every time someone would regen mana, it would iterate through all equipped items to calculate medloss... That's a hell of a lot of calculating because of how many times mana regen is run! Sure the regen needs to know the result of this calculation but the number of times every player on my shard equips/unequips items in a period of time is a whole heck of a lot less than the number of times mana regen runs. Put the calculation in the one that runs less and save it to a CProp if you have to!

Setting sleepms lesser than 5 is just a waste of code.
Seriously, if you're gonna sleep, make the sleep worth it to your system!

Keep the runaway threshold in your pol.cfg at least under 10000, preferably <=5000.
Challenge yourself to keep this threshold as low as possible and still script so that no scripts run away. Can you believe my shard is currently set to 2000? And that only 3 scripts have the No Runaway script option and they only run in the first minute after the shard boots up? There are times where I make changes or new scripts and get a good runaway. But this doesn't cause me to set the script option to no runaway, no, this causes me to rethink the script and make it so it does things more efficiently and more effectively. Sometimes its not about adding sleeps, its about thinking of a better way to do it. Cache repetitive things like static gumps or static parts of gumps in data files so your server doesn't have to keep rebuilding them over and over again (This is if you use functions to build gumps, not if you create raw arrays yourself). Challenge yourself to find better ways of doing things more efficiently. It'll make you a better developer and leave a lot of unused power for those awesome features you're gonna make later! :D

Enjoy

User avatar
andenixa
Grandmaster Poster
Posts: 105
Joined: Tue Nov 09, 2010 1:33 am

Re: "Turning run away script off

Post by andenixa » Thu Dec 30, 2010 8:14 pm

If you just want to turn off the runaway warning (and you are totally sure the message isn't caused by an infinite loop), just put these lines to the start of your script:

use os;

SetScriptOpt(SCRIPTOPT_NO_RUNAWAY, 1);

Adding sleepms(5) to you loops is a NO, as it could easy delay the output for a good half a minute (given sufficient cycles). Its a totally senseless way.

Weird stuff, like thats is a double NO:
if (!(_blubb_iter%100))
sleepms(1);
endif
The overhead will consume more CPU cycles than your code itself.

Increasing the runaway threshold is evil, because you won't know if something goes wrong for the rest of your scripts.
Neither I recommend decreasing it; it will slow down your development trying to fit the newly created constrains. Your goal is to provide comfort for the players, not to the server.

User avatar
CWO
POL Expert
Posts: 1148
Joined: Sat Feb 04, 2006 5:49 pm
Location: Chicago, IL USA

Re: "Turning run away script off

Post by CWO » Sat Jan 01, 2011 8:22 pm

If you don't provide comfort for the server, it isn't going to serve your players in an efficient way. Things will slow down and get delayed if you try to do too much too fast. I have personally seen this for myself when I inherited my shard. Giving your less time sensitive scripts a sleepms(5) can give your server time to do about 5000-7000 instructions in more time sensitive scripts. So yes, that code snippet could also add more efficiency because it sleeps every 100 iterations and costs about 3-5 instructions per iteration. 500 instructions to see if it should sleep for about 1200 instructions. I have yet to see a use to have a million instructions executed by a script and have to be done within 1 second that isn't a function of the POL Core itself...

Post Reply