Representing NPC Knowledge of relationships

This grew out of wanting to generalize the (your $) predicate to arbitrary NPC possessions, but I think this idea of how to represent NPC knowledge of relationships between objects is of general interest. The basic idea is to use a predicate of the form ($NPC thinks [$ $ $]), for example (#edith thinks [#rosemary #owns #tabby-cat]). Here’s the code for the generalization of (your $):

%% Knowledge of Possessions of Oneself
(a $Possession)
	(current player $Self)
	*($Self thinks [$Self #owns $Possession])
	your (maybe link $Possession)
(the $Possession)
	(current player $Self)
	*($Self thinks [$Self #owns $Possession])
	your (name $Possession)
(dict $Possession)
	(current player $Self)
	*($Self thinks [$Self #owns $Possession])
	your

%% Knowledge of Possessions of Others
(a $Possession)
	(current player $Self)
	*($Self thinks [$Owner #owns $Possession])
	~($Owner = $Possession)
	(a $Owner) (no space)'s (maybe link $Possession)
(the $Possession)
	(current player $Self)
	*($Self thinks [$Owner #owns $Possession])
	~($Owner = $Possession)
	(a $Owner) (no space)'s (name $Possession)
(dict $Possession)
	(current player $Self)
	*($Self thinks [$Owner #owns $Possession])
	~($Owner = $Possession)
	(name $Owner) (no space)'s

Test with:

(intro)
	#black-cat (a #black-cat)
	(line)
	#tabby-cat (a #tabby-cat)
	
(#edith thinks [#edith #owns #black-cat])
(#edith thinks [#rosemary #owns #tabby-cat])

#room
(room *)
(#edith is #in *)
(#rosemary is #in *)
(#black-cat is #in *)
(#tabby-cat is #in *)

#edith
(current player *)
(name *)
	Edith
(female *)
(proper *)

#rosemary
(name *)
	Rosemary
(female *)
(proper *)

#black-cat
(name *)
	black cat
(animate *)

#tabby-cat
(name *)
	tabby cat
(animate *)

With this you get things like this:

#black-cat your black cat
#tabby-cat Rosemary's tabby cat

One less than optimal thing is that the following doesn’t do what I wanted it to do (add “Rosemary’s” to the dict). I remember running into this issue before and know why it doesn’t work the way I want it to, but I’m wondering if there is now a solution with the changes that have gone into the language since then.

(dict $Possession)
        (current player $Self)
        *($Self thinks [$Owner #owns $Possession])
        ~($Owner = $Possession)
        (name $Owner) (no space)'s
2 Likes

It’s possible to do, but not in an elegant way. I’ve been considering adding support for your suggested way of doing it, but it’s not there yet.

What you can do is:

    ...
    (collect words) (name $Owner) (into $List)
    (last $List $Word)
    (join words [$Word 's] into $Genitive)
    $Genitive

Be aware that once you start constructing object names algorithmically, performance will suffer on low-end systems, because the compiler can’t figure out at compile-time what words refer to what objects.

2 Likes