Dynamic Predicates limited to two parameters

I’ve been messing around with Dialog with a bit to see if it would work for a project I’m working on and ran into a hurdle I was curious to see if there was any way around. Currently what I am trying to do is use a predicate (Communicated friendship $Communicator to $Listener about $Friend $Value) to store and reference the last communicated friendship value of one person to another about some third person, a total of 4 parameters however when trying to use the special syntax (now) I’m given an error that dynamic predicates must be limited to two parameters. I’m curious if there is some other way I would be able to store and reference this data or if it is just not possible to do dynamically?

1 Like

If I understood correctly, and everything is set dynamically for every person in the game, it’s not really possible. (It’s like when Inform 7 doesn’t have a way to have weighted relations.)

A way would be to use lists instead. You’d store a list as a property of the communicator, such as [#Listener #Friend 3]. Or you could split it into 3 separate properties.

However, if you need to store more than one relation for each communicator, then it becomes a list of lists (at the risk of making finding or updating a value slower if the list is very big).

If there’s only one communicator in the game word (e.g. the player), it would be easier, but I don’t think that’s your situation.


I found this bit from the guide helpful when making sense of this, though you’ve probably seen it already:

Let’s pause for a while and consider a matter of design philosophy. I have claimed that in Dialog, objects are nothing but names, and the world is modelled using relations, represented by predicates. When it comes to per-object flags (and per-object variables, to be introduced below), that standpoint is starting to look tenuous. To be sure, dynamic predicates are designed to look and behave just like ordinary predicates when you query them. And in order to change the state of the game world, you issue now-commands that appear to modify predicates rather than objects. But at the same time, there are restrictions on how you can update those predicates, so that, in effect, what you can do is more or less exactly what you could do by storing flags (and properties) inside objects.

In the end, whether you choose to regard a dynamic per-object flag as something that resides inside the object, or in a separate data structure that represents the dynamic predicate, is entirely up to you. The actual runtime representation is irrelevant, and the compiler will in fact choose among different representations based on how the predicate is accessed from various parts of the program.

@Natrium729’s suggestions seem good; exactly the right workaround probably depends on how you want to end up querying this information, though…

1 Like
(friendship [$Communicator $Listener $Friend $Value])

is another approach, in addition to the

($Communicator communicated [$Listener $Friend $Value])

approach Nathanael suggested.

I experimented with making an access predicate wrap around (friendship [$Communicator $Listener $Friend $Value]) but kept crashing when I tried doing (now) on it, so that doesn’t seem to be a way to pretty up the code-prose.

1 Like

That’s what I thought. I will give your list idea a go and see if that works for what I’m trying to do. I do have more then one relationship per communicator, everyone will have a value (even if it’s a default 0) for every listener friend pair. As well this isn’t the only relationship, this covers communicated friendship but actual friendship is another value which I’ll have to store as a list. But this does give me a place to start so hopefully I’ll be able to take this and figure out what exactly will work best for me.

Sorry if it’s obvious and I’m not seeing it but is there a difference in the way these two approaches operate? For example is one faster than the other? I do somewhat prefer the second due to the psuedo object orientation (one can think of the communicator as storing the list) design.

If using a list of list, to avoid consuming too much memory, you’ll have to delete entries which have the default value (like 0).

Then you’ll have to write a bunch of helpers to retrieve a relationship, set one (and if setting to 0, delete it), change one, and so on. It might be tedious or difficult to implement.

I think will be faster to use properties on communicators, because it will be faster to retrieve. If you use a global, you’ll have to walk the whole liste to find the one that starts with the right communicator. (If I understood correctly @MultidimensionalStep’s suggestion.)

1 Like