Ask About / Tell About and objects

This is a discussion / support forum for the Hugo programming language by Kent Tessman. Hugo is a powerful programming language for making text games / interactive fiction with multimedia support.

Hugo download links: https://www.generalcoffee.com/hugo
Roody Yogurt's Hugo Blog: https://notdeadhugo.blogspot.com
The Hugor interpreter by RealNC: http://ifwiki.org/index.php/Hugor

Moderators: Ice Cream Jonsey, joltcountry

User avatar
Ice Cream Jonsey
Posts: 28877
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Ask About / Tell About and objects

Post by Ice Cream Jonsey »

For the first time, I am gonna use ask about and tell about in a game. I am sure I could find this if I looked, but.... what's the industry-standard way of avoiding having to code objects for conversational topics?

So if I want to mention the weather in the game's text, and let Hugroid ask Nimroid about the weather, how do you guys set that up? I looked at Taleslinger's code for Clockwork Boy, but it seems everything you can talk about is an actual in-game object.

I'll update HxE if I get the answer!
the dark and gritty...Ice Cream Jonsey!

User avatar
Ice Cream Jonsey
Posts: 28877
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Post by Ice Cream Jonsey »

Whoa! And this page answers my next question, which is "keeping track of the number of times asked!"

http://hugo.gerynarsabode.org/index.php?title=DoAsk
the dark and gritty...Ice Cream Jonsey!

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

As far as the first question goes, I think the industry standard is making an object for the topic. I think Merk actually rewrote his conversation code to work strictly off of strings, so you could look at that if you want to go that route (EDIT: this is wrong. Merk didn't do this.). Part of the reason I gravitated to Hugo in the first place, though, was being able to use objects in my conversation code, since for whatever reason, it offended me that I had to type an object's nouns and adjectives twice.

If you do end up using the object route, the most important thing is to use the known attribute. DoAsk/DoTell use the anything grammar token, so objects being referenced do not need to be in scope but they do need to be known.

Code: Select all

object weather "weather"
{
    article "the"
    noun "weather"
    is known
}
The nice thing about using objects- besides inheriting nouns and adjectives and such- is that you can attach whatever other properties to it. Actually, while writing this reply, it occurs to me that my 'timesasked' system would be much better off if I put the properties in every object to be asked about and not in the characters themselves, using a character-numbering system like phototalk.hug.

My 'timesasked' code is the basis that I used for my take on 'the king of shreds and patches' conversation system. I haven't polished it up for any kind of release, but you can look at it here: http://roody.gerynarsabode.org/JC/doasktopics.hug

In the next day or so, I think I will try swapping around the properties and see if it makes it that much easier to set-up (I think it might!).

Hmm, I was going to finish up this post with going over how Merk handled it with his games, but it seems like I was wrong. He has some string-y stuff in there, but for the most part, it's just the regular way.

Anyhow, you could change the DoAsk grammar to just expect a word instead of 'anything' or something, but it's going to be a big can of worms if some of your topics have two or three word names, I think. Probably not worth it.

Actually, that gives me an idea.

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

Well, no. I was thinking you could have:

Code: Select all

verb "ask"
* living "about" word        DoAskWord
line defined before DoAsk, but that'd both require all of your non-object topics to be one word and you'd have to recreate everything that'd normally be handled by DoAsk.

Anyhow, I will be interested in hearing where you go with this.

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

Well, even though it's less than ideal, I threw together a DoAskWord routine to go with the above. It first checks to make sure that the word isn't an adjective or noun (originally was going to only do the latter but thought I'd let it be more receptive) before doing its thing:

Code: Select all

object can "tin can"
{
	adjective "tin"
	noun "can"
	in STARTLOCATION
}

character fred "Fred"
{
	noun "fred"
	in startlocation
	after
		{
		object DoAsk
			{
			select xobject
				case can : "yay can!"
			   case else : "I dunno!"
			}
		object DoAskWord
			{
			select xobject
				case "weather" : "Yay weather!"
				case else : return false
			}
		}
}

routine DoAskWord
{
	local i
	                            ! the 29th object is either the last
   for &#40;i=29; i <=objects;i++&#41; ! hugolib-defined object or the first
	&#123;                           ! non-hugolib object, depending on whether
	if ObjWord&#40;xobject, i&#41;      ! HugoFix is on
		return Perform&#40;&DoAsk, object, i&#41;
	&#125;

	speaking = object

	if object is unfriendly
	&#123;
		if not object.ignore_response
			Message&#40;&Speakto, 4&#41;    ! "X ignores you."
		speaking = 0
	&#125;
	elseif object = player
	&#123;
		VMessage&#40;&DoAsk, 2&#41;             ! "Talking to yourself..."
		return false
	&#125;
	else
	&#123;
		if not object.after
		&#123;
		  	! "Doesn't seem to know anything..."
				VMessage&#40;&DoAsk, 6&#41;
		&#125;

#ifclear NO_SCRIPTS
		SkipScript&#40;object&#41;
#endif
	&#125;
	return true
&#125;

User avatar
Flack
Posts: 8822
Joined: Tue Nov 18, 2008 3:02 pm
Location: Oklahoma
Contact:

Post by Flack »

I don't know if this can be applied to Hugo or not, but in "A Game of Chance" (Inform 6) I did the following with my NPCs:

life [;
Ask: switch (second) {
'slot', 'machine', 'slot machine':
"~Yeah, you did a number on that one, didn't you. I've never seen quite so much drool on a machine before.
Impressive.~";
'clock', 'time':
"~Yes sir, it's half-past time for you to go.~";
'carpet':
"~Matches the drapes, thanks.~";
'drapes':
"~Matches the carpet, duh.~";
'drink', 'drinks', 'alcohol', 'beer', 'beers', 'shot', 'shots':
"~Oh no my friend, you've had quite enough.~";
'poker', 'liquor':
"~Poker in the front, liquor in the rear. Er, wait ...~";
'weather':
"~Partly cloudy, with a chance of you being really hung over tomorrow.~";
};
Kiss: "Although the Pit Boss appreciates your offer, alas, he is on the clock.";
Attack, ThrowAt: Pit_Death();
],
before [;
Talk: Pit_Speak();
],


For objects that the player could interact with I set up actual objects, but for one-line retorts, I did them this way.
"I failed a savings throw and now I am back."

User avatar
Ice Cream Jonsey
Posts: 28877
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Post by Ice Cream Jonsey »

Just a quick reply before work and before I've had coffee: thanks for all the code samples! You guys are the best.

I figured out what was wrong. I didn't have a noun attached to the object I wanted to ask or tell about. I just had the definition like so:

npc blahblah "blahblah"
{
}

Once I threw a noun in there, it worked.

I am going to throw in the code you wrote, Roody, and see if I can get that to work though!
the dark and gritty...Ice Cream Jonsey!

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

I updated my take on 'shreds and patches' to keep times-asked quantities in object properties (instead of the characters). Initially, I was hoping I could do something like this:

Code: Select all

property timesasked #5
where it'd then give every object 5 empty elements, the way that the size property declaration gives every object a default value of 10. Unfortunately, that isn't possible so one still has to manually add the properties to every object. On the plus side, this makes the element-application a lot less wasteful (as there are going to be lots of non-topic objects), and I made adding the properties a little bit easier by making a couple object classes and then using the "inherit" function to quickly add those properties to objects (got this idea by looking at Merk's code recently).

Anyhow, I think the code is a bit more readable now. You can take a look at: http://roody.gerynarsabode.org/JC/reversetopics.hug . Anyhow, the topics-listing aspect is completely optional; you can also just make use of its time-asked-counting scheme.

Also, again going back to the original issue, if the problem is that you want to avoid responses like >GET WEATHER "You don't see that.", you could make a topic object class that has default responses like the following:

Code: Select all

class topic_object
&#123;
	found_in &#123;return location&#125;
	before
		&#123;
		object
			&#123;
			"Don't be silly."
			&#125;
		xobject
			&#123;
			if verbroutine = &DoAsk,&DoAskQuestion,&DoTell,&DoTalk
				return false
			"Don't be silly."
			&#125;
		&#125;
	is known
&#125;

topic_object weather "weather"
&#123;
	article "the"
	noun "weather"
	before
		&#123;
               ! because it is feasible that someone might type
               ! >EXAMINE WEATHER
		object DoLook
			&#123;
			"The weather sure is nice."
			&#125;
		&#125;
&#125;

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

I turned this ask/tell-counting system into a library extension. You can pick it up here.

Roody_Yogurt
Posts: 2179
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt »

I was thinking recently about how any game with ASK/TELL should have some way of telling the player what he can ask about even if it isn't doing the fancy "times-asked"-counting I've tried to do in the posts above. I thought I'd throw together a quick example of how you can put such a thing in your game!

Code: Select all

property ask_topics ! property to hold list of objects that can be asked about

character don "Don Rogers"
&#123;
	in startlocation
	noun "don"
	ask_topics paul producer slash
	after
	&#123;
		object DoAsk
		&#123;
		select xobject
			case paul&#58; "\"I have a better idea. I'll talk over you.\""
			case producer &#58; "\"I have a better idea. I'll play 'The Spirit of
			Radio' again.\""
			case slash &#58; "\"He thinks \Ihe\i knows radio!\""
			case else &#58; "Don cuts your mic."
		&#125;
	&#125;
&#125;

replace DoTalk
&#123;
	print "You can ask "; The&#40;object&#41;; " about ";
	NewPropertyList&#40;object, ask_topics&#41;
	"."
&#125;

routine NewPropertyList&#40;obj, prop, artic&#41;
&#123;
	local a, b, n, total

	for &#40;a=1; a<=obj.#prop; a++&#41;
	&#123;
		if obj.prop #a ~= 0 &#58;  total++
	&#125;

	for &#40;a=1; a<=obj.#prop; a++&#41;
	&#123;
		b = obj.prop #a
		if b
		&#123;
			n++
			if artic
				The&#40;b&#41;
			else
				Art&#40;b&#41;

			if n <total> 2
				print ", ";
			elseif n = total - 1&#58;  print " ";

			if n = total - 1
				print AND_WORD; " ";

		&#125;
	&#125;
&#125;

Post Reply