Monday, 31 January 2011

Loading issues fixed

well, so far as loading chapter headings and background images goes, anyway. Still a lot of cases need adding.

Next I want to do the shuffle code. there's two parts to this: shuffling the narratives in a scene (or items in a narrative, or options in a choice, etc, etc, etc) and then there's re-arranging the treeview to reflect the change.

Let's get test cases for the Scene, Narrative and the rest, first.

Saturday, 29 January 2011

A Test Case

SceneEdit, Boo. Test Case. Why isn't the image tag loading from XML?

        [Test]
        def load_background2():
                source = detab("""
                <scene name="GameStart" default="" desc="wibble wibble">
                 <narrative name="waking_up" desc="In which our hero ...">
                  <image path="data/images/foo.png" />
                  <image path="data/images/bar.png" />
                 </narrative>
                </scene>
                """)

                sr = StringReader(source)
                r = XmlReader.Create(sr)
                scene = Scene()
                scene.load(r)
/*
 *              make sure we have a narrative
 */
                Assert.AreEqual(1, scene.narratives.Count)
/*
 *              get the narrative, check the name
 */
                n as Narrative
                n = scene.narratives[0]
                Assert.AreEqual("waking_up", n.name)
/*
 *              now - it should have two narrative items attached
 */
                Assert.AreEqual(2, n.items.Count)


And that fails: there are zero items in the narrative. Also of interest is an error message in the test output saying "name image not handled". I missed that in the general output chatter when running the app itself.

A bit of grepping tracks that down to the Narrative class:

        def load(r as XmlReader):
                _name = gatt(r, "name")
                _desc = gatt(r, "desc")

                while r.Read():
                        if r.NodeType == XmlNodeType.Whitespace:
                                continue
                        if r.NodeType == XmlNodeType.EndElement:
                                if r.Name == "narrative":
                                        break
                                continue
                        if r.NodeType != XmlNodeType.Element:
                                print "unexpected node type: ${r.NodeType}"
                                break
                        if r.Name == "narrative":
                                break
                        if r.Name == "snippet":
                                sn = Snippet()
                                sn.load(r)
                                _items.Add(sn)
                                continue
                        print "name ${r.Name} not handled"


So I need to add a case to that loop for every tag I intend to read. Tedious, but at least I found it.

Incidentally, that's lousy O-O methodology. One of the basic ideas behind OO is that you have subclasses so you don't need to have ifs or switches like this. The trouble is that this kind of breaks down when you're reading text data.

The OO way to do it would be to have a factory method, typed as NarrativeItem that took the class name as a string and returned the appropriate item. You'd have a reader class specific to each tag and register them with the factory so it knew what objects mapped to what strings.

Really though, life's too short. Getting all that working and debugged is a task in its own right, and for something as minor as this, it just isn't worth it.

Of course, all that may change as the code evolves. For now though, we'll go with the old-fashioned approach.

Friday, 28 January 2011

Shuffling Along

OK, time to look at the shuffle problem. First of all the verb needs to change to "move", if only on the buttons. "Shuffle" takes up too much space. (That said, I'm going to need another row of buttons before I'm done, but that for later).

The thing that stops this being trivial is that we need to be able to shuffle anything from menu choices to narratives.

I think I need some more test cases...

Thursday, 27 January 2011

Shallow Bugs and Whoremaster

Well, there are that many bugs in this editing tool, if I hadn't doucmented the test suite as I went, I'd wonder if I ever tested it.

The thing is, short of some complicated and expensive software, there isn't a good way to repeatably test GUIs. (OK, it should be possible to do some tricks with NUnit and reflection, but I've never quite got that to work in practice).

Anyway, the theory is to put the application logic into a dll and test the hell out of that. The GUI code is to be as thin a wrapper around the dll as possible. But the GUI still needs testing - which is what I'm belatedly doing now, I suppose.

On the bright side, the bugs have generally been pretty superficial - which should be one payoff of the TDD phase. There shouldn't be any deep errors in the application logic, because I have tested the hell out of that.

On another note, I'm quite enjoying playing Whoremaster again. One of the drawbacks of developing a game is that somehow you never get to play it. You make changes and you test them, but somehow you stop playing for fun. Having had a break from the dev process, I'm starting to enjoy the game, and in doing so I#m starting to think about what I'd like to do to the source code.

I'm not about to break my sabbatical just yet but ... I'm starting to look forward to doing some work on the program again.

First Or Second Person

I keep alternating between wanting to write scenes in first and second person. So I thought I'd throw the question to the audience, as it were, and see what people think.

Both styles can be effective. The old Infocom style text adventures generally used second person narratives:
You are in a round room.

> PISS IN THE CORNER

Sorry, I don't understand "corner".

You are in a round room.

And that generally worked. The style was very much based on the pencil-and-paper role-playing games of the time, but you can tell a tale and get the player to identify with the protagonist. Of course you probably need to be a bit careful what words you put in the player's mouth, (and what thoughts you put in the players head!). Even then, games like Curses and Trinity play from the perspective of someone who definitely is not the player, and they still work very well.

Japanese style ADV games on the other hand tend to use first person, at least from the examples I can bring to mind. The dialog tends to be stream of consciousness from the MQ.

This is a very strange room I find myself in. It appears to be completely round.


It's all a bit confusing to me. They told me to take a piss in the corner, but there are no corners to piss in.


Maybe I could do it in the middle and claim the piss drained there. Maybe that would work. Or maybe they would see through my ruse and be angry with me.


It is a conundrum.
I think this possibly works better for ADV text. Second person seems a bit like constantly telling the player what to do. It's all right for descriptive text, as in Zork you have to say what happens to the player as the result of his choices. But then you get a lot more choice per text passage in Zork than you do in any ADV game.

Anyway, opinions anyone?

For example...

If there's no configuration set up, SceneEdit doesn't always default to the current folder. (actually, it should probably default to the one above on the assumption that it's been called from the tools sub folder.

If you edit the path and change it, the change is not reflected in the textbox

You can click +Narrative from the initial config screen and crash the tool - because the scene isn't set up as yet.

Dogfood, I tell you.

[edit]

Fixed them. Started a new scene, called it "waking up" hit tab ... and it crashed. This may take longer than I'd anticipated.

I think I'll just edit this post rather than spread the debug process over umpteen posts.

[edit]

Too many to log, all fairly simple. One that might take a bit more work: TreeView nodes aren't being set quite right. There's a nasty disorienting jump. Probably the result of a ham-handed fix to an earlier crash problem. (Scene needs to be a NarrativeItem - and I suspect Narrative will also need that distinction).

[edit]

No crash on narratives, but browsing for images doesn't use the game Resource folder as its root - which is the point of the config entry...

... the file browser doesn't do thumbnails for images - have to check the docs for that - I might be using it wrong ...

... and when I do find the image I need, the label in tree view is wrong...

[edit]

Save dialog uses the last image folder as default, which is wrong. Can fix that with two save dialog objects, perhaps. Seems wasteful, but should work.

On the bright side, it seems to be getting usable pretty quickly. There's hope yet :)

[edit]

Never did get around to making the shuffle buttons work...

[edit]

images and chapter headings don't appear to load. They save ok, but they don't appear in the loaded treeview. Let's review those test cases.

Also, specifying the XML file on the command line doesn't work

Wednesday, 26 January 2011

Time To Eat Dogfood

If you're familiar with the idea of the "dogfood test", the title will make sense. If not it probably sounds a bit weird.

In software, the dogfood test is "does the developer use his own tools and/or products?" If a maker of dogfood thinks their product really is healthy, they'll be quite happy to eat it themselves. If not, you're entitled to ask "so what's wrong with it?" Similarly, you should expect a software house to use its own tools.

Which is a pain right now, because I need to convert all the text so far. I've got this neat GUI tool to do that (and spent way to long writing it) but what I really want to do is fire up vi and hand edit the XML.

The thing about that is ... you can always tell when a developer doesn't use his own tools. If you use a program, you tend to find and fix the problems as they occur. Eventually it gets to be more than just functional. It gets to be smooth. If you don't use it, then you tend to leave the rough edges in place.

So, if I want other people to use SceneEdit, I guess I better use it myself.

I expect there are dog food manufacturers who don't much care for the taste of dog food, come to think of it.