GuideMe Scripting Engine

Webteases are great, but what if you're in the mood for a slightly more immersive experience? Chat about Tease AI and other offline tease software.

Moderator: 1885

User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

PlayfulGuy wrote: Sun Dec 30, 2018 4:26 am
Looking at the code for the script engine and the way it's structured, and looking at the addTimer() documentation and the other options it has, it occurred to me that the simplest approach is to add a Timer command to the text block processing so you could say

Code: Select all

InitialImage.jpg {
	Initial text
	Timer 10 New text 1
	Timer 10 New text 2
	Timer 10 Image newImage.jpg
}
And then it's all nice and clean and logical, and can it supports changing images too.

The above would show "Initial text" first with InitialImage.jpg, and set the timer to change the text 10 seconds later to "New text 1", and then 10 seconds later to "New text 2", and 10 seconds later change the image to newImage.jpg

This actually fits very nicely with how the script engine processes commands now, and the implementation of it would be similar to how I handle buttons, so I'd say it's looking pretty good.

And it would work with videos too.

And then if I smarten up the page command so it detects videos and handles the other options you suggest as well, things start looking pretty sweet.
PG, thanks! That is very nice and definitely fits the existing command structure well! Much better than my current GM page with multiple sequential function calls, and buttons that turn on/off.

Also, thanks for clarifying the existing video command. I had not tested it in real code as I knew it wouldn't support what I needed. This change is really cool! :yes:
User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

PlayfulGuy wrote: Sun Dec 30, 2018 4:26 am
Looking at the code for the script engine and the way it's structured, and looking at the addTimer() documentation and the other options it has, it occurred to me that the simplest approach is to add a Timer command to the text block processing so you could say

Code: Select all

InitialImage.jpg {
	Initial text
	Timer 10 New text 1
	Timer 10 New text 2
	Timer 10 Image newImage.jpg
}
...

This actually fits very nicely with how the script engine processes commands now, and the implementation of it would be similar to how I handle buttons, so I'd say it's looking pretty good.

And it would work with videos too.

And then if I smarten up the page command so it detects videos and handles the other options you suggest as well, things start looking pretty sweet.

I'm making no promises on when I might be able to get that done, but that gave me the creative boost I needed :-D
Hey there PG - I'm stuck on adding videos to my project, the workaround in GM is possible, but very cumbersome. Just hoping you might have an update? I know everyone is busy, so not trying to be pushy. Also wanted to let you know that it would be used if you get a chance to implement it. Thx! BH
User avatar
PlayfulGuy
Explorer At Heart
Explorer At Heart
Posts: 778
Joined: Sat Jul 07, 2012 10:08 pm
Gender: Male
Sexual Orientation: Bisexual/Bi-Curious
I am a: Switch
Dom/me(s): No domme
Sub/Slave(s): No sub
Location: British Columbia, Canada

Re: GuideMe Scripting Engine

Post by PlayfulGuy »

bobhill wrote: Sat Apr 06, 2019 2:03 pm Hey there PG - I'm stuck on adding videos to my project, the workaround in GM is possible, but very cumbersome. Just hoping you might have an update? I know everyone is busy, so not trying to be pushy. Also wanted to let you know that it would be used if you get a chance to implement it. Thx! BH
I haven't had the right combination of time and energy to get into it, and there are so many great teases to try!

I have been cleaning up the script engine and testing changes I've already made trying to get a new release out. I'm hesitant to add more changes at this point, but what's a few more?

I haven't forgotten, and you don't come across as pushy at all so no worries. And in fact these little nudges are really helpful to get me motivated.

Cheers

PG
User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

Haha! :wave: Thanks, that is very exciting to hear! And I'm happy to help "motivate" you! :yes:

BH
mantrid
Explorer At Heart
Explorer At Heart
Posts: 154
Joined: Sun Dec 30, 2018 6:40 pm
Gender: Male
Sexual Orientation: Straight
I am a: Switch

Re: GuideMe Scripting Engine

Post by mantrid »

Just a small small cross posting.

Today I lost a few hours to the GuideMe state data bug. Unfortunately the workarounds stated here did not help. The problem for me was that the functions defined in 'ScriptEngine.js' couldn't be found, including 'ExitAllScripts()' and 'loadScript(...)'.

The workaround (for me) is to insert 'ScriptEngine.js' directly. Thats not wired enough: If I now overwrite the state file of the old version (with the 'include' statement) with the state file of the new version, the old version now works to.

The full report can be found in the GuideMe thread.
GAsm -- A guide assembler with EStim support to generate interactive teases that run in a browser.
mantrid
Explorer At Heart
Explorer At Heart
Posts: 154
Joined: Sun Dec 30, 2018 6:40 pm
Gender: Male
Sexual Orientation: Straight
I am a: Switch

Re: GuideMe Scripting Engine

Post by mantrid »

According to the docs javascript functions can be used in expressions. But what is an expression (that is evaluated), or maybe more exact: when are expressions evaluated (texts are expressions too).

An example: A global button that reloads the current page. Neither

Code: Select all

GlobalButton reload, guide.getCurrPage()
nor

Code: Select all

GlobalButton reload, <guide.getCurrPage()>
works.

The problem seems to be that there is no clear rule (or do I miss something) when something is evaluated. IMHO evaluated expressions have to be marked somehow, e.g. as tag ('<expression>') or as special tag ('<e expression>').

This would also allow to implement buttons that just execute javascript code (do not goto somewhere if expressions is evaluated to an empty string), e.g.

Code: Select all

// reloads current page
GlobalButton reload, <guide.getCurrPage();>

// increments counter
Button Increment, <count=count+1;>
This would even allow to the evaluate expression within text block, but then the special tag variant may be a better choice:
e.g. '<e count++>'
GAsm -- A guide assembler with EStim support to generate interactive teases that run in a browser.
User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

mantrid wrote: Mon May 20, 2019 11:16 am According to the docs javascript functions can be used in expressions. But what is an expression (that is evaluated), or maybe more exact: when are expressions evaluated (texts are expressions too).

An example: A global button that reloads the current page. Neither

Code: Select all

GlobalButton reload, guide.getCurrPage()
nor

Code: Select all

GlobalButton reload, <guide.getCurrPage()>
works.

The problem seems to be that there is no clear rule (or do I miss something) when something is evaluated. IMHO evaluated expressions have to be marked somehow, e.g. as tag ('<expression>') or as special tag ('<e expression>').

This would also allow to implement buttons that just execute javascript code (do not goto somewhere if expressions is evaluated to an empty string), e.g.

Code: Select all

// reloads current page
GlobalButton reload, <guide.getCurrPage();>

// increments counter
Button Increment, <count=count+1;>
This would even allow to the evaluate expression within text block, but then the special tag variant may be a better choice:
e.g. '<e count++>'
I think you may want to spend some time in the tutorials and look at the sample scripts as this may help you with understanding syntax and functionality. Or if you have specific questions/objectives I can try to assist.

For example, I'm not sure what you mean by "reload the current page" because you are mixing GM commands with the scripting engine: guide.getCurrPage() returns the name of the GM Page (which is usually ShowScriptPage) it's not a command in itself and the script engine "pages" aren't named.

Further, JS functions have to be used in an assignment or an expression and can't be used as button actions. So you could do:

Code: Select all

vCallingPage = guide.getCurrPage()
	
	no-02.jpg {
		Page is <vCallingPage>
		Button Continue
	}
On the last example, I'm not sure why you want a button to increment (or 'go nowhere' as you put it, but something like this is equivalent to what you posted:

Code: Select all

	no-02.jpg {
		Button Increment
	}
	count=count+1
As I said, if you have specific questions or needs, I am happy to try to assist further.

BH
mantrid
Explorer At Heart
Explorer At Heart
Posts: 154
Joined: Sun Dec 30, 2018 6:40 pm
Gender: Male
Sexual Orientation: Straight
I am a: Switch

Re: GuideMe Scripting Engine

Post by mantrid »

Docs say:
The script engine has full expression support for counting and
performing calculations, and evaluating complex conditions. Expressions
can include references to most javascript functions, and to custom
javascript functions defined in the GlobalJavascript section of your
GuideMe tease.
The example commands (which are just examples -- but I think they explain what I want: evaluation of arguments as cited) are expressions, but aren't evaluated as cited.

Meanwhile I took a look into the code and learned how and which expressions are evaluated -- that was my first question.

The basic problem: there are two sets of syntax rules and without knowledge of some internals it's not clear (at least for me) which rule applies.

The rest of my post was a suggestion how this can be changed in a consistent way -- but it's just a suggestion.
GAsm -- A guide assembler with EStim support to generate interactive teases that run in a browser.
User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

mantrid wrote: Tue May 21, 2019 12:21 am evaluation of arguments as cited) are expressions, but aren't evaluated as cited.
I'm sorry, I still not sure what you mean by expressions aren't evaluated as cited. I believe that expressions are evaluated correctly, this, for example, works fine:

Code: Select all

	
	count = 0
	
	no-02.jpg {
		Count is <count>
		Button Continue, count=count+1
	}

	no-03.jpg {
		Count is <count>
		Button Continue 
	}

mantrid wrote: Tue May 21, 2019 12:21 am The basic problem: there are two sets of syntax rules and without knowledge of some internals it's not clear (at least for me) which rule applies.
When you say two sets of syntax rules do you mean the GM syntax vs the ScriptEngine syntax?
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: GuideMe Scripting Engine

Post by RemiHiyama »

Is this supposed to work in GuideMe 3.8? When I try opening any of the examples in the 1.53 package in that GM version, it pops up two blank javascript error windows and then just sits on "Something went wrong".
Auto: Replaces selected instances of the word "not" with the word "definitely".
mantrid
Explorer At Heart
Explorer At Heart
Posts: 154
Joined: Sun Dec 30, 2018 6:40 pm
Gender: Male
Sexual Orientation: Straight
I am a: Switch

Re: GuideMe Scripting Engine

Post by mantrid »

@RemiHiyama
RemiHiyama wrote: Tue May 21, 2019 3:48 pm Is this supposed to work in GuideMe 3.8? When I try opening any of the examples in the 1.53 package in that GM version, it pops up two blank javascript error windows and then just sits on "Something went wrong".
This seems to be the issue we are discussing in the GM thread

Remove the .state file in the data directory of you GM installation, and replace the line

Code: Select all

<Include file="Common/ScriptEngine.js" />
in the .xml files by the content of 'ScriptEngine.js'. For me, this works.

@bobhill
I will start with a small extension because it also serves as a meaningful example. It's a JavaScript function that is used to create pools of labels (e.g. to sessions) and randomly selects an existing target from the pool which has not been visited. A label is considered as visited if a flag with the same name is set.

I use it in this demo and it may be useful for other teases to. It needs to be included in the 'GlobalJavascript' section. Feel free to append it to 'scriptEnginge.js'.
Spoiler: show

Code: Select all

// -----------------------------------------------------------------------
	// Randomly chooses an existing label from a range.
	// This function is intended to implement pool of labels and randomly choosing one label that has not been visited.
	// A label is considered as visited if a flag with the same name name is set.
	// Thus, this function only considers labels that exists and have unset flag.
	// If Labels exits but all flags are set, all flags will be cleared first.
	// Example: 'findTarged(label,10,20)' finds label in the range of target10..target20
	function findTarget(target,first,last) {
	    if ( first == last ) return target+first;
	    else if (first>last ) {
		var i = last;
		last = first;
		first = i;
	    }
	    var flags = [];
	    var j = 0, k = 0;
            for ( i=0; i<=last-first; i++ ) {
        	flags[i] =  ( findScriptLabel(target+(first+i))<0 ) ? 0 : isSet(target+(first+i)) ? 1 : 2;
        	if ( flags[i] == 2 ) j++;
        	if ( flags[i] > 0 ) k++;
//	        jscriptLog("findTarget: " + target+(first+i) + ":  " + flags[i] );
	    }
	    
	    // no targets found
	    var result = target + Math.floor(Math.random()*(last-first)+first);
	    if ( k == 0 ) {
		jscriptLog("Error: findTarget: No targets found, returning: " + result );
		return result;
	    }
	    
	    // return a unset target
	    if ( j > 0 ) {
		j = Math.floor(Math.random()*j);
        	for ( i=0; i<=last-first; i++ ) {
        	    if ( flags[i] == 2 ) {
        		if ( j==0 ) return target+(first+i);
        		j--;
        	    }
		}
	    }

	    // unset all valid targets and return a random one
            for ( i=0; i<=last-first; i++ ) {
        	if ( flags[i]>0 ) comonFunctions.UnsetFlags(target+(first+i), guide.getFlags());
            }
	    k = Math.floor(Math.random()*k);
    	    for ( i=0; i<=last-first; i++ ) {
    		if ( flags[i] > 0  ) {
        	    if ( k==0 ) return target+(first+i);
        	    k--;
        	}
	    }

            return result;  // should not happen
	}
In GSE scripts it can be used like this

Code: Select all

	target = findTarget("floor_1-",1,20)
	button Pool, <target>
bobhill wrote: Tue May 21, 2019 2:46 pm When you say two sets of syntax rules do you mean the GM syntax vs the ScriptEngine syntax?
The two lines above are written in two different syntaxes. Line 1 is JavaScript (like) syntax and consists in a assignment and a call to a function with a string and two integers as arguments. Line 2 is GSE syntax (a description language) and defines a button with two string arguments.

This is neither forbidden nor unusual (HTML/PHP, GideMe/Javascript, ...) but the domains have to be separated somehow, usually by embedding the programming language into the description language using syntax elements of the description language. (GSE tries to guess somehow what the programmer could mean. At least for me this is ambiguous.)

Because GSE already uses tags, this is how I would do that (example from above):

Code: Select all

<e target = findTarget("floor_1-",1,20)>
button Pool, <e target>
That would be equivalent to

Code: Select all

button Pool, <e findTarget("floor_1-",1,20)>
Whenever GSE finds an e tag, it is passed to the JavaScript interpreter.
bobhill wrote: Tue May 21, 2019 2:46 pm I'm sorry, I still not sure what you mean by expressions aren't evaluated as cited. I believe that expressions are evaluated correctly, this, for example, works fine:

Code: Select all

	
	count = 0
	
	no-02.jpg {
		Count is <count>
		Button Continue, count=count+1
	}

	no-03.jpg {
		Count is <count>
		Button Continue 
	}
In this example GSE correctly guesses which syntax is meant. In this example it fails:

Code: Select all

	globalButton Test, findTarget("floor_1-",1,20)
Error message is "onButtonClick: No Label or Page named findTarget("floor_1-",1,20) was found."

Workaround would be

Code: Select all

	globalButton Test, test
	...
	
test:
	label=findTarget("floor_1-",1,20)
	goto <label>
What I really need is a button that executes a JS function without interrupting the page actions (interrupting the sound, because I'm interested in EStim teases)
GAsm -- A guide assembler with EStim support to generate interactive teases that run in a browser.
User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

mantrid wrote: Tue May 21, 2019 6:42 pm @RemiHiyama
Remove the .state file in the data directory of you GM installation, and replace the line

Code: Select all

<Include file="Common/ScriptEngine.js" />
in the .xml files by the content of 'ScriptEngine.js'. For me, this works.
I'm sorry, but you do not need to make this change. If you need to do this, there is a problem with your setup or perhaps with your XML.

@Mantrid - I'll take a look at the rest of your post and reply asap.

@RemiHiyama - you probably need to edit whichever XML file you are running to go to a valid script. I just tested SE 1.53 with GM 3.8 and it runs fine.

If you run ScriptTease.xml, you need to edit this line:

Code: Select all

loadScript("Scripts/myScript.scr"); // **EDIT Assumes the script is in the Scripts subfolder. Edit as required.
Or you should be able to run GuidemeScripts.xml without an edit.
User avatar
bobhill
Explorer At Heart
Explorer At Heart
Posts: 164
Joined: Tue Mar 15, 2016 8:49 pm
Gender: Male
Sexual Orientation: Straight
I am a: None of the above

Re: GuideMe Scripting Engine

Post by bobhill »

mantrid wrote: Tue May 21, 2019 6:42 pm
In GSE scripts it can be used like this

Code: Select all

	target = findTarget("floor_1-",1,20)
	button Pool, <target>
The two lines above are written in two different syntaxes. Line 1 is JavaScript (like) syntax and consists in a assignment and a call to a function with a string and two integers as arguments. Line 2 is GSE syntax (a description language) and defines a button with two string arguments.

This is neither forbidden nor unusual (HTML/PHP, GideMe/Javascript, ...) but the domains have to be separated somehow, usually by embedding the programming language into the description language using syntax elements of the description language. (GSE tries to guess somehow what the programmer could mean. At least for me this is ambiguous.)
Ok - thanks, that's really helpful, I think I understand now. Firstly, from your function I can see that you are a much more advanced programmer than I am - I'm not a programmer, but have learned enough to do what I need in JS, GM and GSE (it took me a while to figure out you meant GuideScriptEngine :lol:).

On your specific issue, since GSE 1.5, you can have expressions or commands as button targets, but you want to have a JS function as a target. JS Functions have to be used in expressions. The issue is that currently the GSE won't evaluate the function as a command, hence the error you mentioned.

Perhaps you could alter the ExecuteCommand and EvaluateExpression functions in ScriptEngine.js, or you could ask PlayfulGuy to add that functionality. Or you could do the workaround you posted, which does work.
mantrid wrote: Tue May 21, 2019 6:42 pm What I really need is a button that executes a JS function without interrupting the page actions (interrupting the sound, because I'm interested in EStim teases)
This is a separate issue/request from above.

Sorry I can't help any further.
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: GuideMe Scripting Engine

Post by RemiHiyama »

bobhill wrote: Tue May 21, 2019 8:28 pm@RemiHiyama - you probably need to edit whichever XML file you are running to go to a valid script. I just tested SE 1.53 with GM 3.8 and it runs fine.
Well, I don't know then. I extracted the 1.53 file, didn't edit anything, stuff works in GM 3.4 and not in 3.8.

I checked guideme.log and it's got this error:

Code: Select all

2019-05-21T19:05:08,715 ERROR Jscript -  FileRunScript illegally formed XML syntax (globalScript#3586)
org.mozilla.javascript.EvaluatorException: illegally formed XML syntax (globalScript#3586)
@Mantrid: If I'm reading this correctly, you should be able to do something like this:

Code: Select all

globalButton Test, foo = findTarget("floor_1-",1,20)
and have it at least run the findTarget function. (onButtonClick won't find a target with that name, it'll pass it to executeCommand, executeCommand will see it looks like an expression and run evaluateExpression on it.) Running the function is all it'll do though, so your function will need to do the page jump itself.

Again assuming I'm reading this correctly. I don't think it'll interrupt page actions either, so that might help you.
Auto: Replaces selected instances of the word "not" with the word "definitely".
mantrid
Explorer At Heart
Explorer At Heart
Posts: 154
Joined: Sun Dec 30, 2018 6:40 pm
Gender: Male
Sexual Orientation: Straight
I am a: Switch

Re: GuideMe Scripting Engine

Post by mantrid »

RemiHiyama wrote: Wed May 22, 2019 12:22 am
bobhill wrote: Tue May 21, 2019 8:28 pm@RemiHiyama - you probably need to edit whichever XML file you are running to go to a valid script. I just tested SE 1.53 with GM 3.8 and it runs fine.
Well, I don't know then. I extracted the 1.53 file, didn't edit anything, stuff works in GM 3.4 and not in 3.8.

I checked guideme.log and it's got this error:

Code: Select all

2019-05-21T19:05:08,715 ERROR Jscript -  FileRunScript illegally formed XML syntax (globalScript#3586)
org.mozilla.javascript.EvaluatorException: illegally formed XML syntax (globalScript#3586)
Strange, my globalScript section has less than 3586 lines. You find a listing in jscript.log. Are you sure that you are using SE 1.53?

Code: Select all

globalButton Test, foo = findTarget("floor_1-",1,20)
and have it at least run the findTarget function. (onButtonClick won't find a target with that name, it'll pass it to executeCommand, executeCommand will see it looks like an expression and run evaluateExpression on it.) Running the function is all it'll do though, so your function will need to do the page jump itself.

Again assuming I'm reading this correctly. I don't think it'll interrupt page actions either, so that might help you.
Nice trick. Indeed, the function is called now without an error. But the button always stops the execution of th page and jumps to the next one.

This probably something I have to implement myself.

Now i also see the misunderstanding. You and the docs write "expression" but mean "assignment". In computer science all these are expressions:
  • globalButton Test, foo = findTarget("floor_1-",1,20)
  • Test
  • foo = findTarget("floor_1-",1,20)
  • findTarget("floor_1-",1,20)
  • "floor_1-"
  • 1
  • 20
GAsm -- A guide assembler with EStim support to generate interactive teases that run in a browser.
Post Reply

Who is online

Users browsing this forum: No registered users and 23 guests