Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dialogue is not character-dependent #3

Open
MichaelPaulukonis opened this issue Nov 11, 2013 · 5 comments
Open

Dialogue is not character-dependent #3

MichaelPaulukonis opened this issue Nov 11, 2013 · 5 comments

Comments

@MichaelPaulukonis
Copy link
Contributor

That is to say -- you can't set conditions for a specific character to speak a certain way.

I don't mean "in French" (per se), but to use different words or phrases.

All dialogue seems to be handled by... different parts of the Character class

  • move_to
  • live
  • converse
  • discuss
  • decide_what_to_do_about
  • converse

... and are not externally exposed (are they?), so they can't be modified/extended without modifying core code.

At any rate -- these notes are for making your engine more generic for my potential purposes and not making it more useful for your definite purposes. So it goes.

@MichaelPaulukonis
Copy link
Contributor Author

In a larger scheme of things, beyond character dialogue, the "tone" of narration cannot be changed.
This is a more core issue of the engine -- f'r instance, passive voice or anything else of variance.

@catseye
Copy link
Collaborator

catseye commented Nov 11, 2013

Point about generic and definite purposes noted. During November, I might be more concerned with my own definite purposes, but it looks like this is shaping up to something that might exist beyond November, so, yes, we can at least discuss it and identify how it could be made more generic...

The main weakness, as I see it, is that each Event object is built around a "phrase", which is a template, like <1> went to <2>. Obviously, this makes them tied to English, and worse, to particular phrasing in English (tense, choice of words, etc.) Ideally, Events would be more abstract than that. For instance, you could instead have a MoveEvent for that purpose, and it could be the Editor's job to select an appropriate phrase for rendering that Event as an English sentence (or in present tense or in Spanish or whatever.) (This is assuming that it's the Editor's responsibility to set the "tone of narration", which I think is reasonable.)

The problem with that is that it's a pain to manage this extra level of abstraction, especially when you're just hacking away at code, trying to get your ideas out. (A solution to that might be to make it optional. I'll think about it.)

As to how the classes are structured:

The Animate class is the base class for things that can move on their own accord, while, currently, Character is The Swallows-specific. The idea is that you (presumably) make characters for your own story by subclassing Animate to your own Character class. You'd implement the live method, and you'd call the methods on Character in that implementation, such as move_to, pick_up, and so forth.

(For the moment, I can probably add a better example of doing this sort of thing, to not_the_swallows.py.)

discuss, converse, and decide_what_to_do_about are Character-specific, because they do control very story-specific logic*, but I agree that they could and probably should be generalized somehow. Although, again, doing so while not imposing a particular sort of dialogue style might be a little difficult. (If you've ever played games written in Inform, with the standard Inform libraries, you notice that they tend to have a similar "voice", aspects of which date all the way back to the original Zork, or rather, MIT's Dungeon -- but I digress.)

One idea I've had is to make an intermediate class, maybe called Sentient, which is part of the engine, and thus generic, and establishes a framework for conversing/discussing. Character would then be a subclass of Sentient. In writing your own story, you could either subclass Sentient for your characters -- in which case they would provide stock reactions for anything you haven't overridden -- or you could copy and customize it, or just write your own, if you wanted to have the characters have a very different dialogue style.

Hope this all makes some sort of sense.

*Heck, they used to be one big method, until I could not stand the deep indentation any longer.

@enkiv2
Copy link

enkiv2 commented Nov 11, 2013

With regard to Event objects -- what about taking a page out of predicate
logic's book and saying that an event is a named relationship between two
or more objects (which could be Characters or Events)? Then, the structure
of how an Event is turned into words can be implemented separately (and
maybe even put into a different class altogether), making it possible to do
tenses and randomize phrasing and conjugate verbs based on gender and even
do limited kinds of literal translation. In the meantime, to maintain
backwards-compatibility, you could have the default string representation
reproduce Event's current behavior.

On Mon, Nov 11, 2013 at 9:14 AM, catseye notifications@github.com wrote:

Point about generic and definite purposes noted. During November, I might
be more concerned with my own definite purposes, but it looks like this is
shaping up to something that might exist beyond November, so, yes, we can
at least discuss it and identify how it could be made more generic...

The main weakness, as I see it, is that each Event object is built around
a "phrase", which is a template, like <1> went to <2>. Obviously, this
makes them tied to English, and worse, to particular phrasing in English
(tense, choice of words, etc.) Ideally, Events would be more abstract than
that. For instance, you could instead have a MoveEvent for that purpose,
and it could be the Editor's job to select an appropriate phrase for
rendering that Event as an English sentence (or in present tense or in
Spanish or whatever.) (This is assuming that it's the Editor's
responsibility to set the "tone of narration", which I think is reasonable.)

The problem with that is that it's a pain to manage this extra level of
abstraction, especially when you're just hacking away at code, trying to
get your ideas out. (A solution to that might be to make it optional. I'll
think about it.)

As to how the classes are structured:

The Animate class is the base class for things that can move on their own
accord, while, currently, Character is The Swallows-specific. The idea
is that you (presumably) make characters for your own story by subclassing
Animate to your own Character class. You'd implement the live method, and
you'd call the methods on Character in that implementation, such as
move_to, pick_up, and so forth.

(For the moment, I can probably add a better example of doing this sort of
thing, to not_the_swallows.py.)

discuss, converse, and decide_what_to_do_about are Character-specific,
because they do control very story-specific logic_, but I agree that they
could and probably should be generalized somehow. Although, again, doing so
while not imposing a particular sort of dialogue style might be a little
difficult. (If you've ever played games written in Inform, with the
standard Inform libraries, you notice that they tend to have a similar
"voice", aspects of which date all the way back to the original *Zork_,
or rather, MIT's Dungeon -- but I digress.)

One idea I've had is to make an intermediate class, maybe called Sentient,
which is part of the engine, and thus generic, and establishes a framework
for conversing/discussing. Character would then be a subclass of Sentient.
In writing your own story, you could either subclass Sentient for your
characters -- in which case they would provide stock reactions for anything
you haven't overridden -- or you could copy and customize it, or just write
your own, if you wanted to have the characters have a very different
dialogue style.

Hope this all makes some sort of sense.

*Heck, they used to be one big method, until I could not stand the deep
indentation any longer.


Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-28202690
.

@MichaelPaulukonis
Copy link
Contributor Author

There is an article on NPC dialogue starting on p331 of IF Theory Reader (PDF) (linked-to from http://nickm.com/if/toward.html ).

Abstraction is not easy - and you should only abstract what you need to abstract. Otherwise: YAGNI.

So, these notes are not nesc. for THIS MONTHS'S implementation.....

Something (potentially?) simple would be to allow for easy addition of stock phrases to a character -- where you now have

        if choice == 20:
            self.emit("<1> yawned", [self])
        elif choice == 21:
            self.emit("<1> gazed thoughtfully into the distance", [self])
        elif choice == 22:
            self.emit("<1> thought <he-1> heard something", [self])
        elif choice == 23:
            self.emit("<1> scratched <his-1> head", [self])
        elif choice == 24:
            self.emit("<1> immediately had a feeling something was amiss", [self])

maybe the templates could be part of each Character, can be set externally, and the core picks from those phrases?

I'll look into how to use "Animate" instead of Character. The name reads as a verb-action, primarily....

@catseye
Copy link
Collaborator

catseye commented Nov 11, 2013

Hm, that's true; I'm usually fairly pedantic about making sure class names are nouns. I think I'm unconsciously imitating Inform's nomenclature here. Come to think of it, Actor isn't a very good name for a class that includes passive things like locations and treasures, either. I think I'll wait until this has actual version numbers before contemplating renaming such basic things, though.

I agree that setting up a list of stock "idle actions" shouldn't be too hard. At least not for Swallows characters. There could be some method that returns a list of template strings, and it just picks one, and you could override that (for, say, Fred.) In general terms... still not too hard but I'd like to think about just what should be in Sentient first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants