Using the same Alt names for different objects

psymann
02 Apr 2013, 00:25
Hello all,

I did have a search around but couldn't see this already answered in another thread so apologies for one last question for today!


In the kitchen, there is a "Letter to Mr Smith".

I want it to appear written in-game as "Letter to Mr Smith" to be clear to the user what it is. But I want my user to take it with the command "Take Letter" since "Take Letter to Mr Smith" is a bit silly.

But...

In the study, there is a "Letter to Mr Jones".

I want it to appear written in-game as "Letter to Mr Jones" to be clear to the user what it is. But I want my user to take it with the command "Take Letter" since "Take Letter to Mr Jones" is a bit silly.


Setting alt names of them both to include "Letter" works fine individually, and I can take either letter.

But if I try to take a second letter, when I'm already carrying the first, I get an error message: "Error running script: Error adding key 'Letter to Mr Jones' to dictionary: An item with the same key has already been added."


Is there a way round this? Or do I have to use a workaround, such as:
- not allowing the two letters to meet
- calling one of them a note instead of a letter
- creating a special command called "take letter" that prompts the user to be more specific

psymann

HegemonKhan
02 Apr 2013, 00:46
the ' NAME ' must be unique ("there can only be one") as this is what the game engine uses to identify the individual objects. if there is no set ' ALIAS ' , then the game player sees the ' NAME ' and if there is an ' ALIAS ', then the game player sees the ' ALIAS '

object.name.potion
object.name.potion
ERROR!

-----------------

the ' ALIAS ' has no restriction on how many of the same words there is for them. the game player will see the ' ALIAS ' if one has been set, otherwise, they'll see the ' NAME '.

object.name.potion1.alias.potion
object.name.potion2.alias.potion
NO error

-----------------

the "ALT" (alternative) is for convenience for the game player with them typing in commands, so they can type in some short version instead of a long NAME or ALIAS, and~or for familarity, as what might seem like the obvious command word to use for you, may not be so for someone else. Like, for you, typing in "equip" might be obvious, but for someone else, what's obvious for them might be, "don" or "wear" or "put on" or "dress", so you can (need) to provide more options so to prevent the game player from getting stuck, merely due to not being able to guess the single command word for something that you set up, not realizing it may not be so obvious to someone else.

--------------

I'm guessing that the error's reference to dictionary, refers to the game.pov ("player's") inventory (objectlist), unless you're trying to implement your code with your own created dictionary(-ies).

the game should only care about the ' NAME ' attribute of the objects, you can't have two ' NAMES ' being the same. the game shouldn't care though if you got two objects with the ' ALIAS ' of "potion", so long as their ' NAMES ' are different (such as "potion1" and "potion2").

---------------

otherwise, the problem is with the dictionary's ' KEY ' word, and~or with if you are using a COMMAND*, and this will take maybe some extra coding for it to work (work around) the problem.

*COMMAND as in the universal verbs (see below), as command can be used more generally in the quest terminology talk too.
<command name="fight_command">
<pattern>fight #text#</pattern>
<script>
fight_function (game.pov,text)
</script>
</command>


or, you could... simply add a number to the letters: letter1, letter2, and etc.

as adding one more character (a number) isn't a big deal, typing letter vs typing letter1, big deal, lol ;)

-------------

for us to help you, we'd need to see your code, with what you're doing, if you don't mind sharing it of course, as we can't really help much more, as it is currently too ambigious for us to accurately help you.

psymann
02 Apr 2013, 01:02
Object 1:
Name: Letter to Mr Smith
Alias: Letter to Mr Smith
Alt Names: Letter
Parent Room: Kitchen

Object 2:
Name: Letter to Mr Jones
Alias: Letter to Mr Jones
Alt Names: Letter
Parent Room: Study

Player starts in Kitchen.

You are in a Kitchen.
You can see a Letter to Mr Smith.
You can go east.

> Take Letter
You pick it up.

> east
You are in a Study
You can see a Letter to Mr Jones.
You can go west.

> Take Letter
Error running script: Error adding key 'Letter to Mr Jones' to dictionary: An item with the same key has already been added.
Error running script: Too few parameters passed to ShowMenu function - only 3 passed, but 4 expected


<object name="Study">
<inherit name="editor_room" />
<exit alias="west" to="Kitchen">
<inherit name="westdirection" />
</exit>
<object name="Letter to Mr Jones">
<inherit name="editor_object" />
<alias>Letter to Mr Jones</alias>
<alt type="stringlist">
<value>Letter</value>
</alt>
<take />
</object>
</object>
<object name="Kitchen">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<exit alias="east" to="Study">
<inherit name="eastdirection" />
</exit>
<object name="Letter to Mr Smith">
<inherit name="editor_object" />
<alias>Letter to Mr Smith</alias>
<alt type="stringlist">
<value>Letter</value>
</alt>
<take />
</object>
</object>


If I do nothing other than change the Alt of "Letter to Mr Jones" to "Letterb" and then "Take letterb" when I'm in the study, it works fine and I can pick up both letters.

psy

[Edit: let me know if that's sufficient code to help - if not I can provide you the full file of a test environment game with nothing but the kitchen, the study, and the two letters]

HegemonKhan
02 Apr 2013, 01:32
okay... I don't have any error... lol.

I was able to take (pick up) both letters and have them in the player's inventory, using your code...

I had to change your code (presumably it is quest v5.4), so it would load, as I'm still using quest v5.3, and it worked fine for me.

<!--Saved by Quest 5.3.4762.29157-->
<asl version="530">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<gameid>d83ba5bb-2e3c-4f31-80c9-3e88a2dc082c</gameid>
<version>1.0</version>
</game>
<object name="Study">
<inherit name="editor_room" />
<exit alias="west" to="Kitchen">
<inherit name="westdirection" />
</exit>
<object name="Letter to Mr Jones">
<inherit name="editor_object" />
<alias>Letter to Mr Jones</alias>
<alt type="list">Letter</alt>
<take />
</object>
</object>
<object name="Kitchen">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<exit alias="east" to="Study">
<inherit name="eastdirection" />
</exit>
<object name="Letter to Mr Smith">
<inherit name="editor_object" />
<alias>Letter to Mr Smith</alias>
<alt type="list">Letter</alt>
<take />
</object>
</object>
</asl>


as you can see, the only difference is that the ALT, doesn't have it's value script nested, and also the stringlist is known as "list" in v5.3, too.

so, you got something set up wrong with how you need to do it with v5.4, hmm...

I'd need to look at the changes of v5.4, lol

so there's only 2 differences between your v5.4 code, and my v5.3 code, so either the problem is with the nested value of the ALT, is causing the ALT label of "Letter" to be used as the KEY for the player's inventory (an objectlist, which is a dictionary or a stringlist), and thus the error, or it has to do with the syntax or format of the "stringlist" coding, as this was changed a bit from v5.3 to v5.4, in how it's done.

HegemonKhan
02 Apr 2013, 01:43
try this (select all, copy, and paste it into your game code):

<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<gameid>d83ba5bb-2e3c-4f31-80c9-3e88a2dc082c</gameid>
<version>1.0</version>
</game>
<object name="Study">
<inherit name="editor_room" />
<exit alias="west" to="Kitchen">
<inherit name="westdirection" />
</exit>
<object name="Letter to Mr Jones">
<inherit name="editor_object" />
<alias>Letter to Mr Jones</alias>
<alt type="simplestringlist">Letter</alt>
<take />
</object>
</object>
<object name="Kitchen">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<exit alias="east" to="Study">
<inherit name="eastdirection" />
</exit>
<object name="Letter to Mr Smith">
<inherit name="editor_object" />
<alias>Letter to Mr Smith</alias>
<alt type="simplestringlist">Letter</alt>
<take />
</object>
</object>
</asl>


------------------------

I actually think your only mistake might be a very simple syntax mistake:

corrections (there's two of these ALT code lines below, in your code for each "Letter" object):

<alt type="stringlist">
~TO~
<alt type="list">

so, try this code too (as well as the code above):

<asl version="540">
<include ref="English.aslx" />
<include ref="Core.aslx" />
<game name="Testing Game Stuff">
<gameid>d83ba5bb-2e3c-4f31-80c9-3e88a2dc082c</gameid>
<version>1.0</version>
</game>
<object name="Study">
<inherit name="editor_room" />
<exit alias="west" to="Kitchen">
<inherit name="westdirection" />
</exit>
<object name="Letter to Mr Jones">
<inherit name="editor_object" />
<alias>Letter to Mr Jones</alias>
<alt type="list">
<value>Letter</value>
</alt>
<take />
</object>
</object>
<object name="Kitchen">
<inherit name="editor_room" />
<object name="player">
<inherit name="editor_object" />
<inherit name="editor_player" />
</object>
<exit alias="east" to="Study">
<inherit name="eastdirection" />
</exit>
<object name="Letter to Mr Smith">
<inherit name="editor_object" />
<alias>Letter to Mr Smith</alias>
<alt type="list">
<value>Letter</value>
</alt>
<take />
</object>
</object>
</asl>


and let me know if:

both codes work, only top code works, only bottom code works, or if neither code works.

------------

P.S.

here's a very useful link for when working with the code, lol:

http://quest5.net/wiki/Category:All_Fun ... t_Commands

and here's the links pertinent to this topic you have here:

http://quest5.net/wiki/List
http://quest5.net/wiki/Stringlist
http://quest5.net/wiki/Objectlist
http://quest5.net/wiki/Using_Lists

http://quest5.net/wiki/Dictionary
http://quest5.net/wiki/Stringdictionary
http://quest5.net/wiki/Objectdictionary
http://quest5.net/wiki/Scriptdictionary
http://quest5.net/wiki/Using_Dictionaries

jaynabonne
02 Apr 2013, 08:51
"stringlist" is the 5.4-renamed "list" type. There is no "list" type in 5.4 anymore, as such. Be careful lest you confuse each other! :)

jaynabonne
02 Apr 2013, 08:54
psymann: This seems to be some sort of bug in Quest, probably in 5.4 (since it works for HK). It fails for me as well.

However...

Quest already does prefix matching (e.g. you can type "take let"). If you get rid of the alt names, it will work as you wish.

Edit: actually, it is a bug of another sort. I think Alex's last minute ShowMenu change is biting him as well (unless my install is hosed). I get this:

Error running script: Too few parameters passed to ShowMenu function - only 3 passed, but 4 expected

It's supposed to put up a menu where you can choose which letter to take (since the command "take letter" is ambiguous). That fails for me. Does that fail for you as well?

jaynabonne
02 Apr 2013, 09:39
Update: I emailed Alex, and he said he'll post an update for this issue shortly (the ShowMenu one). The alt name issue is a different bug, but there is a workaround (for you), so it might be able to be rolled out later - once it's determined what it is.

psymann
02 Apr 2013, 10:38
I've updated to the new version of Quest 5.4

Using the same code as before, I now get:

You are in a Kitchen.
You can see a Letter to Mr Smith.
You can go east.

> take letter
You pick it up.

> east
You are in a Study.
You can see a Letter to Mr Jones.
You can go west.

> take letter
Error running script: Error adding key 'Letter to Mr Jones' to dictionary: An item with the same key has already been added.
Please choose which 'letter' you mean:
1: Letter to Mr Jones
2: Letter to Mr Smith

Clicking on either of the hyperlinks does work which is definitely an improvement, thanks Alex!, but I still get an error message.

jaynabonne
02 Apr 2013, 10:55
That's the other bug. Did you try removing the alt names?

psymann
02 Apr 2013, 11:01
Ah, ok, I guess I will live with that other bug for the time being then because chances are it'll get fixed before I've completed the rest of my adventure and it's only a cosmetic problem as far as I can see.

I haven't removed the ALT names, no, because I want to keep them - because actually what I want to do is stop the Abbreviated Object Naming from working as I don't like it - it seems quite wrong that someone can walk into a room, and just type "Take a", "Take b", "Take c" ... "Take z" and by doing so have found every object in the room that isn't hidden away inside something else. The way I'm writing my adventure is to turn off the objects list both in the text and on the side panel, so you actually have to read what's written to work out what objects are there, and the abbreviated object naming messes that up a bit - I'm more than happy to add plenty of ALT options so people don't have to type everything in full, but they do at least have to type something recognisably the same as what they want to interact with ;)

So actually I want to turn that feature off - I can see a note from Alex in 2008 for the QUest 4.03 update saying "You can now turn off the player's ability to use abbreviated object names, by adding 'abbreviations off' to the 'define options' block." ...

...problem is that I don't know what that means or what the 'define options' block is :-S

psy

jaynabonne
02 Apr 2013, 11:23
So here is a temporary fix. The problem is that Quest is assembling lists of full and partial matches, and it checks whether an object is already on a list before adding it, but it doesn't check whether the object is already on the *other* list. So you end up with the same object on both lists (if it both partially and fully matches), and then when it goes to generate the menu, you end up with this dictionary problem.

This change looks in both lists before adding to either.

Add this replacement function into your game file:

  <function name="CompareNames" parameters="name, value, obj, fullmatches, partialmatches">
if (name = value) {
if (not ListContains(fullmatches, obj) and not ListContains(partialmatches, obj)) {
list add (fullmatches, obj)
}
}
else {
if (StartsWith(name, value)) {
if (not ListContains(fullmatches, obj) and not ListContains(partialmatches, obj)) {
list add (partialmatches, obj)
}
}
else {
// check if input matches the start of any word in the name
if (Instr(name, " " + value) > 0) {
if (not ListContains(fullmatches, obj) and not ListContains(partialmatches, obj)) {
list add (partialmatches, obj)
}
}
}
}
</function>


I don't see a way in 5.4 to disable partial matches. If you don't want them, then just delete the primary "else" in the above, which is what implements partial matches.

Asyranok
02 Apr 2013, 17:10
Jay the "too few parameters" error occurs when you have not selected "yes" or "no" for the "force user to answer?" Parameter

sonic102
02 Apr 2013, 18:25
This is actually a Quest mistake.

Inform would have said "which letter, to Jones or to Mr smith?" which is idiotic since you are holding the Jones letter.

TADS is smarter, it would pick up the Smith letter.

jaynabonne
02 Apr 2013, 18:55
Perhaps that's another one. But the one being run into here was a Quest bug (similar to the recent Ask thread), which was caused by a last minute change in the number of parameters to ShowMenu - which wasn't propagated to internal functions calling it. And Alex has dropped a new version which fixes that.

jaynabonne
02 Apr 2013, 18:59
sonic102 wrote:This is actually a Quest mistake.

Inform would have said "which letter, to Jones or to Mr smith?" which is idiotic since you are holding the Jones letter.

TADS is smarter, it would pick up the Smith letter.


The problem (as I see it) is that Quest doesn't attach semantics to verbs and states. So it just looks for matches for what you type. In other words, it doesn't know the difference between "take letter" and "drop letter" as far as which makes sense, since there is no context attached to it. It would be an interesting challenge to do so - to say "for this object, this verb is no longer viable". And to change Quest to only allow targets which support verbs. It would require rewriting all the parsing code to do that. Perhaps in a later version... :)

psymann
27 Apr 2013, 16:23
jaynabonne wrote:Add this replacement function into your game file:

  <function name="CompareNames" parameters="name, value, obj, fullmatches, partialmatches">
if (name = value) {
if (not ListContains(fullmatches, obj) and not ListContains(partialmatches, obj)) {
list add (fullmatches, obj)
}
}
else {
if (StartsWith(name, value)) {
if (not ListContains(fullmatches, obj) and not ListContains(partialmatches, obj)) {
list add (partialmatches, obj)
}
}
else {
// check if input matches the start of any word in the name
if (Instr(name, " " + value) > 0) {
if (not ListContains(fullmatches, obj) and not ListContains(partialmatches, obj)) {
list add (partialmatches, obj)
}
}
}
}
</function>


I don't see a way in 5.4 to disable partial matches. If you don't want them, then just delete the primary "else" in the above, which is what implements partial matches.



This works, thanks :-) Both solved the error message I was getting, plus disabled the partial matching very nicely :-D