Wednesday, 8 December 2010

OK, these are the classes needed to run that data structure. Thankfully it's not as complex a diagram

























The important concept here is that of the Narrator. We have a narrative, so we need a Narrator. (Although StoryTeller might be a better name).

Anyway, the Narrator needs an interface to to the system. I want to be able to run this through an automated test harness, so I'm going to abstract that interface as a Stage. And then have TestStage, TextStage and GUIStage as different implementations that interface with a test harness, the console, and the game proper.

Let's do the details:

Narrator: This class controls the progression of the scene. It also holds the userdata table that funcs can access.
  • scene is the Scene object being narrated
  • narrative is the current narrative. 
  • index is the index into the narrative item array.
  • new() is the constructor
  • load(scene_xml) takes a string containing a scene in XML format and loads it ready for playback. Arguably, by the Single Responsibility Principle,  it would be better design to put the responsibility for XML design into the Scene class, and pass load a Scene object. We'll see if it causes problems
  • play(interface) plays the scene until it hits a cut or a Choice or runs out of narrative
Scene: Already documents

Stage: This is the root class for the interface classes that interpret narative items. Again, this is an "imaginary" base class. There's no implementation, at least not in my Lua code. If I ever implment the same system in another language, I might well create it.

That said, it's worth looking at the methods:
  •  set_background(file): takes a pathname for an image file and displays it.
  •  text(message): displays message as a line of dialogue or monologue
  • choice_show(options): Takes an option list and shows it as a menu
  • choice_result: Get;s the result from the show operation. The choice needs to be split into two parts since the script needs to leave Lua and return to the C++ engine to show the menu. There's also a nasty bit of hackery where the result winds up in the ChoiceShow.result class member. As soon as I think of a more elegant way to do that, I'll do it. Also, it occurs to me that I haven't documented Option yet.
  • thumbnail(image,where,operation): displays a thumbnail image. Arguments as per Thumbnail object class members
TestStage: Implementation of Stage for the lunit test harness. Operations that would normally be sent to the screen and instead stored in an output queue so they can be checked by the test routines.
  • items: queue of narrative items to be processed
  • output_q: queue of outputs since last call to Narrative:play
I'm not entirely sure why items isn't called input_q.

These are specific to the TestStage class:
  • clear(): clears the output queue
  • num_oq(): returns number of items in the output queue
  • oq(index): returns the item at index in the output queue
  • iq_insert(index): appends n to the input_q. This allows us to pre-load user choices in a non-interactive test harness. At this point, n is always going to be a choice index counting from one.
  • num_iq: number of items in the input queue
  • pop_iq: pops off the head of the input queue and returns the item popped







No comments: