|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Thu May 03, 2007 10:41 pm
Scripts within a window creates triggers outside the window |
I have a strange bug I get sometimes. Not sure exactly how to make it happen on purpose.
What happens is that I in a script creates a variable and a trigger. Usually CMUD places these in the root of the window in which the script itself is located. But sometimes it creates the trigger outside the window. If the trigger depends on the variable it might never fire and when CMUD gets in this mode I usually have no choice but to close it down. When I do this an error always occur.
Has been a problem at least since 1.29 - possibly before. I run 1.32 now.
In my setup I have three windows and the map open. There is a main window which receives output from mud and where I have my command line and all my scripts. Then I have two other windows I use to put stuff I gag from the main window.
Another annoying thing I have had to live with ever since I switched to CMUD is that whenever I run a script and then while it runs activate one of the other windows it affect the script badly so it doesn't execute as planned (seems like it skips waiting for triggers and alarms). This never was a problem in zMUD. |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Fri May 04, 2007 12:06 am |
The best thing to do is post the scripts so we can help you debug them.
|
|
_________________ Asati di tempari! |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Fri May 04, 2007 9:58 am |
Really, Tech, it has nothing to do with the scripts. CMUD is not supposed to place triggers and variables outside the window of which you created them.
It's not too easy for me to post the script as it is not one but a whole package of triggers, variables and aliases working together. I can assure you though that the variables are created the most simple way like below.
#TRIGGER {textToTrigger} {somethingToDo}
Ok, most of the times this works fine. It seems that the error is somehow related to several windows being in action or perhaps when map is active. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Fri May 04, 2007 5:39 pm |
Quote: |
CMUD is not supposed to place triggers and variables outside the window of which you created them. |
That's not necessarily true. CMUD creates scripts in the current class and current module, which can be changed with the #CLASS and #MODULE commands. Also, if something is created by a trigger, then it gets created in whichever window received the text that caused the trigger to fire (not necessarily the same module that contains the trigger that fired).
So, if one of your other windows is getting the text that causes a trigger to fire, then the trigger will be executing within one of those other windows.
Changing windows shouldn't effect your scripts, unless you are doing something bad like using the #WAIT command. Otherwise CMUD does not interrupt your scripts while executing.
But as Tech said, without seeing more details of the scripts, it's hard to help more. It's some complex interaction of your scripts and windows that is causing this. And without a simple way to reproduce the problem, there is no way to tell if it's a bug in CMUD or not, and certainly not something I can reproduce and hope to fix. |
|
|
|
Troublemag Wanderer
Joined: 14 Jul 2004 Posts: 83
|
Posted: Sat May 05, 2007 1:13 am |
I have something similar that occurs. In my case, I will have 2 mud connections open (to the same MUD - it allows multiplaying) and a chat window. For one of the skills on this MUD, you have to hunt the trainer every 24 hours and if he's on the overland vmap, this can take a while, so I've come up with a small script to handle this. One part of this script is to execute a #menu {file|reconnect} when I find the trainer. What happens, however, is that if the 2nd window is the one active (ie my cursor is blinking in the command line for that window), when the reconnect trigger fires, it fires in the active window instead of the window running the script.
This seems to be contrary to what I'm understanding from Zugg's post. |
|
_________________ CMUDPro 3.22 |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Sat May 05, 2007 9:18 am |
Well, I may not have made myself clear before. The trigger is not created in another window - it is created outside all the windows, on same level as the windows. If I happen to find out how to trigger this "feature" every time I will try to make an example and post it, but it is not easy as it is the same code that normally works fine that suddenly under circumstances I do not know yet suddenly blows up. It would be nice if you could see a little more of what CMUD is doing at a given moment. It's not easy to debug when you have no idea what's going on in the engine room.
About the #WAIT command. I don't know why you label it as bad. You put it there yourself and personally I find it a very useful way to kill some time when waiting for feedback from the mud or when I am in roundtime (I'm playing Dragonrealms) and I want to wait a second between updating my roundtime gauge. In all other programming languages I've used there is a similar command and they work fine. Why can't you make #WAIT work fine aswell? And why did zMUD not have this problem? It didn't skip anything because I activated another window and I used the #WAIT command there too. If you have the "good" way to wait a second I'd love to see it. I have asked for this on the forum before but didn't get any good suggestions. And since #WAIT is bad I suggest this alternative way could be put in the manual under the #WAIT command so that users who needs to put a little pause into their scripts can see how it should really be done. |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Sat May 05, 2007 12:58 pm |
kjaerhus wrote: |
About the #WAIT command. I don't know why you label it as bad. You put it there yourself and personally I find it a very useful way to kill some time when waiting for feedback from the mud or when I am in roundtime |
The reason #WAIT was kept was for compatibility so that folks who used it in their scripts from zMUD did not immediately have everything broken. CMUD does not process incoming text so that will be blocked. If you are waiting for a particular input from the MUD it sounds like you want a trigger, or even a temporary trigger (#TEMP) if you don't want it to be permanent. Or better yet use a #ALARM. I see from your other post that you didn't want to use #ALARM maybe you can give them another chance now.
If you are waiting for the Roudtime then consider using #EVENT with onTick in combination with alarms.
I'm curious exactly what feedback are you waiting for from your MUD?
As a side note, #WAIT may get revamped at some later date, but I believe it will be later rather than sooner. |
|
_________________ Asati di tempari! |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Sat May 05, 2007 3:17 pm |
Well, I tried using #ALARM but it is not exactly doing what I need it to do. After having had a lot of trouble with it for some days I decided to stick with #WAIT as this seems to have only the one negative consequence as I described here.
What I need to wait for is every command I give the mud to complete basically. When scripting I need to make sure that the first command is completed before launching the next. For instance if I need a tool in a closed bag I want to open the bag, wait for mud to say something like "you open your bag" and then take the tool from the bag. For this to work I have to take small breaks in my scripts all the time. This is what I use #WAIT for. I also like to use it when my mud says that the last command I gave it has a roundtime. Then I capture the roundtime, set up a gauge and updates this gauge every second until roundtime is over. |
|
|
|
Progonoi Magician
Joined: 28 Jan 2007 Posts: 430
|
Posted: Sat May 05, 2007 3:53 pm |
I think you can solve the break issue simply by making all the stuff you need go through condition triggers which execute the command you need in a row depending of all the output from mud you get. Just an idea that can well be a long shot (I'm not very good at cond/state trigs myself yet, though).
Prog |
|
_________________ The Proud new owner of CMud.
--------------------------------
Intel Core i5-650 3,2GHz
4 DD3 RAM
GTX 460 768MB
Win 7 Home Premium 64x
-------------------------------- |
|
|
|
MattLofton GURU
Joined: 23 Dec 2000 Posts: 4834 Location: USA
|
Posted: Sat May 05, 2007 6:09 pm |
Progonoi has the right of it. There's literally no reason to use #WAIT anymore, and if it wasn't for all the old scriptors who did use it Zugg would be able to completely remove it.
There's a trigger condition type called a wait-state which works exactly like #WAIT, but without any of the problems already associated and documented to #WAIT:
#trigger {blah blah} {you send a command here}
#condition {} {stuff you want to do next} {wait|param=number of milliseconds you want to wait goes here, 1000 milliseconds = 1 second} |
|
_________________ EDIT: I didn't like my old signature |
|
|
|
nexela Wizard
Joined: 15 Jan 2002 Posts: 1644 Location: USA
|
Posted: Sun May 06, 2007 3:33 am |
I believe #WAIT was created for inside loops like #loop, #forall, #loopdb etc to slow the iterations down. And even then it is not recomended for use in triggers or alias that are always active.
An example of a good time for #wait would be if you have an alias to loop through something and write it all to an in game board or note. where you don't want to send it all at once and have the mud kick you off.
For active scripts #CONDitional triggers and alarms are best. |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Sun May 06, 2007 11:18 am |
I am not using #WAIT in triggers or aliases that are always active. I use it during sequential execution of lines in scripts. And it works very well except for the problem when I touch one of the other windows. I wouldn't mind if there was another similar way to obtain the same functionality without having the windows problem but the suggestions so far is not doing that. It would take a complete change to all my scripts because I'd have to nest the next commands all the time. In a scripts with just 10 lines or so this way would make the script unreadable. Maybe one of you could show me how to convert these lines to obtain the same functionality without the use of #WAIT and without obfuscating the code. I am not saying that it can't be done but I cannot see how the suggestions so far does the trick. There is a simple alias "waitForFeedback" that is used by the script to block further processing until feedback is received from the mud.
--------------
// Alias: waitForFeedback.
// A simple command blocking processing until something is received from the mud.
// There are triggers that captures mud output and sets the awaitingFeedback flag but they are not interesting in this context
awaitingFeedback = true
#WHILE (@awaitingFeedback == true) {
#WAIT 100
}
--------------
// A little script to put away a bow
hold my bowcase
waitForFeedback
put my bow in my bowcase
waitForFeedback
wear my bowcase
waitForFeedback
--------------
Now this is a very simple example. But of course I then also expect the alternative to be just as simple. :-) |
|
|
|
Progonoi Magician
Joined: 28 Jan 2007 Posts: 430
|
Posted: Sun May 06, 2007 12:47 pm |
Code: |
#trigger {You hold your (%w).} {} {Wait|Param=1000}
#cond {#if (%1="bowcase")} {put bow bowcase} {Wait|Param=1000}
#cond {You put bow in the bowcase.} {wear bowcase} {Wait|Param=1000}
|
I'm sure it has several flaws as I wrote it on fly with not much knowleadge about conditional sentences and trigger states, but I'm sure it will give you the general idea of how to use conds/states without the need to use #wait and be better off with it.
Prog |
|
_________________ The Proud new owner of CMud.
--------------------------------
Intel Core i5-650 3,2GHz
4 DD3 RAM
GTX 460 768MB
Win 7 Home Premium 64x
-------------------------------- |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Sun May 06, 2007 1:02 pm |
An example of the above using Alarms.
Note that you did not supply the triggers that you used to indicate that feedback has been received and this will not work without said triggers.
--------------
// Alias: waitDo.
// A simple command queue system.
// There are triggers that captures mud output and sets the waitforfeedback flag but they are not interesting in this context
waitforfeedback=1
#addi commands %-1
#T+ waitA
--------------
// Alarm: *.501 With the ID of waitA
// A simple command queue system.
// There are triggers that captures mud output and sets the waitforfeedback flag but they are not interesting in this context
#if (@waitForFeedback=0) {
#execute %pop( commands)
#if (%numitems( @commands)=0) {#T- waitA} {waitforfeedback=1}
}
--------------
// Alias: Testwait.
// A simple test for the command queue system.
// There are triggers that captures mud output and sets the waitforfeedback flag but they are not interesting in this context
hold my bowcase
waitdo {
put my bow in my bowcase
close my bowcase
}
waitdo {wear my bowcase}
--------------
Admittedly this is slightly more complex than your scripts were before as any commands you do not want to be executed out of order following a waitdo must themselves be issued from inside a waitdo block themselves.
Please note that you can put blocks of commands inside the waitdo {}.
Also note that I wrote this in Zmud and it is Cmud compatible. |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Wed May 09, 2007 4:31 pm |
progonoi: If you want to give me any idea what you mean you should describe your example. I cannot find anything in the documentation about the {Wait|Param=1000} construction you use for instance. I know Matt mentioned it in his reply but I'd like to find out how it differs from using the wait command. Anyway I asked for an example doing the same as my own and this certainly wasn't it but thanks for your input anyway. If you can construct something more complete I'd love to see it. It doesn't have to be 100% syntactically correct though.
Arminas: I must admit I cannot figure out where your script is blocking. Is it not true that you put all commands in the queue from the start? Once I've put a command on the queue I want to wait for feedback before I put another command on it. This script could be looping forever until I tell it to stop so I need to block in between commands.
If anyone have input on the original subject I'd love to hear from you too. It's killing me and I have absolutely no idea why it happens. |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Wed May 09, 2007 4:56 pm |
This script DOES wait for feedback, that is the point, You did not give me the triggers for the feedback. You assumed that it was not necessary, I was kinda making a point of that.
#if (@waitForFeedback=0) {do stuff} {Don't do anything just wait a little longer.}
An example of a feedback trigger would be.
#trigger {You place your bow in your bowcase.} {waitForFeedback=0}
This would allow the next thing in the queue to be executed.
At any point and in any script you can add more things onto the queue but they will have to wait their turns.
Yes once you use the waitdo you need to just place everything inside of it if you want them to be done in the proper order.
For simplicity sake though if any trigger sets the waitForFeedback variable to 0 the next thing on the queue is sent.
So for example if you just wanted to wait for a prompt before doing the next action you could do this.
#trigger {Prompt text} {waitForFeedback=0}
And not make any more feedback triggers.
And if you examine the example I gave more closely it should answer your question. If you truely fear that it could concievably be looping forever you could place a counter for how many times the alarm has gone off doing nothing before popping to the next command.
Remember you also said that you wanted simplicity.
#if (@waitForFeedback=0) {do stuff and tell myself that I need to wait again, If I am done with everything turn myself off.} {If I have waited five times I just give up, I am going to do the next thing now.} |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Wed May 09, 2007 5:18 pm |
Well, my point is that I need to be able to block between commands. If there is no blocking in between putting commands on queue when will I stop doing so? It is not enough that commands taken from the queue will be fired in turn after each other completes if I blow up CMUD because I put too many elements on the queue. Remember that I can't tell how many commands I need to give to the mud. I want it to run until I tell it to stop. Perhaps the same 5 lines over and over again. See what I mean?
|
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Wed May 09, 2007 5:56 pm |
For that you could put an if inside the waitdo to limit the number of items within the queue. Still If you are using the #wait command inside cmud to do this limiting the harm is going to be worse to the system than adding things to a string list!
Also remember that each item inside the queue is not necessarily a single command it can represent multiple ones. Even loops etc.
do thing
waitdo {#if (blah blah) {do this stuff} {do that stuff}
DO this too right afterwards
also do this}
waitdo {Do this one thing}
waitdo {#loop 4 {do these things}}
waitdo {do this;and do that}
See each waitdo is waiting for feedback, and waiting for conceivably different feedback. So your output could be this.
Do thing
wait five minutes
DO this too right afterwards
also do this
wait 3 seconds
Do this one thing
wait 1 second
do these things
do these things
do these things
do these things
wait half a second
do this
and do that |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Wed May 09, 2007 5:58 pm |
The #loop could also be replaced by a #while or an #until!
|
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Wed May 09, 2007 6:42 pm |
Your queue system is fine and I am thinking of using some of the ideas for other problems but I don't think it solves this particular case. Let's make a little loop example:
#VAR iAmDone false
#WHILE (!@iAmDone) {
doSomething
waitForFeedback
}
Imagine there is a button that sets iAmDone to true when pressed. Now, you can't do this with your queue can you? It would run exactly as long as it would take for CMUD to reach maximum list size and throw some kinda access violation exception. |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Wed May 09, 2007 6:52 pm |
I'm in the middle of something, and don't have time to think, but I believe I have done that a different way elsewhere.
|
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Wed May 09, 2007 7:00 pm |
I appreciate your feedback and if you come up with a solution I would be delighted to see it. Same goes for everyone else who has suggestions of course.
|
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Wed May 09, 2007 7:11 pm |
#alias recursive {#if (!iAmDone) {doSomething;waitdo {recursive}}}
waitdo {recursive}
That should do it. |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
kjaerhus Magician
Joined: 18 Dec 2006 Posts: 317 Location: Denmark
|
Posted: Wed May 09, 2007 7:19 pm |
I am not sure if I dare to say this but it's not blocking, is it? After the second line the execution will continue, no?
|
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Wed May 09, 2007 7:25 pm |
You use this in conjunction with the rest of the code I gave you.
So you have created the recursive alias that I have above. And now you want to use it in your settings.
Do thing
waitdo {recursive}
waitdo {Other things
still more things
that is enough things}
This is the way that plays out.
doSomething
wait
doSomething
wait
doSomething add infinitum until the iAmDone gets set to true
wait
Other things
still more things
that is enough things |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
|
|