Easier Name/Gender Selection?

I haven’t yet figured out how to code this myself, so in looking for assistance (and in how to handle conversation), I came across Michael Callaghan’s excellent (in my opinion) “Questions” extension. The example game that is included with the documentation works flawlessly, but I’m having some timing issues in my own game. Primarily because I have zero understanding of how his extension is interacting with my horrible code.

I’ve tried searching the forums, but stock phpBB has a completely inept search function. I also can’t find anything in the many awesome PDF manuals and quick starts that I have archived.

“Questions” seems overly complicated for what I’m wanting to do. I assume that there’s going to be some indexed text involved. I know, it’s evil. I also assume that the gender can be changed simply with a “Now the player is a woman” or whatever. (Haven’t tried this, but this is the least of my concerns.) Questions seems to use its own value for gender, though I forgot to test it. Maybe it changes the gender too, though that seems to be a questionable topic as well.

I don’t want to “break immersion” by having to force the player to “say male” or “say female”. I want to change the prompt to “Are you a man or woman” and let the player just type that word.

Now, this is where I assume (an unfortunate thing) that indexed text comes in. I also assume (again with that) that the player can have a text called player_name or something along those lines.

If anyone can just point me in the right direction, that’d be fantastic.

What’s with the indexed text hate? I love those little guys.

I was looking to Questions for my own game at first, but it turned out to be overkill for what I needed. Something else I realised in general from playing with it was that, if you seek to make the player type a word and press enter, the only way inform can do that is via the parser. So whenever you wanna lock people off into answering a question by typing-and-entering, your answer must travel through the whole parser mechanism, and you have to block everything else while the question is being answered. I’m not a fan of going the road that unless I have to.

When might you not have to? Well, when the answer doesn’t really need to be typed.

Would you be happy for a menu to appear saying “1 male” and “2” female" and let the player press 1 or 2?

This is an aesthetic decision as well, obviously. You may want the player to type everything and press enter, depending on your game, or you may hate menus, or whatever. But if you’re cool to go the menu route, I definitely prefer it because it creates a bulletproof moment where the player can’t do anything but press 1 or 2, and all the code required to respond to that moment is in one place, not scattered in rulebooks. And it’s easy to understand and program. I agree that Questions can be confusing to deal with.

Below here there’s a bunch of code, so I folded it in a ‘rant’ tag.

[rant]Here’s my code blob which basically sets up this kind of menu. Think of it as the extension:

[code]Include Basic Screen Effects by Emily Short.

The infinite_loop is a number variable. The infinite_loop is 1.

Current question is text variable.
Current question menu is a list of text that varies.
Current question answer is a number variable.

Asking a menu question is a rulebook.

To ask a menu question: follow the asking a menu question rules.

An asking a menu question rule:
while the infinite_loop is 1 begin;
say current question;
say line break;
say fixed letter spacing;
repeat with counter running from 1 to the number of entries in the current question menu begin;
say “[counter] - [entry counter of the current question menu][line break]”;
end repeat;
say variable letter spacing;
let k be 0;
while k is 0 begin;
let k be the chosen letter;
end while;
now k is k minus 48;
now current question answer is k;
if k is less than 1 or k is greater than number of entries in the current question menu, say “[line break]You need to press a number between 1 and [number of entries in the current question menu].[paragraph break]”;
otherwise make no decision;
end while.[/code]

With this in place, here’s how to ask a question:

now current question is "Do you want to be male or female?"; now current question menu is { "Male", "Female" }; ask a menu question;

After the ‘ask a menu question’ line, ‘current question answer’ is the player’s numeric choice. So in this case, it would 1 if they picked male, and 2 if they picked female. The program will not proceed until the player has made a valid choice.

You can have up to 9 choices in your menu in this system. Obviously when it gets to 10, a person can’t type ‘10’ in one keypress.

Here’s a runtime example of the whole thing you can dump in your compiler to see it in action:

[code]Include Basic Screen Effects by Emily Short.

There is a room called Question Arena.

The infinite_loop is a number variable. The infinite_loop is 1.

Current question is text variable.
Current question menu is a list of text that varies.
Current question answer is a number variable.

Asking a menu question is a rulebook.

To ask a menu question: follow the asking a menu question rules.

An asking a menu question rule:
while the infinite_loop is 1 begin;
say current question;
say line break;
say fixed letter spacing;
repeat with counter running from 1 to the number of entries in the current question menu begin;
say “[counter] - [entry counter of the current question menu][line break]”;
end repeat;
say variable letter spacing;
let k be 0;
while k is 0 begin;
let k be the chosen letter;
end while;
now k is k minus 48;
now current question answer is k;
if k is less than 1 or k is greater than number of entries in the current question menu, say “[line break]You need to press a number between 1 and [number of entries in the current question menu].[paragraph break]”;
otherwise make no decision;
end while.

When play begins:
now current question is “Do you want to be male or female?”;
now current question menu is { “Male”, “Female” };
ask a menu question;
say line break;
if current question answer is 1:
say “You chose male.”;
now player is male;
otherwise:
say “You chose female.”;
now player is female.[/code][/rant]

After choosing a sex in the demo, you can verify you really are of that sex by typing ‘showme me’.

One of the curious aspects of Inform is that it seems to arouse strong feelings of compassion or avoidance towards some of its elements. Some people dislike tables, some scenes, some lists, some indexed text. I know because I myself avoid relations even though I know doing so is completely irrational.

Avoiding indexed text is purely a personal preference. It is an aspect of the language like any other and you don’t gain anything by intentionally avoiding it. You may have seen forum posts where people ask how to do certain things without using indexed text. Sometimes they ask because they do something really memory-intensive or that requires speed optimization, but more often than not it’s because of the indexed text phobia. It’s unfortunate that it sometimes comes across as if using indexed text is something everyone should avoid in all situations.

Granted, if you have a situation where you can substitute normal text for indexed text, you should do that because of good programming practices. (nb: Substitute, as in changing variable’s type from indexed to normal text, not rewrite to work with normal text.) But if you have a simple issue that indexed text is meant for and you spend considerable time and effort to come up with a solution that doesn’t use indexed text, you’re wasting your time for little to no benefit. More often than not the workarounds use up much more of the game’s resources than a simple indexed text variable ever could.

Here’s one way you can do this without avoiding the parser.

"Example"

Rule for printing the banner text when waiting for gender is true: do nothing. Instead of looking for the first time: do nothing. [These prevent anything from appearing when the game begins.]

waiting for name is a truth state variable. waiting for name is true.
waiting for gender is a truth state variable. waiting for gender is true.
player's name is an indexed text variable. 
A person can be ambiguously gendered.

When play begins: say "First, we need to know your name. What is it?"; now waiting for name is true.
	
After reading a command when waiting for name is true: now waiting for name is false; now player's name is "[the player's command in title case]"; replace the player's command with "gender".
	
Gendering is an action out of world applying to nothing. Understand "gender" as gendering when waiting for gender is true. Carry out gendering: say "And which gender are you?".

To tidy up introduction: now waiting for gender is false; say "Very well then![paragraph break]"; say banner text; try looking. 

Identifying as male is an action out of world applying to nothing. Understand "male" as identifying as male when waiting for gender is true. Carry out identifying as male: now the player is male; tidy up introduction.

Identifying as female is an action out of world applying to nothing. Understand "female" as identifying as female when waiting for gender is true. Carry out identifying as female: now the player is female; tidy up introduction.

Identifying as neither is an action out of world applying to nothing. Understand "neither" as identifying as neither when waiting for gender is true. Carry out identifying as neither: now the player is ambiguously gendered; tidy up introduction.

Instead of doing anything other than gendering, identifying as male,  identifying as female or identifying as neither when waiting for gender is true: say "Please, answer the question."

Starting Room is a room with printed name "[player's name]'s Room". "Well, young [if player is ambiguously gendered]one[else if player is male]man[else]lady[end if], here you are."

Being a wiseass by nature, I might suggest some other kind of response should the player actually enter “neither” as his/her/its gender. Of course, you might also want to allow for “both” – which is (I think) biologically possible, although it might further complicate pronoun choice.

Robert Rothman

“Neither” and “both” are both genders belonging to some humans on this planet.

I looked at Menus, but again, unnecessarily complicated for what I’m trying to do. I couldn’t exactly get a feel for how it handled things.

I haven’t tried it yet, but I do appreciate the Aaronius Approach to the situation. Simple, no additional extensions required and will probably play better with my code. I do have Questions implemented and it WORKS, but the way I had to do it is UGLY and I suspect there are going to be some issues down the road.

I’m hoping this simpler approach works better.

No offence to eunuchs, transgenders, transvestites and the rest of the ambiguously gendered individuals of the world who may or may not be reading, but you will not be represented here.

As for indexed text hate, I’m ashamed to say that I’m a victim of herd mentality here. I don’t really understand it or what it’s for, so I basically go on what I read from others until I have learned enough to have my own opinion on the matter. Individuals with YEARS more experience than me hate it, so I figure they hate it for a reason.

The jury is still out for me on tables. Again, I’m not entirely sure how they work in Inform. I reserve judgement.

As a transgendered eunuch that dresses as a furry, I am offended!

(just kidding… as he tucks his tail between his hind legs and sulks off…)

Tables is my newest favorite tool. I am sure I will over-use it. But for now, it is letting me do things that were very ugly before when I did it the hard-coded way.

Indexed text is something I have used (based on others help) but I am far from being able to claim understanding of the full depth to which it can be used. I think once I know more, I will go “Duh!” and be more open to this deviance of nature. :wink:

I guess this is a little off-topic for the original post, but since tables have been discussed I would add that, as one without much experience in these matters, I find tables extraordinarily useful. For example, I use them all the time to generate random “business” in the background as part of an “every turn” rule when the player is in a particular location. I could do it using a “say [one of] A [or] B [or] C [at random]” statement, but I find it a lot more convenient to list all of the possible items in a single-column table; my every turn rule chooses a random entry from the table and plugs that into a “say” statement. It’s easy to see at a glance what the items are, and easy to change or add items.

As another example, I am currently writing a game which includes a rather complicated machine; if a player tries to use the machine incorrectly, it generates an error message (depending on exactly what the player did wrong) which shows up on a screen which is part of the machine. The rule which tests all of the machine settings to determine which, if any, error message is appropriate is complicated enough as it is without building the text of all the error messages into the rule. Instead, I use the rule to set a numerical code corresponding to the particular errror; I then use a table to associate each code with the text of the corresponding error message.

Another example (which I just coded a few days ago): The game includes a camera with a limited number of frames of film, and I want to keep track of what the player has photographed. I created a table with a number of rows equal to the number of frames of film, but left the entry for each row blank. Each time the player photographs an object, I have it choose a blank row and substitute the object photographed for the blank entry. Thus, as the game progresses, the table will effectively become a list (not in the Inform 7 sense of the word) of the things that the player has photographed. I wouldn’t know how to do this without using tables.

Robert Rothman

I don’t mind the thread hijack, since the issue has been resolved. Aaron’s approach to the issue was stunningly simple and fit perfectly into the game without messing up anything else. (I will be buying the book, by the way.)

Anyway, I love the IDEA of tables. I just haven’t yet found a good explanation on how to use them. Or rather, I did, but I keep losing it. I just want to look up a certain value in a certain row. I don’t want to have to TELL Inform to cycle through the table to find it. It should do that automatically and invisibly without my prompting it to do so. There’s no other way to look anything up in a table. I keep finding the syntax and losing it again.

I foresee needing a table. Or maybe several. Or maybe a very large one. I don’t really know yet. But like I said, coming from a programming background that leans heavily on databases (though I’m not very good at it), I’m definitely glad that this functionality exists and I intend to lean heavily on it. I hope it doesn’t let me down. (Or I it.)

Also, props to severedhand for that suggestion. It was a bit over my head at this current juncture in time, but I don’t want you to think I’m unappreciative for the input and an alternative. I might certainly put your example to use in the future and I definitely may learn something from it.

There are many ways to do this, and it isn’t at all necessary to iterate through the table (Chapter 15.5, Choosing Rows):

choose row 2 in Table of Quips choose row with quip-text of "Hi!" in Table of Quips choose a blank row in Table of Quips choose a random row in Table of Quips

You may find the syntax document useful:

inform7.com/learn/documents/I7_syntax.txt

(It’s not quite up to date, I don’t think, but it will usually be good enough.)

–Erik

No worries. Actually I’m so chuffed with my little blob, I may turn it into an extension :slight_smile: - but first I’ll change all the variable names to avoid namespace collisions with Questions, which was my starting place for writing it.

I didn’t mean “There’s no other way to tell Inform to do this.” I meant that, universally, there’s no other way to tell anything to look anything up in a table. Doesn’t matter what you use, that software or service starts at row one and goes down until it finds the value you’re looking for.

I can just never remember the Inform syntax for “Get value of column X where value of column Y is Z”.

And that’s what I meant. For example, if I say

query = "SELECT gender FROM player_variables WHERE id=0";

It’s going to start at row 0 of the table and zip down through the rows until it finds ID 0. I’m not TELLING it to do this, it just knows automatically to do this. There’s never a reason where I have to manually tell it to start at row 0 and go down until it finds what I’m looking for.

Maybe I’m misunderstanding the use for tables as described in the documentation everywhere but 15.5.

repeat with N running from 1 to the number of rows in the Table of Recent Monarchs:

Honestly, that makes my head a’splode.