Home > aen's Blog

Multiple Layers, Part 2

smee, build 14

This build allows plotting to the currently selected layer.

There is also a new menu item under View for switching between Fast and Accurate repainting, with accuracy being the default. Since I couldn't figure out quickly how to fix the fast version, I made it user selectable! It works well on maps that do not use tiles larger than the grid size, and oddly also on isometric views. But no love for your standard tile maps with large tiles. I'll figure it out eventually!

Hit A to add a layer, same as yesterday. Here are some snaps of layers in different orders:

In the last one, I made the full outline of the tree tile transparent, and moved all the trees above the bottom layer. Combine that with multiple layer support, and trees can sit all pretty like on the grass, the stone, you name it. You can see some flowers poking out from under the edge of one tree, even.

Yes, I know. It's like we've all warped thousands of years into the future. And how magnificent that future is.

The modifications were fairly straightforward. In the MapLayerManager, I installed a ListSelectionListener on the JList which contains the layer names. When the selection changes, I set the current editable layer to match.

Framework Composition

It wasn't immediately clear where would be the proper location to keep track of the current layer for editing, so I put it in MapPanel since it was fairly convenient. It did not belong in the Map class itself, because an editing state is not intrinsic to maps, but to the tools for editing maps.

Thinking about it now, perhaps the best location is directly in Main. MapViewport doesn't feel quite right since conceptually it's supposed to be dealing with movement around the map. And technically, there are probably several things in MapPanel which don't belong.

In the end, there are ultimately many little nitpicks like this that you end up dealing with when creating software of any complexity. And sometimes there isn't always a clear line of reasoning to back up where you put things. Nor does it often matter! But it's worthwhile to try and be as consistent and logical as you can. And failing that, ask somebody else! Which I'll do now:

Where do you think would be the proper home for data which tracks the currently editable layer? Better yet, to the several people I know who have written map editors: Where did you put this information?

Subsystem Interaction

Another thing you start to run into when you've added many different features to a piece of software, is conflicts or odd behavior between various subsystems after adding a new feature. This can be an increasingly difficult obstacle to overcome if you don't have a copious amount of experience resolving conflicts. I suspect this is one area where unit testing can truly shine.

In my case, when I added plotting to multiple layers, I forgot about the undo functionality! So, as I merrily created a second layer and plotted some trees on it, then hit undo, I was at first confused to see all of the tiles from the bottom layer disappear, leaving my trees sprouting out of the gray void!

The problem was, of course, that I had rigged the undo system to deal only with the very first layer. It was a fairly easy catch, but I wonder if unit testing could have somehow alerted me to this omission even earlier.

Test Driven Development

Were I writing tests before implementing, ala test driven development, I would probably have composed a test for the undo system which verified that, upon doing and undoing an action, the correct tile on the correct layer was modified and reverted.

This is a fairly good argument for test driven development, I think. Creating tests after the fact, as I have been with Mu and in a very limited fashion for SMEE, acknowledges the need for testing, but doesn't give it the proper level of importance. You kind of patch things up after the fact, if you happen to notice something wrong. This is obviously necessary, even if you do write tests first, but it is only part of the equation.

What I think the point must be in writing tests first is to proactively have you thinking about how all of the systems in your software will be interacting with each other. Were I writing tests first, I would have undoubtedly thought of how each new feature might impact all of the current systems in place, and realized the potential for undo misbehavior with multiple layers much sooner.

Luckily, I've not encountered any devastatingly obscure bugs yet, but as with the other tiny little issues that I've mentioned over the course of this blog, I continue to see how you can head off any trouble before it becomes Big Trouble with test driven development. Some time soon I think a critical mass may be reached, in which I can no longer be happy without writing tests first!

Tile Management

I think it's high time focus started shifting towards tile management! Ripping tiles, arranging them, plotting them... these must all be comfy and easy to wear!

How else can a map editor have any respect for itself in the morning, really? Tiles... tiles everywhere! Plotted all night long... over and over and over... and then what! On to the next map editor, without so much as a courtesy plot? What a callous, lonesome world to live in. And cold... SO VERY, VERY COLD!

...oh yeah, I live in Minnesota.