New Menus in 5.4
homeeman
08 Mar 2013, 22:26I absolutely love that they're in-text now. I went out of my way to make all my menus in-text in my last game, and while it wasn't very difficult, it was a hassle when I knew how easy it could be.
Getting to to the point, the new menus are great, but it doesn't appear that there is a way to disallow the player to cancel. If the player enters a response that isn't a number choice the menu goes away with no response. That's... not as convenient. Especially with how terribly I type when I'm testing a game quickly. I figured I'd put a suggestion for a modification to the menus that made a sort of hidden default to keep the menu open after a response.
Currently, I usually make the menu an attribute of the room or character object from the which the menu spawned and have the default set to repeat the menu function. Does anyone know a way to do it without running an attribute over and over? They're not as convenient to get to in the GUI and I avoid code view when I can because I start coding in C++ before long.
Getting to to the point, the new menus are great, but it doesn't appear that there is a way to disallow the player to cancel. If the player enters a response that isn't a number choice the menu goes away with no response. That's... not as convenient. Especially with how terribly I type when I'm testing a game quickly. I figured I'd put a suggestion for a modification to the menus that made a sort of hidden default to keep the menu open after a response.
Currently, I usually make the menu an attribute of the room or character object from the which the menu spawned and have the default set to repeat the menu function. Does anyone know a way to do it without running an attribute over and over? They're not as convenient to get to in the GUI and I avoid code view when I can because I start coding in C++ before long.
Asyranok
08 Mar 2013, 22:50I absolutely agree. Love the way they are displayed but i wish you could add something to make an invalid selection default to a certain choice. That or refresh the menu with a message about it being an invalid choice.
TriangleGames
08 Mar 2013, 23:52Could you maybe catch the player in a while loop that re-displays the menu?
Asyranok
09 Mar 2013, 01:48Thanks triangle. The thought hadnt even occured to me. Im a total beginner when it comes to coding.
homeeman
09 Mar 2013, 06:04While loops in XML (or at least in Quest) continue outside of receiving input. Which is to say, while that would normally work, I've found that in Quest it doesn't. Normally you can simply make the default of your Switch function (in this case, of your Menu) to run the attribute that your script is contained in, but... that doesn't work for me. I can always go back to the way I've done the menus before, I just thought I would point this out in case Alex thought it was an issue worth addressing. Thanks, though!
TriangleGames
13 Mar 2013, 17:24I came up with one solution. I don't see a way to do this without accessing the code view to put it in, but its short and simple.
Raise a UI request to remove the command line when the menu comes up, and then another to put it back after the player makes a choice. This at least makes it clear to the player that they are supposed to make a selection.
In my sample game, they can still escape it by choosing things from the panes, but if you wanted to force the issue real hard, you could hide the panes in the same way.
This is my game file for "trying new things," so there's a variety of stuff there. What you're looking for is "take junk bin."
Here's what it looks like in code.
Raise a UI request to remove the command line when the menu comes up, and then another to put it back after the player makes a choice. This at least makes it clear to the player that they are supposed to make a selection.
In my sample game, they can still escape it by choosing things from the panes, but if you wanted to force the issue real hard, you could hide the panes in the same way.
This is my game file for "trying new things," so there's a variety of stuff there. What you're looking for is "take junk bin."
Here's what it looks like in code.
firsttime {
msg ("The bin itself is too cumbersome to carry around. You should just take out what you need.")
}
binstuff = NewStringList()
list add (binstuff, "bauble")
list add (binstuff, "trinket")
list add (binstuff, "widget")
// this raises the UI request to hide the command line
request (Hide, "Command")
ShowMenu ("What would you like to take from the bin?", binstuff) {
switch (result) {
case ("bauble") {
if (not Got(bauble)) {
msg ("You take a bauble.")
AddToInventory (bauble)
}
else {
msg ("You've already got a bauble. You should see if there's anything useful to do with it before taking more of them.")
}
}
case ("trinket") {
if (not Got(trinket)) {
msg ("You take a trinket.")
AddToInventory (trinket)
}
else {
msg ("You've already got a trinket. You should see if there's anything useful to do with it before taking more of them.")
}
}
case ("widget") {
if (not Got(widget)) {
msg ("You take a widget.")
AddToInventory (widget)
}
else {
msg ("You've already got a widget. You should see if there's anything useful to do with it before taking more of them.")
}
}
}
//this raises another UI request to show the command line
request (Show, "Command")
}
HegemonKhan
13 Mar 2013, 19:16I'm not sure if this is what you're needing for your problem, but I had a crash due to the menu repeatedly spawning before it was finished.
so, could you in your show menu's default, but in the script block's name to (call upon) run the menu again, as a substitute for canceling it, and then use what was suggested to me, to prevent the endless looping (crashing of the game), by using:
on ready {
(show menu script block)
}
this prevents another menu from running while you still are in the old menu. then for the default, call back the show menu script block.
so, could you in your show menu's default, but in the script block's name to (call upon) run the menu again, as a substitute for canceling it, and then use what was suggested to me, to prevent the endless looping (crashing of the game), by using:
on ready {
(show menu script block)
}
this prevents another menu from running while you still are in the old menu. then for the default, call back the show menu script block.
<function name="aaa">
on ready {
show menu ("message", split ("item1;item2",";"), false~true {
switch (result) {
case (item1) {
some_script1
}
case (item2) {
some_script2
}
default {
aaa
}
}
}
}
</function>
homeeman
15 Mar 2013, 00:50What Triangle suggested was something I had thought about doing, but I'm just so adamant about making the games keyboard-only friendly that I couldn't bring myself to do it. What's more, nine times out of ten, when I bring up a menu, it is 100% necessary to get a response of some kind from the player in order for the game to continue, and it would the source of enormous bugs if the menus were skipped in any way for any reason.
I made another game a while ago that I'm submitting to Spring Thing (I had it made a while ago and I've wanted to show to everyone for SO LONG but now I have to wait) in which I broke down and made my own in-text menus back in 5.3 when Show Menu still produced a pop-up. I've just been using that since it's really not that hard, and I know the process by heart now.
Where "mainclassmenu" and "mainclasschoose" are attributes of the room the player is in when encountering these menus. They work, and they're not... inefficient. I think. So you can use those for the time being if you're as anal as me about not making players use the mouse.
I made another game a while ago that I'm submitting to Spring Thing (I had it made a while ago and I've wanted to show to everyone for SO LONG but now I have to wait) in which I broke down and made my own in-text menus back in 5.3 when Show Menu still produced a pop-up. I've just been using that since it's really not that hard, and I know the process by heart now.
<mainclassmenu type="script"><![CDATA[
msg ("<br/>You may choose from these choices for this relevant thing, {player.alias}.<br/>Please enter a number to find more relevant information about these options.<br/>1 - Option 1<br/>2 - Option 2<br/>3 - Option 3<br/>4 - Option 4<br/>5 - Ready to choose")
get input {
switch (result) {
case ("1") {
ClearScreen
msg ("Option one is all about THIS STUFF you should totally pick this one.")
do (PartySet, "mainclassmenu")
}
case ("2") {
ClearScreen
msg ("Option two is all about THIS STUFF you should totally pick this one.")
do (PartySet, "mainclassmenu")
}
case ("3") {
ClearScreen
msg ("Option three is all about THIS STUFF you should totally pick this one.")
do (PartySet, "mainclassmenu")
}
case ("4") {
ClearScreen
msg ("Option four is all about THIS STUFF you should totally pick this one.")
do (PartySet, "mainclassmenu")
}
case ("5") {
do (PartySet, "mainclasschoose")
}
default {
do (PartySet, "mainclassmenu")
}
}
}
]]></mainclassmenu>
<mainclasschoose type="script"><![CDATA[
ClearScreen
msg ("Which option are you picking?<br/>1 - Option 1<br/>2 - Option 2<br/>3 - Option 3<br/>4 - Option 4")
get input {
switch (result) {
case ("1") {
player.class = Option 1
msg ("<br/>You picked option one. You must be a cool dude.")
do (PartySet, "partyclassmenu")
}
case ("2") {
player.class = Option 2
msg ("<br/>You picked option two. You must be a swell fella.")
do (PartySet, "partyclassmenu")
}
case ("3") {
player.class = Option 3
msg ("<br/>You picked option three. Your mother must be so proud.")
do (PartySet, "partyclassmenu")
}
case ("4") {
player.class = Option 4
msg ("<br/>You picked option four. You'll regret that one down the road.")
do (PartySet, "partyclassmenu")
}
default {
do (PartySet, "mainclasschoose")
}
}
}
]]></mainclasschoose>
Where "mainclassmenu" and "mainclasschoose" are attributes of the room the player is in when encountering these menus. They work, and they're not... inefficient. I think. So you can use those for the time being if you're as anal as me about not making players use the mouse.
tlk
13 May 2013, 14:00So this thread is a couple months old, but I thought I'd chime in with what I do in this situation since it's an option that didn't come up in the discussion. I haven't upgraded to 5.4 yet, so I don't know quite what all the differences are, but most of the games that I've been working on in 5.2 and then 5.3 involve some sort of A/B choices and I wasn't a fan of the pop ups, so I just call a function for the choice and recall it if one of the available options isn't picked. That way everything's in-text but easily allows for forcing the choice.
Here you'd call a function named "menu" and it would do this:
It means you have a ton of functions if you have a lot of choices in your game, but I kind of like that every choice point is really easy to find if it needs to be edited. It might not be the most straightforward way, and it might be improvable in 5.4, but it works well for me.
It's simple in the GUI too; you would just create a new function called "menu" and have it run this script:
Here you'd call a function named "menu" and it would do this:
<function name="menu">
msg ("Choose A or B.")
get input {
if (result="a" or result="A") {
msg ("You have chosen A.")
}
else if (result="b" or result="B") {
msg ("You have chosen B.")
}
else {
msg ("---You must choose A or B.")
menu
}
}
</function>
It means you have a ton of functions if you have a lot of choices in your game, but I kind of like that every choice point is really easy to find if it needs to be edited. It might not be the most straightforward way, and it might be improvable in 5.4, but it works well for me.
It's simple in the GUI too; you would just create a new function called "menu" and have it run this script:

jaynabonne
13 May 2013, 17:15If anyone wants some "third-party" menu code, I have some which:
1) Takes a string dictionary for the choices.
2) Puts up the choices in an inline, numbered menu and allows typing a number or clicking the number to choose
3) If the input is invalid, it redraws the menu, telling you what you should type.
4) Takes an object/script pair to allow invoking the script attribute of an object once a valid choice is made.
5) Takes a "pre-script" parameter (can be null) which specifies a script to run before the menu is shown, either the first time or on subsequent times (e.g. the pre-script might clear the screen and dump out a header).
I suspect a number of us have our own menu code libraries.
1) Takes a string dictionary for the choices.
2) Puts up the choices in an inline, numbered menu and allows typing a number or clicking the number to choose
3) If the input is invalid, it redraws the menu, telling you what you should type.
4) Takes an object/script pair to allow invoking the script attribute of an object once a valid choice is made.
5) Takes a "pre-script" parameter (can be null) which specifies a script to run before the menu is shown, either the first time or on subsequent times (e.g. the pre-script might clear the screen and dump out a header).
I suspect a number of us have our own menu code libraries.
