Dynamic menus without reading from a file

Since I only have access to the web interface for creating games, I was wondering what an option would be for creating dynamic menus based on player choices that persist between saved games?

This first run of using this tool is really just to practice having a player choose from menus to select clips from youtube videos to watch. When they watch a video, it is added to a list of watched videos, the list add function seems pretty clear here, but perhaps have other options for organizing menus as I develop this game.

maybe, science clips watched|not watched, clips from the same video since I can play various segments, like putting together a puzzle, the goal is to hunt down segments of these videos and start making sense of what is being discussed.

But, I need a way of keeping track of what has been watched and what hasn't been watched, and what the player has found and what they haven't found.

Since I only have access to the web client (using a chromebook) I can't write to a file and then retrieve that information from the file. I can create various lists, but without publishing the game, I don't have access to a save game feature to see what works and what doesn't.

Also, storing all the lists somewhere inside an object, such as the phone_.videos.videoList doesn't seem to work.
phone_ being the smartphone object, videos being a child object of phone_ and the videoList stored inside the videos object.

I get errors when trying to use something like videos.videoList inside the show menu command. perhaps I can use GetAttribute (videos.videoList) to drop the contents into a list with a local scope?

Progress is slow in development, I keep running into logistical issues.

Thanks for the patience and the help.

Cheers

"-" egoproctor


phone_ being the smartphone object, videos being a child object of phone_

You don't refer to child objects like that.

If videos is a child object of phone, you would access an attribute of videos by referring to videos.videoList or similar. Objects are referenced by their name, regardless of whether they're inside another object.

I get errors when trying to use something like videos.videoList inside the show menu command.

That should work fine. Can you show the code which is causing the error? Or what the error message is? Then someone might be able to spot the problem.

When pasting code / errors on this forum, you should put it between lines of backticks, like this:

```
Your code here
```

so that the forum doesn't mess it up.

perhaps I can use GetAttribute (videos.videoList)

GetAttribute (videos, "videoList") is exactly the same as videos.videoList. The only time you need to use GetAttribute is when the name of the attribute is in a variable or some other expression.


This is in my videos initialization script. in order to keep track of all the video clips, storing them in variables is going to be easier.

videoList = NewStringList()
introduction = "XHBKM7mBHUM?end=13&rel=0"
list add (videoList, introduction)

To test the system, I am creating a simple menu with one item and a cancel button.

show menu ("Welcome to Chapel Perilous", videos.videoList, true) {
  ShowYouTube (result)
}

this is one of the errors I get when trying to use access the list from inside the object

unlock phone

Unlocked.
You open it.
It contains a videos.

> switch on videos

You switch it on.
Error running script: Unknown menu options type

Other errors are thrown when trying to combine lists and use the video.videoList call, etc. But I can share that code later if this issue doesn't provide answers for the entire set of errors


Does the initialization script also include the line:
this.videoList = videoList
or
videos.videoList = videoList
?

With just the script you showed there, the initialisation script creates a local variable videoList which is discarded as soon as that script finishes.


ok.

this.videoList = NewStringList()
introduction = "XHBKM7mBHUM?end=13&rel=0"
list add (this.videoList, introduction)

fixed it. thanks.


Next question, how to force autoplay?

this.videoList = NewStringList()
introduction = "XHBKM7mBHUM?end=13&autoplay=1&rel=0"
                                  ^^^^^^^^^
                                  not working 
list add (this.videoList, introduction)

http://textadventures.co.uk/forum/quest/topic/xggd1o5hl0eop7olrrgcnw/code-troubleshooting#fe12060e-9ca3-482c-8303-f6a37f738b71

you said

JS.eval("AddYouTube=function(id){addText($('"+Chr(60)+"iframe"+Chr(62)+"',{width:425,height:344,frameborder:0,allowfullscreen:'allowfullscreen',src:'https://www.youtube.com/embed/'+id+((id.search('\\?')>0)?'&':'?')+'rel=0'+((id.search('[?&]autoplay=')>0)?'':'&autoplay=1')}));};")

Is that going to do anything to automatically play the video? It looks like it is just searching the string for parameters and building the youtube video id with parameters, am I right?
Let's assume that most browsers at this point have ad blocking and/or video autoplay functionality disabled by default.

What can I use inside Quest to simulate a mouse click on that video and make it start?


Is that going to do anything to automatically play the video?

No. It just scans the video id passed to it so that it doesn't mangle the last parameter, and so that it doesn't automatically add "autoplay=1" if you already specified an autoplay parameter. Otherwise, it's just the same as Quest's built-in autoplay feature.


What can I use inside Quest to simulate a mouse click on that video and make it start?

You can't. Simulating clicks on another website in an iframe is a huge security risk, because it allows your site to interact with another page the user may be logged in on, possibly without their knowledge. Whenever someone finds a way to do this, it is patched pretty quickly.

If the video is on your own site and included as a <video> element, you might be able to do this. You would at least be able to use javascript to check if autoplay was rejected, and prompt the user to press play.

Could also be possible if you use Youtube's player API to embed the video, rather than an iframe. However, they're trying quite hard to make sure that inconsiderate sites can't use this to play videos without user interaction.


OK ... it looks like Chrome has some pretty complex policies about autoplaying videos.

  • Autoplay of videos is allowed if they're muted. So if you add the parameter mute=1 to the video ID, autoplay should work (but this might not be helpful)

  • Autoplay is allowed if the user is active on the site (the video isn't on the first page they landed on) - for embedded videos, this works a bit differently. I'm not sure (will try to remember to test in the morning, as it's after 3am here), but it should be possible to modify my script so it delegates permissions:

JS.eval("AddYouTube=function(id){addText($('"+Chr(60)+"iframe"+Chr(62)+"',{width:425,height:344,allow:'autoplay',frameborder:0,allowfullscreen:'allowfullscreen',src:'https://www.youtube.com/embed/'+id+((id.search('\\?')>0)?'&':'?')+'rel=0'+((id.search('[?&]autoplay=')>0)?'':'&autoplay=1')}));};")

↑Not sure if that one will work or not. But if it doesn't, then once the player has watched a few videos it would start allowing autoplay.


This is the output, with the video showing below, but no autoplay working,
Not using the JS.eval() in the game initialization script

You switch it on.
Welcome to Chapel Perilous
- XHBKM7mBHUM?end=13&autoplay=1&rel=0

Same output with the JS.eval() in the game initialization script but no video will load.


https://developers.google.com/youtube/iframe_api_reference

YouTube Player API Reference for iframe Embeds

I am going to start reading through this to see what I can do.

YouTube Player API Reference for iframe Embeds

The IFrame player API lets you embed a YouTube video player on your website and control the player using JavaScript.

Using the API's JavaScript functions, you can queue videos for playback; play, pause, or stop those videos; adjust the player volume; or retrieve information about the video being played. You can also add event listeners that will execute in response to certain player events, such as a player state change or a video playback quality change.

This guide explains how to use the IFrame API. It identifies the different types of events that the API can send and explains how to write event listeners to respond to those events. It also details the different JavaScript functions that you can call to control the video player as well as the player parameters you can use to further customize the player.

Requirements
The user's browser must support the HTML5 postMessage feature. Most modern browsers support postMessage, though Internet Explorer 7 does not support it.

Embedded players must have a viewport that is at least 200px by 200px. If the player displays controls, it must be large enough to fully display the controls without shrinking the viewport below the minimum size. We recommend 16:9 players be at least 480 pixels wide and 270 pixels tall.

Any web page that uses the IFrame API must also implement the following JavaScript function:

onYouTubeIframeAPIReady – The API will call this function when the page has finished downloading the JavaScript for the player API, which enables you to then use the API on your page. Thus, this function might create the player objects that you want to display when the page loads.

Has this been implemented on the webserver? I don't know where it would need to be activated, but I don't see it being useful in Quest.


Mobile Considerations
Autoplay and Scripted Playback
The HTML5 <video> element, in certain mobile browsers (such as Chrome and Safari), only allows playback to take place if it's initiated by a user interaction (such as tapping on the player). Here's an excerpt from Apple's documentation:

"Warning: To prevent unsolicited downloads over cellular networks at the user’s expense, embedded media cannot be played automatically in Safari on iOS — the user always initiates playback."

Due to this restriction, functions and parameters such as autoplay, playVideo(), loadVideoById() won't work in all mobile environments.

so I may have to come up with a different idea.


But, it will allow for queuing videos by id it seems, which will be useful, so the API still would have benefits.

Will I be able to use its functions?

if not, eh...


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums