Showing posts with label software. Show all posts
Showing posts with label software. Show all posts

Saturday, February 28, 2009

What to do when you don't know what to do

The last story that I was working on required me to do some animation in Java3D, which I didn't how to do. So, I did a little Spike to learn a bit more about what was involved with that, and I finally finished up the story. With this on my mind, I thought I would spend some time talking about Spikes.

I think Spikes are one of the most misused parts of Agile. The general understanding of a Spike is that it is a research story. If you have questions about how to do your User Story, you spend time researching or spiking the questions that you have. I've seen different teams handle Spikes in different ways. The worst I have witnessed are spike stories that drag on from iteration to iteration. After a time, when something is finally delivered, it's not in a state that is usable, but too much time has been spent on it, so it winds up being put into the code base with no tests, no pair programing, etc. The best use of a Spike is to only use it when you don't know enough to estimate the story, then you spike until you know just enough to do the story. Any code that you write to answer those questions are considered "spike code" and you throw it out.

One really good practice to get into to avoid spike abuse is to always have your Spikes be time-boxed. You set a limit on the amount of time you will spend researching. Once that limit has been reached, the team can then review whether or not they need more time or need to possibly take a different route. If you can't learn enough within a day or so, to estimate, you really should reevaluate if that technology is worth the time. If an off the shelf product takes a week's worth of time to "spike" so that you know how to use it, maybe a simpler approach that doesn't involve that product is the better approach.

I've worked with some people that use the term "Spike" to justify taking a long time to writing crumby code that is meant to be used as a prototype. Truth is, that when they finally get to the point that they can write that code, they know enough to estimate the actual story and then begin working on it. Time spent on a spike after you have answered your question is no longer time that should be spent on spiking, but time spent working on the story.

I've also heard the phrase "architectural spike," which boils down to taking entirely too much time to write up a document to give to the team (that they'll probably never read) describing the solution with many charts and diagrams. And to me, that just goes against the concept of letting your tests drive your code and letting the design emerge from your refactoring.

So to recap, spikes are suppose to be a time-boxed (maybe a day) research efforts that answer enough questions so that you can estimate a story. Anything else, should be your standard test driven development based on satisfying acceptance criteria on your user stories.

Saturday, February 21, 2009

Alright, so I blew through the first two stores that I was attempting:

1. User opens the application and sees the game board. Game board is a chess board (8 x 8 - alternating black and white squares) background is a gray. Camera is looking at the center from above and toward one side.

2. The user has one piece (a blue ball) on the board that is located on one side of the board on one of the center squares.

And up until now there was really no design to it. I started coding a class that had the capability of drawing on the 3D canvas and just kept going. Neither of these stories contain any user interaction yet so I was having a hard time coming up with testable code.

I eventually saw that there was a bit of logic needed for creating the checkered game board. So I thought I'd extract out something that would need to know how to do that. So I started going into an MVP pattern. I wanted the view to get something that it could use to create the proper rows and columns with the right alternating colors without too much logic. It wound up looking like this:

public void constructGrid(GameGridData data) {
for (int x = 0; x < data.getTileData().length; x++) {
for (int z = 0; z < data.getTileData()[0].length; z++) {
Tile tile = new Tile(data.getTileData()[x][z]);
board.addChild(tile);
}
}
}

The Tile class was an abstraction I had done to encapsulate the creation of the geometry and details of creating the individual squares. The TileData is a bean that I had to construct to keep the back-end models from knowing anything about the Java3D APIs. The GameGridData has the algorithm needed to get all the positions and colors in the right data structure (the TileData bean) that the view needed. I have a feeling that GameGridData may morph into an abstract class where subclasses will be specific for Chess boards or terrain looking grids or vast spans of black space. Once that was all pulled apart, I was able to construct a Model that generated these TileData beans and a Presenter that could communicate between the two.

Now what I have is a bunch of smaller classes that don't contain "view code" all of which are very testable! So that's where the first real signs of a design started to form. I had a need to be able to test what I was doing and no real good way of isolating the code that needed testing. So by separating out what was just calls to the framework's API (or my abstractions around the framework) and the logic needed for the correct calls, I was able to write a few tests and get things a bit more agile.

The third story actually got me into some user interaction:

3. The user can select a square on the board and the ball will move to that square. Movement is shown and not just a sudden change in location.

Selecting an object in Java3D is a bit more complicated than in Swing. Picking an object is basically translating a point that your mouse picked on the screen to a ray or cone that extends from the point down into the canvas and then seeing what objects intersect with that ray or cone. So my abstractions around the actual tiles in the grid by my Tile class paid off when I found out that the API will return the Node or Shape3D object that was in the intersection path. So I was able to retrieve the same TileData bean that I used to create the selected Tile object and then notify the presenters that are listening to the view.

And this is what it wound up looking like:

final PickCanvas pickCanvas = new PickCanvas(canvas3D, board);
pickCanvas.setMode(PickInfo.PICK_GEOMETRY);
pickCanvas.setTolerance(4.0f);

canvas3D.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent mouseEvent) {
pickCanvas.setShapeLocation(mouseEvent);
PickInfo pickClosest = pickCanvas.pickClosest();
if (pickClosest != null) {
Tile tile = (Tile) pickClosest.getNode();
selectedTile = tile.getTileData();
tileSelectedListeners.notifyListeners();
}
}
});


So then I needed a way to move the user's game piece once the position selection took place. I made some similar refactorings to the code that created the user's piece with a MVP pattern. And then I let the model from the game grid and the model from the user piece be able to communicate with each other. And then the piece model notified it's presenter which in turn told the view to move the piece to the correct location.

public UserPieceModel(final IGameGridModel gameGridModel) {
gameGridModel.addPositionSelectedListener(new IListener() {
public void fireEvent() {
currentPosition = gameGridModel.getSelectedPosition();
adjustCurrentPositionForHeight();
modelListenerManager.notifyListeners();
}
});
}


So this story is just about wrapped up. I currently just have the user's piece suddenly jumping to the new location but the story has some more specific requirements: "Movement is shown and not just a sudden change in location" I made it that way intentionally because I know nothing of Java3D's animation APIs. So now I'm just doing a quick spike to determine how to do that and then I'll be able to finish this story up and move on to the next.

So overall I think things are progressing nicely. I wasn't liking where this was going at first with a whole bunch of un-testable UI code but now it seems like I've got the start of a design that allows me to test what I'm creating. And really that's the point of this blog. I called it Emergent Development because that's what good software development should be. You start going and you realize you need something so that you can make it more testable, more loosely coupled, more flexible and so you interject a pattern or two so you can test your stuff and just keep going. So your design comes from need not from a over thought-out UML diagram that was created long before any real code started. Design comes as you need it, no sooner.

Saturday, February 7, 2009

Starting to blog...

So I've been told that blogs are good to get your ideas down and let others comment and possibly help you out occasionally. So here's my go at it. I'm a software engineer by trade and by hobby. I've been indoctrinated into the Agile software methodologies and I'm starting to put them into practice, not just at work where we're required to, but at home in my little side projects.

So I also have a hobby of videogaming and that tends to creep its way into my hobby of writing software. I've had grand schemes of writing the most amazing game that's interesting, replayable, exensible and just generally really fun. So I've had several failed attempts and I keep them all in my local SVN repo and occassionally dig them out and remember why I stopped that approach.

I think the reason why I fail most often in my attempts is that I try to do too much. In Agile terms, my stories are entirely too big. So I've decided that I need a backlog of stories that I can massage down to what would be doable and then focus on each one and get a sence of accomplishment and direction of where I'm going next. I've also decided to scale down the scope of my game. For the moment, it will involve moving pieces around a board and possibly taking your opponents pieces. Sounds very checkeredy but I figure that if I can start there, I can build uppon it. Maybe make it multiplayer, then make it networkable, then be able to load in different pieces, then make the board changeable. Then maybe I can pull out a framework that would allow me to create great extensible game that I know everyone will love and want to play! ... maybe...

Ok, first things first. Gotta get a backlog to work with. In order to do that, I need a good game concept. So that will be this weeks task. Some sort of game concept and the beginning of a backlog. And next week I'll plan on doing a release planning and start in on the fun.