Back to list
Views:   11.1K
Replies:  2

Interpretation Setup Consultation (C#)

Hello. This is my first question ever. Party right here. Now, onto the question!

Background information:
I am creating a framework for a game. It is a M(ulti) U(ser) D(ungeon) or a text based imagination driven interactive book or at least that's how I see it. I'm taking an approach to it that is hopefully rather fresh. I have not really looked into all the different ones already in existence because I do not want the vision I have to be tainted (you will not change my mind on this). Enough about that though. Right now I am working on the command text interpretation system.

I view all input from the user to fall into the following 6 categories:

Actions - grab/touch/look/feel
Action Arguments - the action "stand" takes an argument "up" (things that indicate how-to do an action)
Quantity Indicators - some/three/dozen/all
Identity References - my/he/it/Bob/them
Identity Descriptors - dark/blue/tall/ignorant
Order of Execution - before/after/next/previous/then/and

The idea is that Actions know what they need to look for. The action "grab" knows how to check for a who or a what and possibly a quantity in the command text. If multiple actions are present they execute in the order they are found unless Order of Execution modifies are present. Now this is all swell and dandy but what exactly is my question?

The question:
I am all about coding simplicity. Easy to understand readable flexible code design as I am sure most of the people on this site are. I picture there being three steps to interpenetration:

  1. Filter the command text of ignorable words (like "the") and excess garbage
  2. Re-order, if necessary, based on any Order of Execution modifiers
  3. Execute the Actions.
I do not plan on doing all the development of the interpretation library so I want people to simply have to create the actions, quantity indicators, or order of execution words. Is there a pattern(s) or a way I could set things up to achieve this? I may not need a pattern to do what I want to do but I do want to consult with those more wise to evaluate what I may be missing. I am thinking about using a "as long as there is another action" Chain of Responsibility setup with the actions using the Command pattern. Maybe, simply using the Command pattern and executing based on a possibly reordered List<IActionWords> calling "Execute(Context, CommandText)" would work. I'm not sure what I want yet.

All of this is design work. A string of text comes in and I am deciding how I want to handle it from there. Please feel free to suggest anything as I have nothing more than "string comes in now what?".

Thanks in advance! I do appreciate the time it takes to wrap you're head around what I've said and also the time it takes to devise and respond to my question.

Karl Wessels, Jul 25, 2011
Reply 1
Let me start off by thanking you. I was quite suprised to see your reply but even more so when I noticed that you (maybe) created your account to just reply to my question! Sweet ^_^

I'll address what you have me in much the same manner it was given.

1. I wouldn't use a third party. I'll take concepts from other things but as for simply using them is not something I plan to do. It creates a dependency in most cases. I want full liberities with the design and implementation of my model/system.

2. You did lose me a little bit in your bird example but let me try to give me thoughts on it.

"Put bird in cage" is definitly viable. Now, I add an aviary to my game where there are hundreds of birds. I'm not sure what you mean by the implied "the" but here is how I see things going down. "Put" should be intelligent enough to go:

put> what?> looks at the identity reference "bird" > can we find a sole instance of bird? > no > is a quanity given > no > put fails.

what if it was "put five bird in cage" though incorrect grammatically someone could try it:

put> what?> looks at the identity reference "bird" > can we find a sole instance of bird? > no > is a quanity given > yes > are there identity descriptors given? > no > take first 5 or less identities (entities/objects) that match "bird" and put them into cage (assuming it allows that) up to however many will fit.

I foresee the actions being rather intellegent about what they do; developing with the needs of my game/framework. I plan to let the objects, cage in this case, handle the addition of birds.

I really do not forsee "the" really being used. It simply states "an identity reference is coming up" or more often it connects words for the tongue. I've tried to think of cases where it matters but so far I haven't. I will be consulting a few "english major" friends of mine as I progress.

3. It seems like the purpose of my reordering step is a bit foggy. First, let me say that my game is not going to be like any prior. I am always asking "What we would be the best version of this idea/feature be?" then proceeding to *try* and create it. Let's just say I have a big dream for this game. Anyhoo!

Take the sentence, "grab the hat after standing up", which to me is a worthy command in game. Without reordering it I would "grab the hat" then "stand up" while the command clearly was intended to be the other way around. I want this type of syntax to be do-able because it allows more natural combo commands. In addition to that eventually the command input will be wired to a voice-to-text system (I think it will be easy to do).

4. I believe the parts of speech are irrelevant. The reason being I look at them in more simpler terms being the six I mentioned above almost programmatic if you will.

"My" says "The one who gave the command" so then "My knife" says "The giver of the command's knife."

The reason for breaking things down differently is to avoid the pitfall of an expected format. Using the examples you gave as reference it seems far more complex than letting the actions define what they do. Take "statistics" for example. If that was the entire command it would come back with "of what?" because is that not what you thought when you read it? Now, "statistics for Bob" it would come back with "Bob is age 24 currently eating an ice cream cone in his villa in Arizona." for example. The word knows what it expects to operate on and how to find it. You could leave out "for" and that would be shorthand because it is merely a connector in this case.

I can see why you might think this "would be fiendish to hand code" but it really only becomes that when you try to add a lot to a simple thing. As we (the developers of the framework) have a need for new action or an existing one to do more it can be incorperated then directly into the action.

5. I love your examples. WE GET CHICKEN! (that might be an easter egg :P)

You bring up some good points to consider. When throwing a bird does the bird have a state and how does that affect the action.

All I can tell you now is that as I am thinking about the command system I am also modeling out my Obj (objects since C# has it as a keyword) and Entity models. I forsee my model developing as my actions are. In order to "unlock and open the door" I first must have a door and the commands unlock and open.

6. This really made me smile/laugh because of your examples.

"throw axe" would expect a direction or a target.

"take axe at dwarf" might operate like this: take> what?> found axe> at dwarf are not actions therefore there is nothing to do.

however given "take axe from dwarf": take> what? found axe> is there a what or who?> found from> from what/who?> found dwarf> take the axe from the dwarf (which I am guessing would trigger off an event on the dwarf).

"take dwarf": take> what?> dwarf found> is dwarf take-able> no> do nothing.

"take knife": take> what?> knife word found> can we resolve a knife reference> no> do nothing.

7. This is where my mind is grid locked at the moment. The reason I brought up the command pattern is that it *could* be called via "Action.Execute(commandText)" in which the Action knows how to execute it. The next part I question is from there how do we execute the next command if it exists which is why I brought up the chain of responsibility pattern at least for the idea of "passing it off to the next".

This is the part I am trying to map out. I'd like to keep it to the "three steps to interpertation" I mentioned about. How it actually comes together is really up to the imagination. Maybe the "thought process" I use in response 6 will give you more of an idea of what I got/am thinking.

I'll keep reviewing what you answered above and see if it sparks any ideas. You have given me a lot of good things to think about as well as a good laugh or two :) I'd love to keep discuss things with you or even work with you. If you're interested in either then perhaps we could get some email correspondence going. I won't be offended at all if you are not.

Thank you! Catch you later.

Karl Wessels, Jul 28, 2011
Reply 2

If I'm understanding your goal right, you want to create an extensible engine, where other developers are able to add new commands (and, perhaps, new objects that can be maniuplated, etc.).

Here are a bunch of thoughts generated by your question. Some may be way off the mark - in which case please forgive me. Hopefully, however, some will be helpful and will give you new directions of inquiry as you design your system.

1. You can rule out third party parsers
There are a number of parsers "out there" (GOLD comes to mind, but I know there are others).  Since a parser generator expects a fully defined grammar (I think this is true in the general case) none will meet your need since you want to be able to discover new commands at run time - and parser generators need to know the text of keywords are the time the parser is generated.

2. Planning for complexity
You may need to do a little more thinking about the possible complexity of the game you plan to create, before you can create an engine that meets your need. Here's a scenario that bears thinging about:

Consider a room with a bird in it; the adventurer has a cage.

"Put bird in cage" is a viable command.

Now, consider that you'd like to add an aviary to your game - where there are several (maybe hundreds) of birds in the room. An implied "the" may not be sufficient - maybe you'll want the user to be able to say "put five birds in cage" or "fill cage with birds" (requires bird size and cage volume, or cage bird count capacity, constraints, etc.).

The above scenario is intended to illustrate that you need to strongly consider whether ignoring words like "the" will always work, or will only be acceptable depending on context. This greatly affects your parser.

3. Reordering
The text-based adventure games I've played require a single command on a line. So, (in those games, at least) there is no need to reorder commands, or to queue them, etc. 

Perhaps you plan to implement some temporal constraint on commands - so that commands issued on the same command line have a different relationship with each other than commands issued on distinct command lines do.

Either way, I'd make my engine start by splitting the input on the sequencing keywords; it can then sort the now distinct commands, and submit them one at a time to the true command interpreter - just as if they had been typed one per input line. And, if you have a 'commands on the same line are related' you can pass to the command interpreter a token of some kind (a line number, perhaps) that indicates their relationship.

The bottom line is that I see the reordering action as a step prior to true command interpretation, making the latter simpler.

4. Command interpretation
   This, of course, is the hard part, and I suspect that you have some more thinking to do before you're ready to implement your engine. (Look at your Identity References examples: 'my' and 'Bob' (or 'knife') are very different parts of speech, so cannot both be identity references ("my" doesn't specify the thing in question, whereas "Bob" very concretely specifies a thing).  "my knife", "Bob's knife" and "Bob" are all equivalent parts of speech (things - nouns), with two of those phrases having extra content that selects a specific knife.)
   I recommend that you write a description of the grammar you want to implement and then experiment with dozens of possible commands to see if it works.
   Here's an example (which is probably overcomplex and far from workable, but it hopefully illustrates an approach to designing your interpreter):
   <command>         := <action> <object phrase> [<action modifier phrase>]
   <action>          := {command name from internal dictionary}
   <object phrase>   := [<object selector>] [<adjective>] <object> [<post-selector>]
   <object>          := {object name from internal dictionary; singular and plural forms accepted interchangeably}
   <object selector> := my | the | <number> | <posessive> | his | hers
   <number>          := {digit string} | one | two | some | any | dozen | ...
   <post-selector>   := in the corner | behind the door | ...
  [...]    represents an optional clause
  x | y    represents a choice of x or y
  ...    means I couldn't be bothered to enumerate all the possible choices!
 Note that the grammar above is almost certainly overkill for a text-based game - and would be fiendish to hand code. So - researching how other text-based games interpret their input might be useful.
5. Objects and actions
   Before beginning to create an object model for your application, I'd spend some time thinking about how objects and actions are related and, sometimes, constrained. Here are some examples of what I'm thinking:
   You can put a bird in a cage. You can probably put stones, a lamp and a water bottle in the cage, too, if you care to.
   You can throw a stone. Can you throw a bird? What happens when a stone is thrown (and how far will it travel)? What happens when a bird is thrown (is it alive, asleep, stunned, dead, etc.)?
   You can light a lamp, but not a rock. What happens when you try to light the bird? (Grilled chicken?)

6. Incomplete and meaningless commands
   You can 'take knife', but can you 'throw axe'? Or must you 'throw axe at dwarf'?
   What does it mean if the user types 'take axe at dwarf'? Or, 'take dwarf'?
   What does your engine do if the user types 'take knife' and there is no knife in the room to take?
   You need to think about these questions as you design your model. 
7. Design Patterns
 None of the above even begins to address OO design patterns, but you will need to address the kinds of concern I raise above before you can start designing an object model for your engine.
 Let's assume that you've thought through the above and have some solid conclusions. What are some of the obvious objects in your game?
 * TheGame (probably a container for everything else)
 * Player(s)
 * Objects (rocks, birds, etc.)
 * Places & 'connectors' (doorways, tunnels, transport portals, etc.)

 I keep trying to find a way to use the Command Pattern, but it just doesn't seem to fit: each type of object (and place) likely has different actions that it can, or cannot, perform.  If there are hundreds of objects in your world, and some can be thrown while some can't, how do you express the throwability of an object, using the Command Pattern?  The point of the command pattern is that each command implements a stragety (Strategy Pattern) that depends on all commandable objects having a common set of properties, - but each command is completely agnostic about the specific type of object being commanded (and objects are command-agnostic, too, so an IsThrowable property is out of the question).

 SO... to have a model where other developers can add new commands you have to have a pre-defined set of modifiable attributes (and context, I suppose: the "take" command may move the target object from being contained in the room to being contained in the player's backpack). So, custom objects can only meaningfully expose the same set of properties (any extra properties will be unrecognized by commands, that only know about a particular interface).

 AH! Lets say your friend Joe wants to implement some specialized objects (magic spells) and specialized commands to work with them. I guess he could create objects that implement the mandatory IGameObject interface, but also implement the IMagicObject interface; his set of commands have access to the IGameObject properties, but can use reflection to discover if the object at hand also implements IMagicObject and, if it does, manipulates the object accordingly.
 SO - maybe the command pattern will work for you, after all.
I'm Done
I know I've not directly answered your question, for which I apologise, but I hope that some of what I've said makes sense and is useful. It may be that after you've thought about the interactions between (the) player(s), places and objects that you want to be able to implement, you'll discover what design patterns will support you.

Chris Trelawny-Ross, Jul 26, 2011
Stay Inspired!
Join other developers and designers who have already signed up for our mailing list.
Terms     Privacy     Cookies       Do Not Sell       Licensing      
Made with    in Austin, Texas.  - vsn 44.0.0
© Data & Object Factory, LLC.