Register to post in forums, or Log in to your existing account

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum

Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Apr 10, 2006 6:15 pm   

Loops, threads, #WAIT, #Priority and all that
Here's another example where zMUD programming can get complicated and "wierd".

Loops, such as #WHILE, #REPEAT, #LOOP, etc have always been a bit of a problem in zMUD. The code that handles this has evolved and been kludged over the years and I'm taking a second look at it.

At one time, I apparently decided that it would be useful to continue processing incoming text while a loop was operating. This started with changes to the #WAIT command, but extended into all of the other loops as well.

This caused some problems with triggers since you could start receiving new text and getting new triggers while a previous trigger was still processing.

So to "fix" this, I then added the #PRIORITY command which prevented new text processing on the commands within it.

The other side effect of all this is that you could get a bunch of multiple "threads" running various loops. These loops could get stuck and start causing all sorts of unusual problems and crashes during exit.

But zMUD doesn't actually use threads. zMUD is not threadsafe. This is because the original Winsock code in Windows wasn't threadsafe long ago. So zMUD has always avoided threads.

Threads can get complicated and can make an application very unstable if not used very carefully. I'm not yet sure that I can make CMUD "threadsafe" either, especially with the new database code that it uses. I haven't tested the database system to see how threadsafe it is.

The basic question that is raised is: Should triggers be executing in background threads, or in the foreground application?

When you execute in a background thread, you lose syncronization with the incoming MUD text, so you can't use #conditions or stuff like that.

The whole idea of triggers is to perform an action based upon input from the MUD. Seems like keeping in sync with the MUD is very important. The only reason I could see for wanting a background thread is to perform some complex calculation that is unrelated to the incoming text stream.

This also brings us to the #WAIT command. This command is responsible for most of the problems people have with scripts. I wrote a paper several years ago on the evils of the #WAIT command (See the Support/zMUD Support menu at the top of this page for the article list). But I know that people still use it.

I can think of two common uses of #WAIT:

1) wait for an interval of time to pass to handle stuff like forced MUD delays. You can set an #ALARM in a trigger instead of using #WAIT, but this seems cumbersome and complex for many people. Using #WAIT just seems easier, so people do that instead. You can use the new trigger conditions to split a trigger into multiple pieces separated by delays, but this also seems too complicated for some people.

2) wait for another line of text from the MUD that matches another pattern. I.e. "wait for this text..." Again, this can be done using trigger conditions.

Seems like all of the normal uses of WAIT can be handled with trigger conditions. So somehow I need to improve the user interface for creating and dealing with trigger conditions.

What I'd *like* to do is fix how loops are handled and *not* process incoming text while a command or loop is being executed. Essentially like always using the #priority command. I'd like to get rid of #WAIT completely and get people using trigger conditions more.

This would remove the kludged attempt to simulate background processing and would remove a lot of the unstabilities in zMUD caused by stuck background loops and wait commands.

But now we are talking about more serious compatibility issues with zMUD. So let's have a discussion of this.
Reply with quote

Joined: 10 Oct 2000
Posts: 856
Location: USA

PostPosted: Mon Apr 10, 2006 7:26 pm   Re: Loops, threads, #WAIT, #Priority and all that
Zugg wrote:

What I'd *like* to do is fix how loops are handled and *not* process incoming text while a command or loop is being executed. Essentially like always using the #priority command.

Make the change (scripts complete before new input is accepted). If someone's looping script is slow, that's something they can be helped with. If their scripts have weird timing issues, that's a lot harder to troubleshoot.

Users sophisticated enough to want background processing can implement it themselves with timers firing off a few loop iterations each time.

I can see two possible ways to handle #WAIT:
1) all scripts stop for the duration of the #WAIT
2) break out of that particular script and return after the #WAIT period (potentially a little confusing for novices if they change variables in the meantime, or if they wind up with several copies of a function running)

Both raise problems as far as what to display in the meantime given the possibility of subs and gags.

Reply with quote

Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Mon Apr 10, 2006 8:23 pm   
Definately ditch #WAIT. As you said, the vast majority of people that use it use it because they don't know better. Those that do know better will be able to fix any scripts that break because of it.

Maybe leave the command in but make it so that
#WAIT 1000

Does what
#ALARM waitLegacy +1000

currently does. So it doesn't break many things, but instead converts or acts like it should do?
Reply with quote

Joined: 10 Oct 2000
Posts: 1551
Location: Australia

PostPosted: Mon Apr 10, 2006 10:33 pm   
For the most part I want my #WAIT's to be #ALARM's.... eg wait 5 seconds, then send a command to the mud. I think keeping the syntax there is probably important, nested #ALARM's get kinda confusing, so if there was a way you could:

#SEND north
#WAIT 1000
#SEND knock gate
#WAIT 3000
#SEND north

and have it automatically convert when processing / compiling 'silently' to:

#SEND north
#ALARM +1000 {
  #SEND knock gate
  #ALARM +3000 {
    #SEND north

For 95% of all triggers I don't think it's necessary to have any background processing - most of them you want to execute right away and are very fast so it doesn't slow your buffers down at all.

That being said, I think there is a definate value to allowing some processing to happen in a background thread - for example, I have a database that logs every kill I make and how much exp I get etc. The triggers there have to fire some ADO commands etc which are usually pretty quick, but I would still prefer to have them operating in a background thread if possible. Likewise when I do a query to see how much exp I gained in the last hour / day and how it compares to the previous hour / day and which was the most rewarding monster and least rewarding monster, and so on... all that could be collated in a background thread without impacting my play experience.

So... I kinda want both - the new syntax for #WAIT which makes more sense, and a checkbox 'process trigger/alias/button in the background' which executes whichever trigger/command/etc in a worker thread.

I would also propose a #BACKGROUND { some;commands;here } command for inside a trigger/etc, which an optional #WAIT forBackgroundProcessToComplete if you wanted to do some processing at the start, then some non-critical processing in the background, then finally a little more processing at the end.

It's probably a bit complicated for beta 1.0 but it's probably a good idea to implement.
Reply with quote

Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Apr 10, 2006 11:08 pm   
Well, most of ADO and most COM objects are not threadsafe, so I doubt I'll do that kind of background processing.

What I'll probably do is eventually let you just use the THREAD object from zApp in your scripts. And then let you worry about what works in a thread and what doesn't.

Another idea is to send your "background" stuff to another window and let it process stuff there. Each window is independant and something running in a child window shouldn't cause the main window to pause.

But yeah, any background processing commands will have to wait a while. Making everything threadsafe is a lot of work. For example, I had to kludge stuff in zApp because the Microsoft scripting engine isn't even threadsafe.
Reply with quote

Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Apr 11, 2006 12:46 am   
I would actually like to see the #PRIORITY command elminated by bring all loops back into real time processing. This change would essentially not affect users at all since #PRIORITY could simply be made into a do nothing type of thing; to quote the Windows API help, "this function has been deprecated." The speed gains shown from compiling scripts should strongly overcome the original need that lead to moving loops into the 'background'.

#WAIT still has a use, but its use should be adjusted to something like Rainchild suggested. As an automatic shortcut for building alarms it serves the purpose it is truly needed for, a time delay between a series of commands being sent to the mud.

I have seen background loops get stuck from time to time working on my scripts, and often it takes a little while to figure out why everything is slowed down. However it is a lot worse when it is a stuck foreground loop. I would say improve handling there so that all loops have an iteration limit somewhere in the range of 100K. Once the limit is reached it is fair to assume the loop is stuck and kill the script with an error message. This offers another type of loop detection to users, sometines it is just to easy to make a bad loop with a mispelled variable.
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote

Joined: 25 Mar 2003
Posts: 1113
Location: USA

PostPosted: Tue Apr 11, 2006 1:40 pm   
I can say with fair certainty that the change to loops has caused me some pain in getting my complex scripts working. Sometimes just adding the #PRIORITY to it fixes it, but I didn't want to do that for every single loop (and didn't realize that all loops were changed to essentially run in the background, either).

I always tell people not to use #WAIT, and I do my best to avoid it in my own scripts. There are very few situations where I find it useful, and where an alarm or a wait state is much more difficult. For example, Achaea only lets me send 20 commands a second, so if I want to do more than that, I add a short wait in my loop, like when I'm picking up 50 vials one at a time (because there are lots of vials and I'm going for specific ones, based on a string list of recorded ID values). I simply do "#loop {get %item(@myvials, %i);#wait 200}" to space out the commands a little.

It would be very nice to have the option of multi-threading code or just doing some background processing, but foreground processing synchronized with the MUD should definitely become the default mode of operation. Some scripting languages support threads, so if zMUD supports those scripting languages, we could always try to make use of the threads they provide us.
Reply with quote

Joined: 29 Nov 2005
Posts: 482

PostPosted: Wed Apr 12, 2006 12:21 am   
i use wait at times to allow for applicable parsing of like a who list then turning off the class since i have no END LIST text.

However personally i would like to see #WAIT removed altogether.

Remember new product better to make the change and have a few ppl redo their scripts. Just add a note to a text file

#WAIT has been depreciated please use #ALARM
EXAMPLE: goes here

All things i think should be processed in the foreground as i believe someone else noted the background processing would be an extremely advanced situation and those users will probably figure another way to handle that through looping iterations anyways.
Confucious say "Bugs in Programs need Hammer"
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Page 1 of 1

Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by