GuideMe (TeaseMe v2.0) - Current Build 0.4.4

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

wheresmything
Explorer
Explorer
Posts: 62
Joined: Tue Nov 16, 2010 2:02 pm

Re: GuideMe (TeaseMe v2.0) - Current Build 0.4.4

Post by wheresmything »

Ok, took some tweaking and such, but I got it working. Thanks much for the help.
EroticDevelopment
Explorer
Explorer
Posts: 36
Joined: Thu Oct 15, 2020 3:32 am
Gender: Male
Sexual Orientation: Straight
Location: USA

Re: GuideMe (TeaseMe v2.0) - Current Build 0.4.4

Post by EroticDevelopment »

RemiHiyama wrote: Fri Feb 18, 2022 4:53 am
EroticDevelopment wrote: Fri Feb 18, 2022 4:20 am put this in a new debug.bat).
Maybe we should consider adding this to the build?
Yeah, I think it wouldn't hurt. Hopefully these are rare, but it would make debugging easier when they happen.
RemiHiyama wrote: Fri Feb 18, 2022 4:53 am Anyway, yeah, the problem was that issue that shows up periodically where startup.state ends up containing something like this:

Code: Select all

<scope><![CDATA[ignore]]></scope>
And then when the GuideSettings constructor is run, ComonFunctions.getSavedObject hits an error trying to turn "ignore" into a Scriptable, and then because of the way the exception is handling it just returns the string "ignore". Then it tries to cast that into a Scriptable object that fails and nothing catches the exception.

I'm not really sure of the best way to handle this.
That's a good observation, and definitely something that needs work. I'll take a look at how error handling works during the state load and see if we can't make some changes. It seems like if a single property is bad or can't be read it could substitute the default value and go on, or worse case restore the factory-default state and re-launch.
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: GuideMe (TeaseMe v2.0) - Current Build 0.4.4

Post by RemiHiyama »

EroticDevelopment wrote: Fri Feb 25, 2022 12:25 amYeah, I think it wouldn't hurt. Hopefully these are rare, but it would make debugging easier when they happen.
It's also useful for developing teases with tricky javascript in them. (I like the way the console shows things better than how the log section of the debug window does.)
That's a good observation, and definitely something that needs work. I'll take a look at how error handling works during the state load and see if we can't make some changes. It seems like if a single property is bad or can't be read it could substitute the default value and go on, or worse case restore the factory-default state and re-launch.
That's about what I was thinking, except that I'm not sure which is the appropriate way to jump. It doesn't seem to assign *anything* to scope if the state file doesn't exist, and that seems to be okay, but I'm not at all clear on what it's even *for*, so I don't know if that's safe when the other stuff in the file has been assigned already. And how come a tease that corrupts it only corrupts startup.state, and not the state file for the tease with the broken code?
Auto: Replaces selected instances of the word "not" with the word "definitely".
User avatar
PlayfulGuy
Experimentor
Experimentor
Posts: 1068
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

Javascript and global variables

Post by PlayfulGuy »

Hi guys,

I know it's been discussed before, but I want to see what the chances are of this ever getting changed.

This is currently the biggest stumbling block I have with development of the downloader and downloading advanced EOS teases. Many of the really complex ones use elaborate javascript that unfortunately relies on global variables (as in global across pages) for proper operation. Since EOS supports this, but GuideMe does not, conversion becomes a huge challenge. If Guideme supported globals across pages, some of the largest issues I have left in the downloader would disappear.

If memory serves, these used to work in older versions of Guideme but then something was changed later on so globals no longer persist across pages. I recall philo mentioning a change like that at some point (though I could be wrong).

Does any else recall anything about this, and why it was done, and what may be the ramifications of changing it back?

If I understand how Guideme works, I think the globaljavascript code gets executed for each page, resetting any global variables defined. EOS on the other hand uses an "init" module that gets executed once when the tease loads, and the javascript environment persists across pages so individual pages can use "evals" to execute functions defined in the init module, refer to global variables etc.

Or maybe I need to use a different approach? Right now I add the EOS init code to the global javascript, and try and modify it to work in GuideMe, which means implementing a javascript parser that's smart enough to modify the code. As I'm sure you can appreciate, this is not a trivial task, and in it's current state it badly mangles some stuff. If global variables worked "properly", I would presumable be able to just pass all the javascript through to Guideme, and conceivably everything would just work.

What are your thoughts?

PG
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: Javascript and global variables

Post by RemiHiyama »

PlayfulGuy wrote: Mon Feb 28, 2022 8:12 pmIf I understand how Guideme works, I think the globaljavascript code gets executed for each page, resetting any global variables defined.
Not quite true.

Global javascript (and then the javascript for your current page) gets executed once for every time a function is called. If you have any page javascript whatsoever, then that will all get run as part of calling pageLoad. If you have a timer that calls a function, same thing. If you have a button that does some javascript, same thing.

Every time seems to start with a fresh context, although I'm not really sure from looking at it where it does that. I'd have to hunt down the commit where that was changed again, I think.

In any case, the intent was to be able to script each page completely independently, without having to worry about name collisions and so forth. I'd be very surprised if just changing back to the old behavior doesn't break some teases.

What I do think would be worthwhile is having an optional configuration setting that makes all the resetting not happen and only runs global javascript once. Page javascript probably has to be rerun every time, and pageLoad would need to be used with caution. (If a page didn't have it defined, but did have other page javascript, it would run the last version of the function to be defined - not necessarily ideal!) This seems like it'd do what would be "expected" in most cases, though some things would require cautious handling.

I believe such an option would cover your needs, but I'm not sure exactly how to do all of it.
Auto: Replaces selected instances of the word "not" with the word "definitely".
philo
Explorer At Heart
Explorer At Heart
Posts: 831
Joined: Sun Jan 08, 2012 3:10 pm
Gender: Male
Sexual Orientation: Straight
Location: UK

Re: Javascript and global variables

Post by philo »

RemiHiyama wrote: Mon Feb 28, 2022 10:18 pm
PlayfulGuy wrote: Mon Feb 28, 2022 8:12 pmIf I understand how Guideme works, I think the globaljavascript code gets executed for each page, resetting any global variables defined.
Not quite true.

Global javascript (and then the javascript for your current page) gets executed once for every time a function is called. If you have any page javascript whatsoever, then that will all get run as part of calling pageLoad. If you have a timer that calls a function, same thing. If you have a button that does some javascript, same thing.
This was designed deliberately. Global variables are a pain and lead to bad programming practices and code that is hard to maintain / understand.
The purpose of the scriptvar object is to hold state between pages.
Global javascript was meant to be used for reusable functions, it was never designed to be used to hold state.
There was a bug where that was not cleared down in some circumstances, but was inconsistent, so setting a global variable worked by accident some of the time, that was fixed :-D
The design is supposed to give a clean state for each time you run a script.
It should run global javascript to set up any re-usable code.
It should then run the actual javascript for that event.
You can take a copy of a variable from the scriptvars and use it locally.
You can update a variable in scriptvars if you want to change the value.

I would recommend keeping that model, however you may want to rethink the implementation of scriptvars to make them easer to use / understand.
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: Javascript and global variables

Post by RemiHiyama »

philo wrote: Tue Mar 01, 2022 8:26 amThis was designed deliberately. Global variables are a pain and lead to bad programming practices and code that is hard to maintain / understand.
This may be true, but it doesn't really make any reference to PlayfulGuy's use case. For better or for worse, EOS handles variables the way it does, and if automatically converting between the two idioms was easy he would have already done so.

As for my personal feelings... well, maybe it comes down to where you learned to program. Scriptvars feels like I'm still using global variables, but with the addition of a voice at the back of my head screaming "Don't repeat yourself!" every time I write another scriptVars.get. Ultimately it makes for confusing and difficult to follow code, at least for me, and working within GuideMe places strict limitations on what other methods can be used.

That being said, I have no desire or intention to replace the existing model. (One of my major goals is to avoid breaking existing teases.) Just to make additional options available if there's a niche that doesn't seem to be filled.
you may want to rethink the implementation of scriptvars to make them easer to use / understand.
I'm not sure how you could. They'd be a lot more intuitive with subscript notation, but neither Java nor JavaScript have operator overloading so that's not on the table.
Auto: Replaces selected instances of the word "not" with the word "definitely".
User avatar
PlayfulGuy
Experimentor
Experimentor
Posts: 1068
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: Javascript and global variables

Post by PlayfulGuy »

philo wrote: Tue Mar 01, 2022 8:26 am
Spoiler: show
RemiHiyama wrote: Mon Feb 28, 2022 10:18 pm
PlayfulGuy wrote: Mon Feb 28, 2022 8:12 pmIf I understand how Guideme works, I think the globaljavascript code gets executed for each page, resetting any global variables defined.
Not quite true.

Global javascript (and then the javascript for your current page) gets executed once for every time a function is called. If you have any page javascript whatsoever, then that will all get run as part of calling pageLoad. If you have a timer that calls a function, same thing. If you have a button that does some javascript, same thing.
This was designed deliberately. Global variables are a pain and lead to bad programming practices and code that is hard to maintain / understand.
The purpose of the scriptvar object is to hold state between pages.
Global javascript was meant to be used for reusable functions, it was never designed to be used to hold state.
There was a bug where that was not cleared down in some circumstances, but was inconsistent, so setting a global variable worked by accident some of the time, that was fixed :-D
Spoiler: show
The design is supposed to give a clean state for each time you run a script.
It should run global javascript to set up any re-usable code.
It should then run the actual javascript for that event.
You can take a copy of a variable from the scriptvars and use it locally.
You can update a variable in scriptvars if you want to change the value.

I would recommend keeping that model, however you may want to rethink the implementation of scriptvars to make them easer to use / understand.
Okay, that's basically what I recalled and fills in the blank on why it was done.

While I agree that global variables are not necessarily the best practice, the fact remains that they are valid javascript, and they do get used. I agree with RemiHiyama that scriptVars seem to just betaking the place of global variables, but the main difference is it forces them to be explicit, and communicates to GuideMe what needs to be saved in the guide state between sessions. Come to think of it, if javascript required explicit globals some of my issues would be greatly reduced.

So (and correct me if I'm wrong) it seems the source of the issue is that EOS and Guideme use slightly different models and assumptions.

In Guideme it's assumed that all pages are essentially independent and scriptVars() are used to share information between pages, while at the same time keeping Guideme informed of what needs to be saved between sessions, and saving of the session state is done automatically.

In EOS it's assumed that pages are all related, and global variables hold the state while a session is active, and allow shared data between pages, then the teaseStorage() module is used to explicitly save selected variables between sessions, and this must be explicitly done by the programmer.

So in summary:
Guideme requires manual communication between pages, but provides automatic saving of the state between sessions.
EOS = provides automatic communication between pages, but requires manual saving of the state between sessions.

I'll sleep on it a bunch more times and see what other ideas come up, and what happens when I start re-writing the affected portion of my downloader. I guess it may just never be perfect, but if I just take it one issue, and one step at a time it will continue to get better.

Thanks for the replies guys!

PG
User avatar
PlayfulGuy
Experimentor
Experimentor
Posts: 1068
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: Javascript and global variables

Post by PlayfulGuy »

RemiHiyama wrote: Mon Feb 28, 2022 10:18 pm
PlayfulGuy wrote: Mon Feb 28, 2022 8:12 pmIf I understand how Guideme works, I think the globaljavascript code gets executed for each page, resetting any global variables defined.
Not quite true.

Global javascript (and then the javascript for your current page) gets executed once for every time a function is called. If you have any page javascript whatsoever, then that will all get run as part of calling pageLoad. If you have a timer that calls a function, same thing. If you have a button that does some javascript, same thing.

Every time seems to start with a fresh context, although I'm not really sure from looking at it where it does that. I'd have to hunt down the commit where that was changed again, I think.

In any case, the intent was to be able to script each page completely independently, without having to worry about name collisions and so forth. I'd be very surprised if just changing back to the old behavior doesn't break some teases.

What I do think would be worthwhile is having an optional configuration setting that makes all the resetting not happen and only runs global javascript once. Page javascript probably has to be rerun every time, and pageLoad would need to be used with caution. (If a page didn't have it defined, but did have other page javascript, it would run the last version of the function to be defined - not necessarily ideal!) This seems like it'd do what would be "expected" in most cases, though some things would require cautious handling.

I believe such an option would cover your needs, but I'm not sure exactly how to do all of it.
Yeah, that makes sense and helps clarify my understanding. I can see how there could be issues with the page level javascript, and reading that brought to mind times in the past where stuff was happening in a tease that I could not explain, or stuff was working and I could not understand how it was working because it seemed like it shouldn't. Given my experience level now I can see how both cases were clearly examples of the issues philo was addressing with the change.

Not the answer I wanted :lol: but it is what it is, right?

Thanks,

PG
philo
Explorer At Heart
Explorer At Heart
Posts: 831
Joined: Sun Jan 08, 2012 3:10 pm
Gender: Male
Sexual Orientation: Straight
Location: UK

Re: GuideMe (TeaseMe v2.0) - Current Build 0.4.4

Post by philo »

All the javascript code should be in the jscript.java class.
There were two competing jscript libraries at the time Rhino and node.js, Rhino was supported by Mozilla and node.js was some obscure entity so I assumed Rhino was more likely to succeed :-D
I do remember Rhino was not particularly well documented and scopes were particularly obscure and it took a lot of trial and error to get it working.
I think there were 3 scopes in the end, one common one stored in guidesettings, I think one that isn't used by Guidme but needed to be there and one created for each run.
The way the scopes inherit and what it uses from each was a bit arcane from what I remember, but you may be able to implement global variables in the guide scope and have them inherited by all scripts.

Code: Select all

Scriptable globalScope = guideSettings.getGlobalScope();
That line for instance gets the global scope from guide settings in the script class
EroticDevelopment
Explorer
Explorer
Posts: 36
Joined: Thu Oct 15, 2020 3:32 am
Gender: Male
Sexual Orientation: Straight
Location: USA

Re: GuideMe (TeaseMe v2.0) - Current Build 0.4.4

Post by EroticDevelopment »

philo wrote: Tue Mar 01, 2022 8:26 am This was designed deliberately. Global variables are a pain and lead to bad programming practices and code that is hard to maintain / understand.
I definitely feel that comment.. I've spent a lot of time in my professional development career working with PHP. In recent versions globals are very much discouraged, but that wasn't always the case. In working with several applications that were inherited from other developers, I ran into a ton of this. I can say without hesitation that having a ton of global variables used throughout an application was a guarantee I'd find other bad programming practices, and the code was always more difficult to understand, debug, and maintain. In the end nearly all of this was re-written into an object-oriented architecture without globals.

All of that said, I'm really conflicted on how to move forward from here. Philo has made some excellent points and it's great to hear why some of this was built the way that it is. However, many of the newer teases are written in EOS or use some kind of architecture that nearly requires the use of global variables. I really want to say we really should discourage and not support globals in the way EOS does, but it also concerns me that doing so raises the bar for the amount of development and technical knowledge needed to write teases compatible with GuideMe. As much as I hate the overuse of globals, it's significantly easier for users just getting started with JavaScript and I don't want to ignore that.

I guess my confliction really comes down to is it better to keep globals completely removed and require better practices, or is it better to allow globals and perhaps lower the bar to entry and have more content available for GuideMe?

As others have said, switching GuideMe to use globals by default is a non-starter because of how much it would break, however it does seem feasible to have a config option in the tease XML that enables the global scope and changes behavior. Whether or not this is a good idea is yet to be determined.

philo wrote: you may want to rethink the implementation of scriptvars to make them easer to use / understand.
Browser oriented JS has the concept of the "window" object, and I suppose something like that could work as well. Keep one variable, say "global" for explanation purposes, in the global scope and the rest per-page. That would allow things like "global.varOne = 5" to set and keep a global, and could then be used as-is like "myFunction('page1', global.varOne)" etc. Any variables not part of the global object would be destroyed, but the global object would be persisted between pages. My only concern with something like this is I don't think it solves the problem of porting EOS teases to GuideMe. It would still be difficult to rename variables that needed persisted to all be in the global scope.

It does feel like there's room to make this easier to use / understand, but I really can't think of any great ways to do this that are solving an issue rather than just re-working the implementation to say we did.
philo
Explorer At Heart
Explorer At Heart
Posts: 831
Joined: Sun Jan 08, 2012 3:10 pm
Gender: Male
Sexual Orientation: Straight
Location: UK

Global variables

Post by philo »

In hindsight, I am not so convinced restricting global variables was the right design decision.
Not having them in the actual Guideme java programming is correct.
Not having them in the tease JavaScript was probably a step too far.
The chances of someone maintaining someone else's tease JavaScript is pretty low, so if the author wants to use globals and EOS makes extensive use of them, it makes sense to allow them.
As EroticDevelopment says it lowers the entry level for writing the tease.
I doubt it would break many teases if they were introduced, but having a tease option to turn it off at a tease level so a tease can be made backward compatible would help.
RemiHiyama
Explorer At Heart
Explorer At Heart
Posts: 203
Joined: Thu Feb 28, 2019 3:30 pm
I am a: Switch

Re: GuideMe (TeaseMe v2.0) - Current Build 0.4.4

Post by RemiHiyama »

EroticDevelopment wrote: Sat Mar 05, 2022 1:22 amI guess my confliction really comes down to is it better to keep globals completely removed and require better practices, or is it better to allow globals and perhaps lower the bar to entry and have more content available for GuideMe?
Part of the way I look at it is "Why, these are globals, nor am I not using them." Someone using scriptVars as it exists now still has to take most of the same cautions as someone working with plain globals, just with different syntax.

On a more general philosophical level, I think it's better for a language to provide tools that make good programming easier rather than trying to make bad programming hard, because that's always going to be a moving target. But we're kind of limited here, because of how we've got to work around the limitations of other parts of the engine. Images in EOS are a major example of this kind of thing. One of the things you just can't do with javascript in EOS is display an image by filename. You've got to have a page load it. So you start getting teases that have little stub pages that do little but show an image, then jump to another page that does the actual game logic. The inability to have a true loop within a single page also leads to some odd design choices sometimes.

GuideMe lets you get way "closer to the metal"; I can't think of anything quite as hinky in it at the moment. But there is still a structure imposed by how the non-scripting parts work that mean you can't necessarily do things the way you would if you were coding the whole thing from scratch. There's always going to be workarounds required. But we can make it easier for people to code things in ways that make sense to them.


As others have said, switching GuideMe to use globals by default is a non-starter because of how much it would break, however it does seem feasible to have a config option in the tease XML that enables the global scope and changes behavior. Whether or not this is a good idea is yet to be determined.
Browser oriented JS has the concept of the "window" object, and I suppose something like that could work as well. Keep one variable, say "global" for explanation purposes, in the global scope and the rest per-page. That would allow things like "global.varOne = 5" to set and keep a global, and could then be used as-is like "myFunction('page1', global.varOne)" etc
That seems like a useful middle-of-the-road addition. Make a NativeObject at the appropriate time and stick it an a javaside Object variable, and I don't think it would cause any problems with backwards compatibility even, and javascript objects give you pretty easy access at that point.

A couple questions do occur to me. One, should places that interpolate scriptVars also look in this new object? I'm leaning to yes, because it's useful, though as a secondary to checking scriptVars. (And it'll need to check to make sure the entire object hasn't been replaced with something else for safety.) Two, should it's contents be saved? I'd prefer not here, since right now I'm not aware of any way to have values that persist between pages but not between runs.
Auto: Replaces selected instances of the word "not" with the word "definitely".
User avatar
PlayfulGuy
Experimentor
Experimentor
Posts: 1068
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

Dynamically enable/disable TTS

Post by PlayfulGuy »

Question for the devs / feature request:

Is it possible to dynamically enable/disable TTS in a guide?

I had an idea for a tease mixing traditional follow along on screen segments with other segments that give audio instruction using TTS, but would need to be able to turn that on/off. As far as I recall TTS is an all or nothing setting at the application level.

It would be nice if this could be a tease level setting, and to have the ability to turn it on/off in javascript/xml

PG
EroticDevelopment
Explorer
Explorer
Posts: 36
Joined: Thu Oct 15, 2020 3:32 am
Gender: Male
Sexual Orientation: Straight
Location: USA

Re: Dynamically enable/disable TTS

Post by EroticDevelopment »

PlayfulGuy wrote: Wed Apr 06, 2022 12:50 am Question for the devs / feature request:

Is it possible to dynamically enable/disable TTS in a guide?

I had an idea for a tease mixing traditional follow along on screen segments with other segments that give audio instruction using TTS, but would need to be able to turn that on/off. As far as I recall TTS is an all or nothing setting at the application level.

It would be nice if this could be a tease level setting, and to have the ability to turn it on/off in javascript/xml

PG
Hi PG,

It's definitely possible, but I'm a bit curious as to what types of teases would be using this and how? The current TTS implementation was mostly used to copy text to the clipboard for other utilities to read it aloud as far as I'm aware. With the recently added Audio2 tag, is this something where you could just have audio instructions read on the Audio2 player? That would allow them to be read simultaneously with video and a second music or e-stim track if needed.
Post Reply