Author Archives: Fishbreath

OpenTafl v0.2.4.7b, and a finalized engine protocol

The biggest news first: the OpenTafl Engine Protocol is officially version 1.0. Future changes to the protocol will be backward-compatible, and will contain some way of alerting OpenTafl that you support a version greater than 1.0, but that’s not in the near term. The OpenTafl Notation Spec has changed in a few minor rules-string-related areas, particularly king strength; make sure you update your engines based on that. The Notation Spec is also finalized: changes will be backward-compatible for the foreseeable future.

With engine mode all set up, I spent some time hammering out bugs in the OpenTafl AI, and its external engine client functionality. The 2.4.x series has been almost entirely bugfixes since my last tafl post, so I have very little news on the recent-developments front. As always, you can read about the little changes in the latest README file, available as part of the OpenTafl download.

As I said in the last post, I’m taking a break to work on my schedule generator for Out of the Park Baseball, which should take me a week or two of coding time; after that, I hope to get the Lanterna-based UI working in a raw terminal context, so that it doesn’t depend on a system with a GUI. (The default will probably remain Lanterna’s Swing-based terminal emulator, but having a headless version will make running the tournament easier.)

Once I’ve finished that, it’s on to networking! Though it’ll be a huge pain, I’m looking forward to wrapping up that feature.

The Crossbox Podcast: Episode 6 – Tax Day Edition

In this episode, we debut a new segment, talk about our summer shooting sports plans, kick in virtual doors and shout, “Police! Freeze, scumbags!”, and bore our listeners to death with a piece called ‘logistical topics of interest’.

Happy Tax Day! Remember, your government is sufficiently bloated that Tax Freedom Day isn’t for another week.


(Download)

OpenTafl v0.2.4… .2b: now with extra hotfixes

I’ve released another new OpenTafl version, this one with two major features:

First, tablut games. Two tablut variations are included. The one listed as ‘tablut’ is standard tablut, according to the rules given at Aage Nielsen’s site: armed king, strong at the center but weak elsewhere on the board. The one listed as ‘Foteviken tablut’ is, again, from Aage Nielsen’s site, and features something altogether new for OpenTafl, a feature I had planned for but had not yet used: attacker fortresses, used here for hostile attacker camps. In this version, the attackers may move around inside their starting areas, but may not re-enter them from the outside. Defenders may not enter the attacker fortresses. Additionally, the attacker fortresses are hostile to the king. In exchange, the king is always strong. This represents an interesting middle ground between corner escape rules and edge escape rules: the king’s side must still play for the corners of the board, but needs not play for the corners specifically.

Second, the implementation of the ‘rules’ command. In a game, you can type ‘rules’, and you’ll get a dialog window showing the rules of the game you’re currently playing, or the replay you’re currently viewing. Helpful if you lose track of them, or if you want clarification on a certain point of the rules for a replay.

In other news, I’ve made some small improvements to the UI, specifically the scrolling labels used for the help and rules windows, and for the in-game status display, and have compiled two more of Tim Millar’s excellent annotated games (from the World Tafl Federation) into OpenTafl replay files.

This is likely the end for 0.2.x; I hope to do some serious testing over the next week or two, as well as finalize the engine protocol. Look for a 0.2.x final in the next few weeks.

Glass for Kat: picking an AK optic

As is so often the case, choice of optic dictates other firearms setup questions, and, since Kat did not come with an optic, I had some choices to make right off the bat.

Choice one: skip optics altogether, shoot irons like real man, da? This is not a particularly compelling choice, although it is made very slightly more compelling by my colleague’s admittedly effective sight mods (painting the front sight white, and filing the rear notch a little bigger). In Standard Two-Gun Rules, I’m allowed one (1) rifle optic in the Practical Division in which I plan to compete, so I don’t want to handicap myself unnecessarily.

Choice two: bog-standard Americanski-style micro red dot on a railed gas tube. This is one of those indisputable choices: I can’t really fault someone for going this direction. You get a nice, easy-to-acquire sight low to the bore, you get cowitnessing for free, and you get all the benefits of red dots: good-enough precision for battle rifles, durability, and all that tasty, tasty red-dot ease of use. Nor will they break the bank.

That said, I don’t think it’s quite for me. A micro dot far forward on a rifle has a very, very small apparent size, and that makes rapid transitions and fast acquisition harder, robbing the red dot of its main advantage over a magnified optic. It’s also impossible to magnify: even if you could find a magnifier with a foot and a half of eye relief, you’d be hard-pressed to fit it on the rail, and even if you could fit it on the rail, you’d be wrecking the balance of a rifle which is already a little nose heavy.

Choice three: red dot or holo sight on one of those AK side-rail Picatinny mounts. This is the first one I seriously considered. For one, your top-of-the-line red dots and holo sights (your Aimpoint Micros and EOTechs) come to about $500 or $600, which is much cheaper than high-end glass1. The mounting position solves some of the issues I have with the forward red dot: it’s right there, next to your eye, so picking up the sight is easy. You lose cowitnessing, but I don’t care about that much anyway. Without having to worry about putting weight way up by your front hand, you can also go a little bigger on the sight, moving up to full-size red dots or holo sights, and on the larger side-rail mounts, you could even fit a magnifier. Perfect, right?

Well, not quite. A red dot and magnifier are two parts to fail, and neither is useful without the other2. Nor are you gaining anything in weight, really: you’re up at a pound or so with a 3x magnifier and micro dot, and that’s getting up toward the weight of our eventual winner.

Choice four: ACOG-style compact, low-eye-relief scope
This is the one I ended up going with. It isn’t an ACOG, but it fits the pattern: we’ll call it a nayCOG. First: limited eye relief doesn’t bother me. If it’s whacking you in the face, you’re doing it wrong3. Second: I like magnification, especially with a reticle smaller than the target I’m likely shooting at (which may or may not be the case with a magnified red dot). Magnification buys you better precision straight up, and also better target discrimination at range. Third: a nayCOG is only a few ounces heaver than alternative options at most4, and all of that weight is at the back of the rail, owing to the scope’s small size.

Why not a simple, variable-power 1-4x tactical scope, say? Because at 4x, the field of view for such a scope is a little more than half the field of view of a fixed-power 4x nayCOG. Field of view at range helps maintain situational awareness and eases target acquisition; at close range, a good field of view helps with rapid acquisition of a target and both-eyes-open aiming, though on both fronts it obviously loses to a proper reflex sight.

Finally, you may object that I just said difficult acquisition pushed me to drop the forward micro dot; that, though, is a fundamentally different sighting system. I don’t mind the extra work if it means I have access to magnification.

So, having decided all these things, I was at a gun show a few weeks ago, and came across what is turning out to be just about the perfect optic. Tune in next time to find out exactly what I bought, and how it’s turned out so far.

1. I was just talking to parvusimperator about his next rifle build, and he could end up spending four times as much for a high-end 1-6x variable-power scope.
2. This is not ordinarily an issue, if you’re buying things of moderate quality, but I am nothing if not a cheapskate!
3. Next time, you’ll see that this is an ironic tack for me to take here.
4. The one I got weighs 16 ounces with an integral mount. A 1-4x tactical scope is probably a little lighter, but a red dot, magnifier, and flip-aside magnifier mount are just as weighty.

OpenTafl v0.2.3b release, and a vision for 0.3.x

OpenTafl v0.2.3b has been released. I won’t go into its myriad features, leaving that task to my previous post, and the README included with OpenTafl, but I do want to talk briefly about the next release, and what it’s going to bring to the table.

0.2.x has been a little less focused, with its three major features (by my count, external engine mode, AI self-play, and replays/saved games), but 0.3.x is going to be laser-focused on adding network play. This will happen in a few stages.

The architecture
I’ve made good progress on this stage already. I will add a server mode to OpenTafl, which will hold canonical representations of all games in progress, and send move updates and clock updates between clients over a TCP connection.

I chose a pure server-client model to limit NAT issues: peer-to-peer networking is super-annoying, while server-client lets clients initiate the connection and therefore know to do all their fancy address translation. I chose TCP to limit the amount of bookkeeping I’ll have to do. UDP requires acknowledgement and resending; TCP handles all of that as part of the protocol, and given that an OpenTafl server won’t send traffic to any given client at very high rates, the overhead is acceptable.

The protocol
I intend to recycle the OpenTafl Engine Protocol pretty hard: guaranteed ordering and delivery, as you get with TCP, solve a lot of its problems in unreliable environments. (It will require some enhancements to compensate for latency in clock updates.) No reason to do more work than necessary.

Unlike external engines, network clients can’t run so headlessly—at a minimum, they need to display the game for the human on their end, so I feel that clock updates ought to come a little more often than ‘on turn changes’. It’ll probably end up being on turn changes or every five or ten seconds; the client will handle intermediate counting-down, while the server will keep track of time authoritatively.

Server features
The first version of the server will be pretty bare-bones. It will likely keep a list of known usernames and passwords, but feature no recordkeeping; it may be able to save game records on the server machine for later replay by hand.

I’d like to focus on building strong, configurable internals for the server, in case anyone else plans on running one: a thread pool to help limit resource usage, to start, and we’ll see what other options turn up.

I don’t intend on doing anything for correspondence play—Aage Nielsen has that market handled.

Client features
I hope to make the client fairly full-featured: a filterable game browser, lobby and in-game chat, the ability to load saved games as the base of a network game, and game passwords.

Tournaments and AI play features
I’d also like to build in some features for tournaments (whether AI or human) and AI players (where computers running an AI can join the server, and humans can choose the AI as an opponent).

Tournaments are kind of a tricky issue; the ideal for human players (flexibility, marking yourself ‘ready’ and getting pushed into your next match) is incompatible with the ideal for AIs (order, which would plug them into games as soon as possible). There may be a viable middle ground, or a way to configure between the extremes, or, frankly, I might just skip it. If I get the networking functional in a general sense, I have a lot of time before I need to worry about

Anyway, that’s what’s coming next: exciting times ahead, in which OpenTafl will finally fulfill my original purpose for it—a better way to play realtime games with remote friends of mine. (Granted, it has rather expanded since then.)

OpenTafl progress: v0.2.3b, and 20,000 lines of code

This is not a notification of the release of v0.2.3b: there’s quite a bit of work still to go, as far as releases go. However, since I hit the milestone in the title last night, I figured I’d offer a little preview of what I’ve been working on. (Astute readers of Many Words Main will likely remark, “Well it clearly isn’t writing!” In this, they are not correct. It’s merely the typing I’ve failed to keep up with.)

So, what’s in 0.2.3b? Quite a lot, as it turns out; I got started on a certain big feature and couldn’t help myself. We’ll get to that in a bit. Here’s a rundown of the smaller pieces:

Completed external engine support
I finally buckled down and added the last piece of external engine support: engine-raised errors. I’d previously considered a more complicated set of engine-raised errors, but it boils down to this: there are two kinds of errors an engine can encounter, recoverable and unrecoverable errors. Whenever OpenTafl receives an ‘error’ command from an external engine, it presents a dialog box with a message provided by the engine in the command. If the error is critical (determined by the error code), the game ends. If non-critical, the game continues.

A particular IntelliJ feature greatly aided me in completing this task: there’s a quick-fix item for ‘implement interface method’, which is, to say the least, extremely handy.

Some internal changes
These mostly have to do with fixing little things which could cause trouble later. One of the principles of object-oriented design is that objects should do one thing, and some behind-the-scenes functionality was creeping into UI components. I spent some time and energy on this.

Resilience and stability updates
As this series of releases deals with adding more outside inputs to OpenTafl, I spent some time making sure that failures and edge-cases are handled gracefully. For instance, 0.2.3b will properly terminate external engines when they’re no longer required, and analysis engines are handled more like regular engines for consistency. In other news, I fixed a few random crashes I came across while working on this update.

Resolve embarrassing Copenhagen rules discrepancies
It turns out I had two things wrong about Copenhagen rules: first, edge fort escapes require the edge fort to be an invincible shape, not merely an enclosing one—that is, that black cannot break the fort no matter how many unanswered moves he gets. Second, the attacking side goes first. The second one rankles a little more than the first, especially because the first one revealed an interesting heuristic for whether or not a taflman in a chain of taflmen can be captured.

It goes like this. If a taflman is part of some safe structure (that is, a structure which contains no enemy taflmen), then you can determine whether it can be captured by, in a sense, counting liberties. Get all four orthogonally-adjacent spaces, then remove any spaces which are inside the structure, and any spaces which are currently occupied by friendly pieces. If and only if you are left with three spaces can the taflman be captured. This is a nifty little way of detecting defects in chains, taflmen which are ‘sticking out’—alone on a certain rank or file. It may come in handly sometime down the line.

And now for the big feature.

Saved games and replays
Screenshot

As part of AI self-play mode, I wrote a game serializer: a way to write out game records for later viewing. Once I had done that, I was halfway to a full replay system; and once I had a full replay system, I was immediately adjacent to loading games. OpenTafl’s replay/save system has the following features:

  • Replays and saves become the same sort of object: a human-readable OpenTafl Notation game record file.
  • Replay mode can be initiated from any game record file, or from any point in a game in progress. If the other player is not also a local human, the other player can make moves while you are viewing the replay of the game in progress.
  • At any point in a replay, you can begin a new game from that position. (Note that, at this point, you can’t return to your original game except by reloading the original game. This is a limitation which will likely be around for a long time: playable variations are likely to be a huge pain.)
  • Replay mode supports annotations, and annotations following a certain format will correctly update OpenTafl’s clock display.
  • Saved games are a shortcut of sorts: they load a replay file, play it to the end, then use the ‘play-here’ function.

I have two tasks left on my plate before I’m ready to release 0.2.3b. First, I need to test the game serializer and loader against Berserk rules tafl: the potential for more than two moves per turn (in the case of berserk moves) is one I hadn’t quite considered, and need to consider. Second, I need to write help messages for all of the new functionality.

Once I’ve released 0.2.3b, it’ll be time to give the engine protocol one final once-over, and freeze it at version 1.0, where it will remain until at least this winter’s tournament. (If critical weaknesses are revealed, it’ll have to change. If no major weaknesses are revealed, it might stay at version 1.0 indefinitely.)

Finally, I want to touch on how big a milestone this is for OpenTafl, in my estimation. Before the 0.2.x series of releases, OpenTafl was essentially a toy: a novel way to play tafl games—there aren’t a lot of modern desktop clients—but little more than that. Following the completion of 0.2.x, OpenTafl will be a tool: for learning to play tafl, through the replay and annotation functions, and for studying computer tafl, through external engine mode. We’re arriving now at the purpose I had in mind for OpenTafl—to expand the base of people who are able to translate a casual interest in the game into a deep study, by building tools to make it easier to do so. Here’s hoping it works.

Meet Kat: an AK project gun

Kat1 is a GP WASR-10/63. Essentially, this is a stamped-receiver AKM, with a side rail for optics mounting pre-installed. The WASR designation marks it as a Century Arms import of a Romanian AK; some WASRs were built for the American civilian market back during the bad old days of the assault weapons ban, but this one is not. Kat’s receiver bears a triangle-and-arrow mark that marks her as a demilled Romanian military rifle. Century Arms imported her and built a rifle around the parts kit. Unlike the old AWB-compliant rifles, she had a pistol grip and a bayonet lug2.

Kat was originally parvusimperator’s rifle; he sold it to me at a steep discount as part of a wedding gift package. Since he is Captain Tacticool, it varies a bit from the original, 1950s-style configuration. Here’s what he’s done to it:

  • Added a NATO-length polymer stock. (NATO-length is slightly longer than the default AK stock, more closely approximating your M16 length of pull.)
  • Added a railed gas tube forward.
  • Switched out the forward handguard and the grip for Hogue rubberized ones.
  • Added an AK-74-style muzzle brake.
  • Added a large charging handle knob.
  • Added an improved safety lever.

I had the rifle out at the range the other day for some sighting in, and with a few magazines through Kat, I’ve decided what I’m going to keep and what I’m going to drop. Before I get into that, though, I should explain what Kat is for. At a shooting range an hour or so from Many Words World HQ, there’s a monthly two-gun shoot: that is, a combined practical rifle and pistol event. Kat will serve as my Scary Black Rifle for that endeavor. The precise setup, however, is a topic for the next post.

NATO-length stock – Drop
The main reason why this stock won’t do has to do with my choice of optic, which, as I said, is a topic for the next post. The NATO-length stock has two faults: it’s too long for proper/comfortable eye relief with my side-rail-mounted optic, and the comb is too low for a good cheek weld for same.

Railed gas tube – Keep for convenience
I don’t plan on going the cowitnessed red dot route, which is the main use for the gas tube rail, but I don’t have any particular reason to ditch it. Rails are useful. It might come in handy sometime.

Hogue furniture – Keep
I can’t speak highly enough of Hogue’s AK stuff. Grippy without being painful, comfortable to hold, well-molded to the human hand. I couldn’t do better if I tried.

Muzzle brake – Keep
I wasn’t planning on sticking with the AK-74-style brake, since it’s renowned for its size and weight. Tapco used to make a superb muzzle device for AKM-style rifles, which scores at the top of every muzzle device shootout I’ve seen, but they aren’t available anymore. The AK-74 brake may be amusingly large, but that’s part of its charm, and it does look very proper on the front of the gun. It also scores very well in most shootouts, and certainly reduces felt recoil and muzzle climb to very manageable levels: not very far off of an AR-15 without a brake.

This one may change down the line, but I’m holding onto it for now.

Charging handle knob – Keep for convenience
I probably would have chosen a slightly smaller charging handle extension: parvusimperator, in typical fashion, went for what I think is the biggest one he can find. It’s held on with a set screw, looks like, and parvusimperator tells me that he used the dreaded red Loctite, so in the interest of avoiding the tremendous bother finding my heat gun would be, I’ll just leave it as-is for now.

Safety lever – Keep!
The single best mod on the gun. I can easily flip the safety on and off with my index finger. Definitely holding onto it.

So parvusimperator did a pretty good job, though it pains me to say: Kat already has some of the features I want in a competition rifle. She is controllable, much better off as regards ergonomics, and attractive in that Scary Black AK way. Next post, though, we’ll explore what I’m doing to make her mine.

1. It’s multilingual wordplay. A common way of forming a diminutive, cutesy version of a name in Russian is to add an ‘oshka’ or ‘eshka’. For instance, the word for ‘male cat’, ‘kot’, turns into the general word for domestic cats of any sort by adding ‘oshka’: ‘koshka’. Pinning it onto the end of Kalashnikov yields ‘little AK’, Kalashnikoshka, which also ends in the word for cat. Hence, Kat.
2. It was ground off, at some point, but it was almost certainly imported with one. Parvusimperator speculates that, since he obtained it in New York (no friend to firearms rights), the bayonet lug was removed for compliance there.

OpenTafl v0.2.1b released

OpenTafl v0.2.1b has been released here. It has almost full support for OpenTafl Engine Protocol, and the protocol specification is also near-final. (I’ll be finalizing the protocol definition in a release or two.)

The other feature on the docket for 0.2.x is a local engine-vs-engine tournament mode, which I (and, for that matter, you) can use to quantify strength gains from changes you make to your AI, by playing the current version against prior versions. I’ll provide more information on this feature as I develop it.

On tafl: time use strategy

I wrote last month on game clocks for tafl games, and settled on something like the go game clock: main time, plus replenishing overtimes. You can find my reasoning at that link, so I won’t go into it here, rather taking the opportunity to chat about how to use the time that game clock gives you.

In undertaking any previously un-undertaken task in AI development, this question usually has an instructive answer: “How does chess do it?” Unfortunately, this case is one of the ones where the answer is a little less instructive. A perfectly functional, if not altogether optimal, time usage strategy for a chess AI is to assume that, however many moves the game has taken so far, finishing it will take 20 to 40 more moves. The AI should therefore use between 1/20 and 1/40 of the time remaining. Simple, and surprisingly effective: a chess game gets less complex over time, as pieces come off of the board.

No such luck with tafl games, though. A tafl game starts at moderate complexity, then grows significantly in complexity into the middle game, before tailing off again as the action focuses on a corner and as captures are made1. So, for fixed-time games, we want to spend a moderate amount of time on the early game, the bulk of the time in the middle game, and a decreasing amount of time in the endgame, conserving it as long as possible. For fixed-time games, OpenTafl, in its current incarnation, assumes that it’ll want to make a certain number of opening game moves (3, 5, or 10, for board sizes 7, 9, and 11), a certain number of midgame moves (6, 10, or 20), and an indeterminate number of endgame moves after the midgame. It dedicates a fixed amount of time (at present, 5%, but probably likely to increase) to finish all of its opening moves, a much longer amount of time (presently 75%) to the midgame moves, and a constantly decreasing amount of time to its endgame moves, with the remaining 20%. This seems functional enough in play with me, but the numbers will obviously be tweaked once I finish automatic self-play. (A feature which will be in 0.2.x, I’m pretty sure, given how handy it is for AI developers.)

Four hundred words in, though, and I haven’t yet covered the topic I said I wanted to cover to begin with: how do we handle overtime timing? It turns out that it’s simpler than fixed time, even: take the number of midgame moves above, use the main time for them, and use overtimes for all remaining moves. This, too, may be non-ideal—I could see some benefit to using the fixed-time framework for early game and midgame, and falling back on the overtimes only for endgame moves2.

There are some extra features I hope to add at some point: a little bit of history awareness, so that, whenever OpenTafl sees a wild swing in expected value for the current state, it can dedicate extra time to a deeper search. Another useful addition would probably be some slightly more adaptive time usage generally, with the ability to understand when the game has moved from the early game to the midgame, so that it can adjust its thinking time based on the state of the board, rather than fixed numbers of moves. That said, it’s heartening to see that my system for main time plus overtime time usage is basically what AlphaGo used in its games against Lee Sedol3.

Finally, and a little tangentially, I want to talk about OpenTafl’s success against me on various time controls. Now, I am a poor to average tafl player at best, so you should not take this paragraph to mean that I think OpenTafl has much of a chance against anyone good. Keep that caveat in mind. OpenTafl generally loses to me, and loses pretty severely, on longer time controls: this is a result of its flawed evaluation function4, which, along with alpha-beta pruning, frequently gets rid of branches that are ultimately better than the one it chooses to explore most deeply. The matches are closer with blitz timing: a 60-second brandub game proved to be pretty intense, and I only won with six seconds left on the clock. The shorter time control plays to the computer’s strengths: exhaustive reading three or four plies out, and it gets much closer to me in skill (in part because I can’t read exhaustively in such a small amount of time).

Anyway. That’s your inside look at the most recent major OpenTafl feature. Stay tuned for more in the coming weeks.

1. I should note that by ‘complexity’ here I’m referring mainly to branching factor, the quantitative measure, mixed with a little bit of my sense for what proportion of moves are worth considering, a much more qualitative one, and, for that matter, a much more unreliable one.
2. Although it may strike you that 30 moves for an 11×11 game seems a bit light, consider that it’s actually 30 turns, or 60 moves total: for most 11×11 games, the game has either ended by then, or we’re well into the midgame or late game.
3. I got sleepy just thinking about being up that late. It is my sincere hope that when DeepMind announces its match against Ke Jie or whoever’s next, that they agree to play in London. Or maybe New York. Somewhere closer to Eastern Time, please.
4. A topic I intend to go into deeper detail on in a later post, when I’m working on some cleanup and improvement.

OpenTafl v0.2.0: Engine support arrives

In experimental, incomplete fashion, but it’s sufficient for you, as a developer, to start working with OpenTafl in engine mode. You can find the new version at the OpenTafl site. The engine protocol document has been updated with the latest developments. Although I won’t be able to say for sure until I’ve finished the implementation, this version of the protocol is nearly feature-complete, and likely won’t change very much going forward.

Expect a post in the not-too-distant future on OpenTafl’s time usage planning and time-filling activities, both of which are topics of some interest.