I've been trying to write a decent introduction to user stories, and it hasn't been working. Instead I'll just summarise them as follows:
* User stories describe what the software should do.
* User stories are written from a user's point of view.
* User stories are often used in agile software development (see e.g. here or here).
Here are 3 user stories for Ighalsk.
User Story A.
Tom feels the need for more, bigger and better monsters. He fires up the Ighalsk Monster Editor and creates a Plaid Dragon and a Blue Orc (starting from existing monsters and modifying stats appropriately). He tries them out and decides that yes, they add something to the game. Maybe Melissa would like them? He knows that she's already got the other monsters that he's created, so he just exports these two using the Monster Editor to a separate text file and emails it to her.
Melissa (a friend of Tom's and a fellow Ighalsk player) reads the email, saves the file, and imports the monsters - again using the Monster Editor. Next time she plays Ighalsk, Plaid Dragons and Blue Orcs might be lurking in one of the dungeons ...
User Story B
The Ighalsk website includes a page for uploading and downloading monsters. Each monster has a summary, a description written by its creator, and reviews posted by others. The Ighalsk community votes regularly on which monsters should be included in the next release, or the next bonus pack of monsters (downloadable separately).
User Story C
Cass stares blankly at the screen. YASD - those stupid Plaid Dragons of Tom's! Ah well, they're not official - she'll remove them before she plays again. Now, what sort of Hero to play this time? How about a Mighty Hero for a change? The good thing about starting a new game, she thinks, is that all Heroes have plenty of powers right from the start, which gives them lots of options in dealing with monsters. Though they can still die if they make the wrong choices ... And each sort of Hero calls for a completely different playing style, and a different choice of quests.
Showing posts with label agile. Show all posts
Showing posts with label agile. Show all posts
Wednesday, January 13, 2010
Monday, November 30, 2009
Ighalsk - Tests and Time
At a recent checkin, there were 486 tests defined for Ighalsk, which took 31.8 seconds to run (on my old laptop: 500 MHz, Win98). I'm happy with the number of tests, but would like to decrease the time somewhat (still too many file accesses).
A Google spreadsheet showing some numbers and times for different revisions is available here. I don't know why the time went down to 9 seconds and back up again almost immediately, but I think the dip from 23.3 seconds to 20.9 seconds was just after some test refactoring to speed up tests - probably replacing file I/O with StringIO (see previous post).
Also, I now have a Twitter account here - any updates to these numbers/this spreadsheet will probably be posted on Twitter first (and possibly only). I'm working on increasing the popularity of #roguelike ...
A Google spreadsheet showing some numbers and times for different revisions is available here. I don't know why the time went down to 9 seconds and back up again almost immediately, but I think the dip from 23.3 seconds to 20.9 seconds was just after some test refactoring to speed up tests - probably replacing file I/O with StringIO (see previous post).
Also, I now have a Twitter account here - any updates to these numbers/this spreadsheet will probably be posted on Twitter first (and possibly only). I'm working on increasing the popularity of #roguelike ...
Thursday, November 26, 2009
Ighalsk and Motivation
Ighalsk is not the first software project that I've worked on at home, or even the first game. But it is easily the most mature and furthest along. With earlier projects, I've had a great idea, started working on it, got a few things done, and then my enthusiasm has slowly worn off and I've given up.
With all my projects, I've only had an hour or two to spend on them in a night, and some nights that dropped to zero. Often in this time I'd get started on a task, but wouldn't have time to finish it - I might find a bug, or the task might be more complex than I'd planned for. Then I'd need to wait a day or more before I could work on it again. This was frustrating, and it made me feel like I was going very slowly.
With Ighalsk, I've generally been able to get something finished each night. Part of the reason is that I'm using Test-Driven Development (TDD) almost all the time. This means that my work cycle is usually: write a new test, run it to check that it fails, write just enough code for it to pass, check the changes in. A lot of the comments that I make when I check in changes start with "Added test + implementation of ..." Similarly when I refactor, each refactoring is small and I test it before I go further, so that when I do make a mistake, I can go back and fix it easily. It helps that the full set of tests runs in less than a minute (though I still want to speed them up further over time).
TDD has meant less bugs - or more to the point, that it's quicker and easier to fix bugs - and frequent refactoring (not to mention using Python!) has meant simpler code. Both of these factors have also helped me finish tasks more quickly and feel like I'm making progress.
Motivation has been less of a problem lately; I've got to the point that I have a playable game, where it's easy to see how any new functionality can fit in and will be usable immediately.
Doubtless it's also helped that I don't have any new games that I want to play at the moment - though often ProgressQuest is running in the background while I work on Ighalsk, and I've started playing FreeCol years and years after I last played Colonization ...
With all my projects, I've only had an hour or two to spend on them in a night, and some nights that dropped to zero. Often in this time I'd get started on a task, but wouldn't have time to finish it - I might find a bug, or the task might be more complex than I'd planned for. Then I'd need to wait a day or more before I could work on it again. This was frustrating, and it made me feel like I was going very slowly.
With Ighalsk, I've generally been able to get something finished each night. Part of the reason is that I'm using Test-Driven Development (TDD) almost all the time. This means that my work cycle is usually: write a new test, run it to check that it fails, write just enough code for it to pass, check the changes in. A lot of the comments that I make when I check in changes start with "Added test + implementation of ..." Similarly when I refactor, each refactoring is small and I test it before I go further, so that when I do make a mistake, I can go back and fix it easily. It helps that the full set of tests runs in less than a minute (though I still want to speed them up further over time).
TDD has meant less bugs - or more to the point, that it's quicker and easier to fix bugs - and frequent refactoring (not to mention using Python!) has meant simpler code. Both of these factors have also helped me finish tasks more quickly and feel like I'm making progress.
Motivation has been less of a problem lately; I've got to the point that I have a playable game, where it's easy to see how any new functionality can fit in and will be usable immediately.
Doubtless it's also helped that I don't have any new games that I want to play at the moment - though often ProgressQuest is running in the background while I work on Ighalsk, and I've started playing FreeCol years and years after I last played Colonization ...
Tuesday, July 7, 2009
Ighalsk - in which I discover StringIO
The suite of unit (more or less) tests that I run for Ighalsk currently takes about 11 seconds to run 281 tests (for the current version with Subversion revision number 58). This is not too bad, but I've read about projects running more than 1000 tests in less than 10 seconds, perhaps even less than 1 second. In particular, the suggestion is to avoid file accesses in unit tests (see for example Michael Feathers here).
When using Java, I think the idea is to accept an abstract Reader object as a parameter, which can be a FileReader object in the actual program, and can be mocked as a StringReader (or is it ByteArrayInputStream? so many choices!) in test code for speed. (On checking, I found that the example I was thinking of is actually for .NET ...)
I was planning to implement my own FileReader and StringReader objects in Python, but then I'd have to unit test those as well ... when, reading through the Python manual, I discovered a class called StringIO!
Its description begins, "This module implements a file-like class, StringIO, that reads and writes a string buffer (also known as memory files). See the description of file objects for operations ..." - which is exactly what I wanted!
I've started using this approach (mocking file objects using StringIO) in new classes, but I still need to switch to it for existing classes. In most cases, it should be a matter of opening a file and passing in the file object before calling a function instead of passing in a filename and opening the file inside the function, though this still means that there'll be at least one class somewhere that will still have to open some files ... but separating out this functionality should mean that file I/O only needs to happen in a small number of unit tests. Yet another treasure hidden away in the depths of the standard Python libraries!
When using Java, I think the idea is to accept an abstract Reader object as a parameter, which can be a FileReader object in the actual program, and can be mocked as a StringReader (or is it ByteArrayInputStream? so many choices!) in test code for speed. (On checking, I found that the example I was thinking of is actually for .NET ...)
I was planning to implement my own FileReader and StringReader objects in Python, but then I'd have to unit test those as well ... when, reading through the Python manual, I discovered a class called StringIO!
Its description begins, "This module implements a file-like class, StringIO, that reads and writes a string buffer (also known as memory files). See the description of file objects for operations ..." - which is exactly what I wanted!
I've started using this approach (mocking file objects using StringIO) in new classes, but I still need to switch to it for existing classes. In most cases, it should be a matter of opening a file and passing in the file object before calling a function instead of passing in a filename and opening the file inside the function, though this still means that there'll be at least one class somewhere that will still have to open some files ... but separating out this functionality should mean that file I/O only needs to happen in a small number of unit tests. Yet another treasure hidden away in the depths of the standard Python libraries!
Subscribe to:
Posts (Atom)