I’m having a hair pulling experience of trying to achieve a random name generation routine for NPCs in Inform 7. I am only 8 days into learning Inform, but I have been stuck on this one exercise for about 72 hours now and I still can’t get it right. Could anyone help?
Basically I have one room, and a button. An NPC is in the room, and the idea is that when you press the button, the NPC’s name changes to a randomly selected name from a list/table. This happens everytime you press the button.
I have just about got it working using an indexed-text property to control the printed name of the NPC, (as opposed to changing the coded name of the NPC) but where I am really falling down is being able to UNDERSTAND the new name. That is to say:
A man called Nameless is here.
Press large button
A man called Adam is here.
I don’t see such a thing.
…please help?! it’s driving me insane!!
I tried Understand “[random name]” as the man.
And a million other combinations but it doesn’t work.
For complicated reasons, you can’t use an understand line that way with a text property (which is what “printed name” is). Instead, you need to use an indexed text property. Here’s a complete little example to illustrate how to do it, and a couple of ancillary issues that arise:
[code]Test is a room.
A person has an indexed text called the real name. Understand the real name property as describing a person.
Rule for printing the name of a person (called the being):
say “[real name of the being]”;
Wizgo is a man in Test. The real name is “Wizgo”.[/code]
I use JUMP as my action of choice when I want to check out something quickly like this. Here, typing JUMP changes the real name of the NPC to “Billy”:
First instead of jumping:
change the real name of Wizgo to "Billy";
say "Name changed to [Wizgo].";
Because the name of an object is usually understood by the parser, we also need to prevent the game from referring to be Billy when the player types “Wizgo”. One way to do that is to make NPCs “privately-named”, which prevents the parser from understanding the name (it can still understand the real name property, though, because we’ve told it how to do that above):
A person is privately-named.
(If the player also has a name, you might want to revise that so the player is not included. For example, “Wizgo is privately-named.”)
You might also want to give the player a bit more guidance when he types the wrong name. To do that, we can look at the player’s command before we’ve actually parsed it:
After reading a command when the player's command includes "wizgo" and the real name of Wizgo is not "Wizgo":
if the player can see Wizgo:
say "Wizgo is not here any longer. [Wizgo] is here now.";
reject the player's command.
This works really well, until it comes to the NPC’s possessions and things that are a PART of the NPC. At this point these parts are subsequently stored using the original coded name. For example, SHOWME Billy might read:
Billy - man
Wizgo’s hair (part of Billy) - Hair
location: in the Computer Room
unlit; inedible; portable; singular-named; proper-named
printed name: Billy
printed plural name: men
carrying capacity: 100
real name: Billy
Notice the ‘hair part’ remains coded back to Wizgo. I actually tried coding the following line to try and solve this:-
change the printed name of wizgo’s hair to “[real name of wizgo]'s hair”;
Which worked in so far as SHOWME was concerned, but crucially, typing:
examine billy’s hair
resulted in a no such thing exists again. Although examining Wizgo’s hair worked fine… (?)
Remember, we haven’t changed the name of the Wizgo object–that’s not possible. We’re only working out ways to refer to the Wizgo object as something else, both in the parser and in the output. SHOWME and particularly TREE generally work with the actual names of objects, and thus they are always going to be able to refer to the object as Wizgo, even if in some cases they use the printed name instead (this is how the hair in your example was correctly referred to as “Billy” even though the hair was identified as Wizgo’s).
So, here’s how you can do this. The basic set-up is the same; just as we had to break the normal parsing of our NPC’s name, we now have to break the normal parsing of hair and substitute our own:
hair is a kind of thing. Hair is part of every person. Hair is privately-named. Understand "[something related by reversed incorporation] hair" as hair. The printed name of Wizgo's hair is "[Wizgo]'s hair".
Note that this understand line for hair will match “Billy hair”, not “Billy’s hair”. That’s because Inform needs a space between tokens to understand them, and the apostrophe + s won’t be correctly matched. So, we need to hack a bit to get rid of the apostrophe-s from the player’s input before we try to parse it:
After reading a command when the player's command includes "hair":
let T be indexed text;
let T be the player's command;
replace the regular expression "[apostrophe]s hair" in T with " hair";
change the text of the player's command to T;
Veering aside: If your people are really going to be this complicated, you might want to consider just keeping a stable of precreated characters off-stage to be swapped in as needed, rather than messing around with changing the name as we’ve been doing. This is much easier:
[code]Test is a room.
North of test is TesTube.
Wizgo is a man in Test.
Adam is a man.
Billy is a man.
First instead of jumping:
let candidate be a random off-stage person;
remove Wizgo from play;
move the candidate to the location;
say “Wow, now his name is [candidate]!”[/code]
The only real advantage of the first method is that the name you give to the person can be any text; you can generate it randomly, or you can even ask the player to provide the name. The more complicated the person who’s having his name changed is, the more work you’ll have to do to hide the seams. This second method requires that all the possible names be spelled out in advance, and created as separate people, but it’s otherwise far easier.
Yea I was trying to build up a huge stock of names (hundreds) within a table, so that a character’s identity could genuinely be a surprise not just to the reader, but also to me the author. I suppose one of the reason’s I’m attracted to writing IF, is the idea that the author can enjoy the finished product just as much as the reader can – with the random element being the central component. Consider a whodunnit, where the culprit turns out to be Howard Rivers, 68 years old, Occupation: Marine Biologist etc. Rather than the author already having a preloaded idea that it’s got to be either Adam, Billy, or Christopher etc…