Thursday 9 December 2010

Conditional Choices

There are some common idioms in ADV games that I ought to support. One of them is like this:

"You don't like this room. What are you going to do"
1) Sulk
2) Complain

You chose 2) Complain
 "I hate this room!"
 It seems no one is listening.

"You don't like this room. What are you going to do"
1) Sulk
2) Complain

You chose 1) Sulk
You hold your breath until you turn blue.
You are still in the room


"You don't like this room. What are you going to do"
1) Sulk
2) Complain
3) Try The Door


You chose 3) Try The Door
The door opens. You may leave the room.
What we have here a conditional option. Option three doesn't display until one and two have been tried, usually by setting flags in those branches. Despite the frivolous example, there are sensible uses for this approach, like making sure the player has enough background before you advance the plot.

There's also the evolving option. I'll abbreviate this one a bit:
You chose 1) Sulk
You pout. The door remains closed
What are you going to do?


You chose 1) Sulk
You stamp your foot. The door remains closed
What are you going to do?


You chose 1) Sulk
You hold your breath until you turn blue. Mary opens the door.
Mary: "For heaven's sake! I was only gone two minutes."
Here the result of the action depends on how persistent you have been. You could also make it depend on other factors. Like whether the key is in your pocket.

All right, I don't plan on having a lot of find-the-key problems in Clonemaster. The mechanism is the same, however. I need to be able to set conditions on Options.

So the thing to do is to write the test first.

[edit]

So, here it is:

--
-- check conditional options
--
function test_conditional_option()
        local rc
        local scene = [[
        <scene Name="func_s">
         <narrative Name="in_the_room">
          <snippet>
           You don't like it in this room. What do you want to do?
          </snippet>
          <Choice>
           <Option      Text = "Sulk"
                        Next = "sulking"
           />
           <Option      Text = "Complain"
                        Next = "moaning"
           />
           <Option      Text = "Try The Door"
                        Next = "thinking"
           />
          </Choice>
         </narrative>
         <narrative Name="sulking">
          <snippet> You pout </snippet>
          <snippet> The door fails to open </snippet>
          <func>
           userdata.sulked = true
          </func>
          <jump name="in_the_room" />
         </narrative>
        </scene>
        ]]

        local narrator = Narrator:new()
        local stage = TestStage:new()
        narrator:load(scene)
end


TTD test cases are supposed to fail initially, so you can change you code to make them pass. This works nicely, since the XML loader complains that it doesn't know what to do with the "jump" tag. That's not surprising - I hadn't realised I was going to need one

Jump: Narrative item; sibling of Snippet and Choice
  • type: always "jump"
  • target: name of narrative to which the narrator should jump
I'm tempted to add a condition to this so we can jump if the condition is set ... but let's get the condional mechanism working for options first.

No comments: