Let’s take a look at what might be good next steps toward a game. I’d like to get to some code today. A second personality emerges from my mind, the PDP.

Possible Features

I wouldn’t say that we have Arcade graphics totally in hand, but between the code we’ve written here, and my perusal of the documentation and examples, I think we’re in good shape there. There are certainly many graphics stories ahead, of course, unless we really want to play with a dot in a bunch of squares. But there are many other aspects of a dungeon crawling game that we need to consider, including but not limited to …

Border handling.
We have a rudimentary notion of borders, enough to allow us to draw lines where borders exist, and we can tell exterior walls from interior. We still need to figure out doors, locked or unlocked, open or closed, visible or hidden.

Our borders are currently zero width, which will limit what we can display. Commonly in these games, a wall cell takes up a full tile’s space. Given how we create room right now, I don’t see how we could do that without significant changes, since consuming neighboring cells to make a wall could make a passage impassible or cause disconnected rooms.

One idea pops into my mind: what if, as we build our random rooms, we built them of walls, not open cells, and then as cells “inside” arose, we could free them, making them open? Maybe. Seems that could still build big long walls with no open cells by them. Maybe we don’t care?

Another possibility would be to make the room tiles a bit smaller than the space between coordinates, leaving room for thin walls to display in the borders if needed.

Combat
Presumably there will be enemies and monsters in the dungeon. In my iPad dungeon, written some years ago, the player would just attempt to move onto the same tile as a monster, signifying an attack. We could, stick with that kind of scheme, but maybe there should be something better. I really don’t want to do a game controller, however. Certainly possible, just doesn’t seem like fun.
NPCs
There should be non-player characters in the dungeon, with whom one can interact, from whom one can receive quests, or be given hints, and so on. Each NPC would presumably need its own state and memory, so that Old Codger would remember that he had already sent you off to find the Grey Poupon, so that if you still don’t have it, he could remind you forcefully that exploring a dangerous dungeon without decent mustard is simply not done.
Mini-map
We’d like to have a mini-map. I guess the conceit is that the Intrepid Adventurer maintains the map as she travels, so it grows as exploration continues. We may be able to produce this with little more than scaling, but it will require learning some more graphical tricks. See also:
GUI
There are probably some buttons on the screen, and a display of inventory and the like. I don’t think this is likely terribly difficult but we have learning to do and it will take work.
Player and Monster Info
We’ll want to display the Intrepid Adventurer’s health and similar status information, and when a monster appears, it would be nice to pop up a panel showing that it is a Pink Blob with 6 hit points and so on.
Action at a Distance
There is a mysterious lever in this room. If Dot moves the lever, something may happen elsewhere: monsters might be released or caged, traps might be enabled or disabled, and so on.

In my iPad game, I had some kind of publish-subscribe service, where an object could register to be informed about certain messages, and if another object published such a message, all the registrants would be informed via a message call.

It occurs to me that if there were two kinds of levers in the dungeon, they’d need to be distinguished somehow so that the monster release door would only open if the monster release lever was thrown, not if some other lever was thrown.

Placement
There are some dungeon objects that only make sense in certain situations. A spike trap is pretty visible, so there’s not much point in putting one in the middle of a room. A spike trap belongs in a narrow hallway. We’ll want to place such things randomly, but according to some rules. One relatively easy possibility is to require a cell with two borders on opposite sides, i.e. a hallway tile.
Special Rooms
Presently our dungeon is nothing more than a mostly random collection of connected cells. We have the ability to make particular structures, but we also have those very random cave-like rooms, and I do like them. But at present there’s almost no “dungeon semantics”. We do have Rooms, and Rooms can have names, so there is some prospect of doing special things in special rooms.

It goes on and on, doesn’t it? One more “big” topic:

Room and Cell Contents and Status
We’ll need to have some kind of structure that lets us know, when we need to, what is in a cell. Suppose there is a closed chest in a cell. Dot walks onto it to open it. She cannot step on a closed chest, so her move is somehow refused. But the chest is somehow informed to open. If it is a trap, it might stab Dot or poison her. If it has a treasure in it, The cell now contains an open chest and a treasure. If Dot steps there again, she can move onto the cell, and gets the treasure. (We probably have to allow her to step on an open chest, because otherwise a chest in a hallway could block off part of the dungeon.)

Of course, the chest might be a Mimic! Oh no! The chest gets replaced with an angry mimic, which attacks Dot!

All this implies that there is some association between a Cell, which is really just an (x,y) pair, and arbitrary contents. Perhaps this is as easy as a CellContents object of some kind, and a dictionary kind of thing from (x,y) to a CellContents.

No, wait, one more:

Narration
NPCs can talk with Dot. Dot needs to be informed that she has been poisoned by the chest, and probably needs to be told that she has received a Sphere of Profound Roundness. We’ll want some kind of scrolling textual display, I suppose.

Approach

These ideas may only scratch the surface of what we need to do. Whatever we choose to work on, we do not want to go dark for ages while we build up a Publish-Subscribe Facility or a Universal Contents Scheme. We want to show progress, if not every day, then at least every couple of days.

We’ve spent a lot of time with the dungeon layout, but we were at least able to show interesting maps. But if I were working for a living, building dungeon software, I think that management would be getting impatient, wanting to see something that looks more like a game.

Aside
Kent Beck once said—I’m pretty sure it was Kent—that all methodologies are based on fear, the feat that most drives that method’s creator. My biggest fear in software development is that we’ll be doing really good work but that management will not see it, will not be able to appreciate it, and they’ll cancel the project out of impatience.

I fear that because it has happened to me, more than once. Sometimes the cancellation was somewhat justified, sometimes not so much. Either way, if we had been producing visible results, management would have better understood what was going on and could have made better decisions.

So I want to work, as we go forward, so as to provide visible results as soon and as often as possible. The results may not be graphically good, unless that’s what we set out to do, but they’ll be visible enough to show that progress is being made. Or … it could happen … to reveal that progress is not good.

Next Feature

Let’s do a treasure in the dungeon. It will be visible in some easy way. When Dot steps on its tile, the treasure will no longer be visible (even when she steps away) and a message will appear in the console telling us that Dot has the treasure.

Let’s see what some of the steps might be here.

We’ll need a cell-to-contents structure, part of the Dungeon or Layout. Probably Dungeon. We’ll need a Treasure object. We’ll put it very near where we are going to put Dot. We’ll have to give it a display of some kind.

Let’s look around, see what we have that might be useful. In main:

main.py
def main():
    ...
    layout.make_borders()
    dungeon = Dungeon(layout)
    dungeon.populate()
    target = Cell(32, 28)
    options = layout.furthest_cells(target)
    chosen_cell = random.choice(options)
    dungeon.place_player_at(target)
    window = arcade.Window(screen_width, screen_height, 'Caveat Emptor')
    view = DungeonView(dungeon)
    view.setup()
    window.show_view(view)
    arcade.run()

I see dungeon.populate there. Does that do anything? Ah, yes, but we undo it in main.

class Dungeon:
    def populate(self):
        dot_room = random.choice(self.rooms)
        dot_cell = random.choice(dot_room.cells)
        self.place_player_at(dot_cell)

Right. I think we’ll do our setup in main for a while. I’m not sure quite how Dungeon.populate might work.

Let’s do an obvious and obviously wrong thing:

    target = Cell(32, 28)
    dungeon.place_player_at(target)
    treasure_target = Cell(29 , 28)
    dungeon.place_content_at(treasure_target, 'treasure')
    window = arcade.Window(screen_width, screen_height, 'Caveat Emptor')
    view = DungeonView(dungeon)
    view.setup()
    window.show_view(view)
    arcade.run()

I was going to call place_treasure_at but place_content_at might even be close to the right idea.

We have no such method. I think we should TDD this. We have a test_dungeon file, I’ll add tests there:

    def test_place_content(self):
        layout = DungeonLayout(10, 10)
        room_cell = layout.at(5, 5)
        room = Room([room_cell])
        layout.add_room(room)
        dungeon = Dungeon(layout)
        dungeon.place_content_at(room_cell,"treasure")

This is enough to fail. Code the method:

class Dungeon:
    def __init__(self, layout):
        self.layout = layout
        self.player_cell = None
        self.contents= {}

    def place_content_at(self, cell, content):
        self.contents[cell.xy] = content

The test is passing. We’ll want to display something when we display that cell. Let’s review how we draw the cells.

class DungeonView:
    def on_draw(self):
        draw_start_time = timeit.default_timer()
        self.clear()
        cx, cy = self.dungeon.player_cell.xy
        self.camera.position = (cx*cell_size, cy*cell_size)
        # Constrain the camera's position to the camera bounds.
        self.camera.view_data.position = arcade.camera.grips.constrain_xy(
            self.camera.view_data, self.camera_bounds
        )
        with self.camera.activate():
            self.shape_list.draw()
            self.draw_contents()

    def draw_contents(self):
        adventurer_cell = self.dungeon.player_cell
        cx = adventurer_cell.x*cell_size + cell_size//2
        cy = adventurer_cell.y*cell_size + cell_size//2
        arcade.draw_circle_filled(cx, cy, cell_size//2, arcade.color.RED)

Well, that’s nearly useful. Let’s try this:

    def draw_contents(self):
        adventurer_cell = self.dungeon.player_cell
        cx = adventurer_cell.x*cell_size + cell_size//2
        cy = adventurer_cell.y*cell_size + cell_size//2
        arcade.draw_circle_filled(cx, cy, cell_size//2, arcade.color.RED)
        for k, v in self.dungeon.contents.items():
            x,y = k
            cx = x*cell_size + cell_size//2
            cy = y*cell_size + cell_size//2
            arcade.d.draw_circle_filled(cx, cy, cell_size//2, arcade.color.GREEN)

With any luck that’ll draw the Big Round Green Treasure off to the left a few squares from Dot:

big round green treasure a few spaces left from Dot

Perfect! Ship it! Commit: Content items in dungeon draw as green dot.

Call it a morning.

Product Conversation

We can imagine a conversation with our Product Definition Personality:

Ron
So. We have rudimentary content in the system. There’s only one kind of content right now, and it displays as a green dot. We can have as many content items as we want.
PDP
Can there be more than one content per tile? We’ll need that.
Ron
Not yet, but we can readily do it: we’ll just save a collection of content items rather than just one, in each cell that has content.
PDP
What about different kinds of content?
Ron
Currently content is present or absent. We’ll need to define a content class of some kind for each kind of content you want. Each one will have its own properties, and we’ll need to devise some way to give each one its unique display, probably a monster or treasure picture.
PDP
Are monsters just content?
Ron
I’m not sure. Probably not, now that I think of it. Monsters move around, and content, is probably more static. We’ll probably want a different collection for monsters and NPCs.
PDP
Are monsters NPCs?
Ron
Hadn’t though of it until just now, but probably a monster is a relatively simple NPC. Maybe separate, maybe not. Depends on things we haven’t done yet.
PDP
What’s next with this?
Ron
A fair number of things. We’ll want some priority guidance, what you’d like to see next, but we’ll want to have at least two treasure types, with two separate styles of picture. We should make the cell contents a collection, not just a single item.

We’ll need to give Dot an inventory of some kind, and when she steps on a content item, which right now is only some kind of treasure, we need to put it into her inventory and remove it from the dungeon.

And a thing that we have not addressed at all is how to specify what content items exist, and how to allocate them into the dungeon. There might be items that only show up in certain levels and so on. We haven’t talked much at all about dungeon design.

PDP
Yes, that’s a big deal if we try to generalize it. For now, we’ll program up the dungeons we want to play with and maybe tune the randomness for different levels. I’m not sure if we want a real dungeon definition system or not.

For now, I guess I’d like to see her take it, and to get some indication that she has it. Then I’d like to see more than one kind of treasure, at least a different color. We can hold off on pictures unless you need to sort it out earlier.

Ron
OK, I’ll work on giving her this one, then on having more than one. Somewhere in there I’ll go from one item per cell to allow more than one. Not sure what I’ll display in that case, maybe just one of them, or perhaps a number if there’s more than one thing?
PDP
Sure. The sort of thing longer term might be to display an open chest and a potion on top of it or something like that. Don’t want too look to work on display, but I can wait a while for the fancy stuff.

Summary

When we have something to show that our management, product definers, friends, whoever can see, we can have sensible conversations, based in the current reality. We can still be uncertain about things. We want to be clear about what is working and what is not.

With visible progress every time we talk with others, we’re all standing on much more certain ground. In some cases we’ll need to be careful not to give people the impression that we’re more done than we are, because another of my fears is that they’ll suppose that because it looks good, it’s nearly ready to ship. That’s one advantage to the simple graphics we have here: no one is likely to think we’re done.

From a design viewpoint, I do have over six decades of experience, so I am fully aware that a single item indexed by (x,y) isn’t a robust contents solution. But it is standing in roughly the right place. It should be easy enough to switch to a collection instead of one item per (x,y). Similarly, we can surely put objects under the (x,y) instead of a string, and we can define messages that ContentItems must understand, for display and other purposes.

We’ll evolve those in over the next few days, I imagine.

The point, and I do have one, is that a very small change can help us determine how we will do some feature, and with a bit of care, it can be shown to our PDP, and used to help us communicate.

Small steps. Darn, they’re nice!