Tuesday, April 30, 2013

You have survived... for now.



The "One Game a Month" challenge permits a little bit of slack at the end of the month to polish things up. I'm going to avail myself of that leeway - I've written all the story that I'm going to write, and I intend to revisit the code I wrote to turn the Twine file into an EPUB file to make it a little bit more presentable.

I'm not especially proud of the writing; towards the end, I was definitely just getting stuff down to wrap things up.

  • page count:  38
  • ending count:  12
  • dangle count:  0
  • word count:  3642
Interesting that I got to around a 33% ending/page ratio, which is pretty consistent with the CYOA books that I had looked at.

One thing that I gained from this particular experiment was the appreciation for people who can tell a good story. In this project, I struggled to tell a branching narrative of some twelve (or more?) interlocking tales. Perhaps I could have pulled it off if I had focused on it more consistently, but I knew that April was going to be a rough month to find time to work on this project anyway.

I'll be uploading the Twine source code, which feels like a technical completion of the challenge, and then I'll polish it a little bit more and upload the EPUB in a few days.

Saturday, April 27, 2013

You can almost see the end of the month...

I've been dragging my feet on my branching path story "game" for April. Here it is, almost the end of the month; I really need to get some more written, and actually format it into a completed document.


So far, I have:

  • 29 pages
  • 4 endings
  • 318 lines of text
  • 7 dangling links
  • 2261 words
I'm really not going for quality at this point, just trying to get the storylines to have endings. Not good endings or bad endings, or even good writing - I'm just trying to wrap up the stories.

Most of the endings are bad endings (though coming up with distinct ways for the reader to die has been a challenge). One of the good endings is almost a trap; you get into exploring a wrecked ship, and nothing you can do can help but get you rescued. Aesthetically, I don't care for that so much; if the player is given a choice, there ought to be a difference between the outcomes. Getting rescued one way versus being rescued a different way isn't good enough.

Since I've been writing this at different times, the feel of different passages is different, and that's OK - one part of it is more brooding and introspective, and I like that.

I was hoping to get 60 pages written and 20 endings, and I don't know that I have that much in me. If each of my existing dangling links is one more choice and two endings, that's 21 more pages and 14 more endings, that's 50 pages with 18 endings - pretty close to my target. I think I can do that.

Friday, April 19, 2013

A little more progress:


  • 22 pages
  • 2 endings
  • A little bit of storyline merging
  • 1669 words
The script I'm using to analyze the graph says that I've got 28 dangling links, which seems totally wrong. I told myself that I wouldn't be debugging code as much with this project, and yet here I am, debugging code. What's in the spooky cave? Only what you bring with you.

Sunday, April 14, 2013

Working on the Branching Path Game Book Project

Inspired by "A Conversation with Ophion" by gnustoboz as well as the Car Wars Adventure Gamebooks"Ring of Thieves" by S. John Ross, and, of course, the  Choose Your Own Adventure books, I've decided to make a branching-path gamebook for my One Game a Month game for April.

I've already done some work to take a text file and turn it into an .EPUB file, which is going to be my delivery format. There remains a little bit of work to do there (shuffling pages, making sure linkages work), but the majority of the work that remains is to actually write the story.

Again, taking a page from gnustoboz, I'm using Twine to manage my text. I could write it all in any text editor, but having a little bit of feedback about what pages link to other pages is appealing to me.


So far, I've created:

  • 15 pages
  • 20 dangling links to pages I haven't created yet
  • 1042 words of (non-link) text
  • 1 ending (where the character falls, trips, and is eaten. Be careful!)
I think I want somewhere between 64 and 100 pages, and somewhere around 10-16 endings. This isn't going to be a big book; in comparison, the old CYOA books had around 120 pages, with something like 30-40 endings. Perhaps I should scale down the number of pages I'm targeting - perhaps 60 pages with 20 endings is reasonable.

Sometimes, I feel like I'm writing a text adventure game, but then I remind myself not to give the reader/player any reason to want to backtrack as they explore the world. Then, I lurch into more narrative mode, and I have to remind myself to give the player meaningful choices every few paragraphs.

Perhaps, if I'm pleased with the outcome, I'll end up formatting a print copy that is available on Lulu. Perhaps some Creative Commons licensed clip art could be pressed into service to make it feel more like a real book.

It'd be kind of funny, kind of strange, if the first money I make from this One Game a Month project comes from a book.

Sunday, April 7, 2013

Trying to take it easy in April, so I'm only working on two game projects

I need to focus on work this month (again), so I'm deliberately trying to take on a small project. Unfortunately, I've got two small-ish projects, and I haven't yet chosen, meaning I'm sort of working on them both.

Maybe I'll get one done early, and then defer the other one for May.

Idea 1: Crystal Golf

For my first idea, I'm thinking of a puzzle game where the player is shown a maze (a little like a sokoban configuration), with walls on a rectangular grid. Also on the grid are several crystals, and a ball. The player has a fixed number of "swings" to putt the ball around the level and collect all the crystals.

Nothing too challenging there code-wise. A handful of square images for the level, a few images for crystals and the ball, maybe some particle special effects when a crystal is collected.

Today, I did a first pass of generating a grass square, a grey stone square, a ball, and a crystal. Not much, but it's a start.

Idea 2: Branching Adventure Game Book

I've been toying with the idea of making one of those branching-path books that I read over and over again as a kid. You know, the one where you make choices at the bottom of the page, which would direct you to turn to page 31 if you wanted to explore the spooky cave, or page 63 if you wanted to check out the abandoned amusement park.

My idea is that this might take less code to do, especially if I use a tool like Twine / Twee. I saw somebody do a similar thing in March, which wasn't the origin of my idea, but it gave me encouragement.

One idea that I had, to make it portable and useful to people who might want to play this on tablets, was to make my book as an EPUB file, which I figured could make it easy to read - if I could figure out how to get links to work.

I spent a fair amount of today tinkering with the tutorial code from python-epub-builder and opening it up in Okular, the app that seems to want to handle .epub files on my Fedora Linux box. I've been getting weird behavior with the links, where sometimes they'll be underlined, and sometimes they won't be, and sometimes they change the cursor on hover, and sometimes they don't, and sometimes they react to clicks, and sometimes they don't.

I teased out some of the reasons for some of the weird behavior, but I still have behavior that I can't explain. I opened up my test book on FBreader on my tablet, and Aldiko, and to my surprise / relief / consternation, things seem to work fine over there.

Just now, I installed FBReader on my desktop machine, and it works OK here. So, maybe I'll work on getting an .epub book working in April - I'll still end up doing a little bit of programming, including getting a little bit of styling working, but presumably not as much work as if I were making a real game.

The working title that I've got for now is "Escape from Puzzle Island", which I'll probably abandon - or, rather, I'll probably keep that title for a different project (much) later, where the player will actually have to solve puzzles to progress.

The first book of this kind that I read as a kid was the Choose Your Own Adventure book "Space and Beyond", which boasted 44 different endings. Maybe I can get a dozen endings and call it good.

Monday, March 18, 2013

Dots 'n' Boxes - playable, sometimes beatable

Over the weekend, I did a little bit of work on the small Dots-n-Boxes (DnB) game that I've been working on for March.

Dots and Boxes is Hard(ish)

Years and years ago, I took a game theory class taught, in part, by Elwyn Berlekamp. The man's an important figure in combinatorial game theory, but I was frustrated, because that didn't seem to cover the parts of game theory that I was interested in. We had one lecture on finding optimal mixed strategies, given a payoff matrix - which I still think is more generally applicable.

Berlekamp wrote the book on DnB, and surprise, surprise, it's a good example of using combinatorial game theory to find optimal play. Well, its one of the few examples of a game that is appropriate for CGT. When was the last time you played a good game of Nim? Yeah.

Later on, I saw John Conway speak at the Game Developers Conference, and the point of his keynote was that game developers should put more mathematical grounding in their games. I think he wanted more games that could have provably optimal play. If you want a contest to prove your mathematical insight, you're welcome to build such a thing, but that's (mostly) not the kind of games I'm interested in.

As part of that keynote, Conway brought a person from the audience (let's assume this guy wasn't a plant) and challenged the audience member to play a game of DnB. Conway pointed out that a 3x3 dot game of DnB has approximately the complexity of tic-tac-toe, and no adult would have any difficulty playing to a draw after they've played tic-tac-toe a few times. Conway proceeded to trounce the audience member game after game after game.

I expect there are a few tricks to 3x3 DnB, which Conway must have picked up, but it's weird to me that they're hard for a casual player to grasp.

I think one of the things that distinguishes DnB from tic-tac-toe is that DnB is a combinatorial game, where tic-tac-toe is not. If you're not familiar with CGT, that may require a little more explanation. In CGT, an important property of games is that they break up into independent smaller games. Nim is a good example of this kind of game - in Nim, players alternately take stones from a set of piles of stones, and the last player to move wins. With some analysis, you can determine that you can play optimally by XORing the sizes of the stone piles together and always leaving your opponent a game configuration that XORs to 0. (I leave the analysis to the reader. Or Google it. Or take it on faith. Or don't - it's been a while, but that sounds correct.)

So, Nim is actually one game, made up of several smaller games, each on a single pile of stones. Each time you make a move in the game of multi-pile Nim, you're actually selecting one pile of stones, and making a move in a game of single-pile Nim. The analysis of multi-pile Nim ends up being the study of how these independent games of single-pile Nim work together.

Back to DnB, though. At the beginning of the game, maybe you play randomly, and you try to avoid drawing a third wall on any box, or else your opponent gets a free box. Good so far. At some point, all these "free" lines have been taken, and all that remains are a number of chains. So, maybe you pick the smallest chain, and add a line to a chain, and your opponent takes that chain and gives you the next chain, alternating, and if you're lucky, you get enough of the long chains to win.

Wait, lucky? Did I mean that? Well, I shouldn't have - there's no luck in this game. Well, if you're actually playing randomly, there could be.

Anyway, you can see that these long chains have the feel of the single-pile games of Nim, and you can hear Conway and Berlekamp in the shadows, laughing at you. Should have paid attention in game theory class.

It's been a while since I read Berlekamp's book on DnB, but I recall him making some claim that an observant DnB player can beat a good computer playing DnB using normal lookahead. I think that he had a research student write a mediocre computer player, and Berlekamp was able to beat it at some reasonable lookahead depth. Maybe he was being unfair, or maybe he was making a point that you can abstract board state in DnB down to a much simpler representation (the set of lengths of chains in late-game play), which is much more susceptible to efficient analysis.

Weekend Progress

This weekend, I started by making just about the simplest computer player that I could - one that listed all the legal moves, and picked one at random. I like giving my AI opponents names, so I named this one "Randy".

This opponent isn't much to play against - one can readily beat him if you're paying any sort of attention. Well, and not trying to lose. I spent a little bit of time trying to lose to Randy, and found a few bugs where the AI kept trying to find good moves, even when the game was over.

After getting Randy to play as well as he was going to, I set Randy playing against another Randy, and it was interesting to me that it was typical that games typically were won by a large margin. This may have been due to there being a few very long chains, and once you started playing in a long chain, you usually cleaned the board.

After Randy, I proceeded to use the same framework of choosing moves, and added in a fixed-depth Minimax opponent.

One thing that I find frustrating is the gulf between the academic presentation of AI (particularly minimax game tree analysis) and the practical AI that's used for computer opponents in actual games. This sort of gets to my dismissal of John Conway's plea for more mathematically-based computer opponents. The problem is that the assumptions and the goals are completely different - academics typically assume that they have a single thread of execution and can consume that, maybe for a maximum length of time, and if they can come up with an optimal answer, that's great, or, if not, at least a best guess. In practical opponent design, it's more important to provide a good challenge to the human, and you typically only get a few milliseconds at a time before you have to give the CPU back to let the game render or play music or whatever. Some of this can sometimes be handled by threads, but it seems to me that being able to make incremental progress towards a good solution is important, as it'll give you more room to negotiate as the other parts of the game consume more or less resources.

So, I hacked together a simple minimax opponent, and I'm being all sorts of gross, as I'm making heavy copies of a heavy board state object, and I'm not caching them, so if I'm evaluating one board state in one branch of the game tree, and then I re-evaluate that board state in another branch, I don't reuse the knowledge I came up with, I redo all of the work. So, branching factor kills me.

Even with all of that, I play a little bit of 3x3 dot DnB, and the 2 and 3 depth minimax player is playing acceptably - not perfectly, but decently. Depth 3 on 3x3 can play me to a draw and beat me now and then, and I can beat it, but I think that means I'm a terrible player.

I tried playing 3x4 dot DnB, and it was at the edge of my patience. I also cranked it up to 4x4, and that was well outside what I wanted to wait for.

This morning, I added in a simpler representation - I took each piece of important information out of the board state and combined all of the data into a single number that uniquely represented the board. In the code, I call it a 'hash', which is not exactly correct - it's a binary packed representation. I can turn a board into a 'hash', and construct a board from a 'hash'. From this, I can start caching results, which will help prune out redundant evaluation.

Another thing I could do is look into implementing alpha-beta pruning, which ought to eliminate a bunch of other unnecessary evaluation, but I think won't be as useful.

Another thing that would help a great deal is to identify equivalent boards. The easiest set of equivalences is to recognize that rotating a board 90 degrees doesn't make an interesting difference when figuring out the best move. If you can rotate the board into a canonical best state, and evaluate that, then you can reverse the rotation and get the best move for 4 rotations (on a square board) plus 4 more with reflection. That's an 8x speedup, which is pretty good for shallow trees.

Another bit of equivalences that'd be useful to capture would be to boil the board down to chain lengths. A chain of length three behaves the same way, no matter where it is on the board. And then a chain of three and a chain of five combine the same, even though there are a lot of ways that those two chains might be positioned on the board.

Monday, March 11, 2013

Marching forward

I told myself that my March game was going to be deliberately small, as the Space Courier game was a lot bigger than I had planned, and (real) work needs to be able to expand to fill the time that it will, so best to keep the after hours coding project scoped small.

So, I decided to again punt on designing anything new, and this time went to an old standby, the dots-and-boxes game.

This weekend, I started off by copying code over from the Space Courier directory (woohoo, code reuse!), and culling out the stuff that was obviously unrelated to dots and boxes.

I added in a little bit of drawing code, and a little bit of "if the player clicks at position x,y on the screen, what line segment do they mean?" code.

And then I got distracted by other stuff in my life.