I just released a new game!
Mosaic River is a mobile solitaire game. You’re an archaeologist, sailing down a river, collecting mosaic tiles, and placing them into a triangular grid to make melds (straights, flushes, etc). Tiles have bonuses randomly assigned at each game.
You can try it now: it’s free (ad-supported) on iOS and Android.
It’s perhaps easiest to explain by describing some of the influences.
The first is Uwe Rosenberg’s Patchwork, one of the finest board games ever created. In Patchwork, the acting player can choose any of the three tiles in front of a marker, and choosing a tile advances the marker to that position. This means sometimes you might want to take a suboptimal piece to skip over a piece that would be really good for your opponent. In Mosaic River, you draft by sailing across the river and choosing one of the next three tiles. Choosing a nearer tile will allow you to collect more tiles overall, but it has a cost. Choosing a further tile might mean that you skip tiles you want, but in return you gain more optionality later (or, at worst, a few extra points).
Another influence is Diffusion-limited aggregation (DLA). In DLA, particles move around randomly and then connect. You end up with these tree structures. This influenced the design of Mosaic River’s connectivity rules. Half of tiles are “center” tiles, which need to be next to two other tiles, and other half are “edge” tiles, which need to be next to only one. The idea is to create a similar bushy structure. But since you only end up taking a small subset (perhaps a third) of the available tiles, and because center tiles want to connect in multiple ways in a compact cluster, we need to give a little bonus to edge tiles to get the desired shape.
Of course, Lost Cities is also an archaeology-themed card game with five suits, but it wasn’t consciously an influence. It’s just that every kid dreams of being Howard Carter or Indiana Jones. I’ve been listening to the History Of Egypt podcast too, although I think I am likely to give up, since there’s often proportionally more focus on the pagentry of Egyptian religious celebrations than on the narrative than I would prefer.
I’ve decided to try a different revenue model with Mosaic River than with Surfwords. I’m doing ads. This sucks, and I hate it, but since Surfwords isn’t selling, I’m going to try something different.
It was pretty easy to get AdMob working with Godot, but the plugin is a little dumb: it doesn’t seem to understand that you need different admob ids for Android and iOS but that you otherwise want (usually) the same codebase for each. (Actually, looking at the config, maybe it does understand this, and I’m just doing something wrong.)
I guess we’ll see how ads perform financially. My next game (see below) will try the freemium model and maybe that will do better.
As with Surfwords, getting graphical elements to scale nicely to different screen sizes is a hassle. I ended up having to adjust the dimensions of the mosaic to accommodate older (wider) iPhones. It looks like phone manufacturers are starting to standardize somewhat on very skinny ratios, roughly 2:1, but older iPhones and Android phones still exist in the world and must be usable. The long skinny shape is actually somewhat restrictive as a game developer — as a random example, on some modern phones, anything circular can take up at most 35% of the screen (for a 4:3 screen, it’s 58%).
As usual, Godot’s layout model is not as user-friendly as one would hope. It even makes me miss CSS, which is saying something.
Google refused to approve my app, because it was crashing on startup. Weirdly, this didn’t occur during their pre-launch checks. During pre-launch, crashes are reported with logs. During approval, you can’t get logs. This makes no sense. I uploaded a new version with some random added logging, and of course the crash went away. But please let me know if you run into a crash, and, if you can, send me an adb logcat.
Of course, as soon as I released, someone pointed me to an issue that didn’t exist on any of the devices I tested on (and that Apple somehow totally failed to flag — so much for the supposed quality review). Then when I went to upload a hacked-together fix, I ran into a random Apple bug that Apple, of course, didn’t report on their system status page. It eventually fixed itself. The fixed version is now released.
It turns out that I do not enjoy art direction. This is about me: I don’t want to tell an artist that I don’t like their work, and that they have to do it over again. I think I would feel differently if an artist were a true partner in the project, instead of a hired gun.
I’m working with a designer on my next game (see below). This will, I hope, be a different experience, since instead of requesting spot art, I’m asking someone to work out the entire visual design of the game. It’s still a contractual relationship with me taking all of the risk, but it feels like a different story, since it’s not someone working to a specification, but rather someone creating their own visual story.
I used Material Maker to create the two main backgrounds of my game. This is a model that I really like: you plug some nodes together, maybe write some light math, and out comes an image at whatever scale you like. But it’s also somewhat opaque: when it performs badly, you have to go into a bunch of generated code to figure out what’s going on.
The marble-ish mosaic background ended up just baked into an image. Easy, and performant. The river background was way more complicated, since I wanted something animated and not obviously repeating. The problem is that phones have very crappy GPUs, so doing anything at all complicated blows the framerate budget out of the water. I didn’t really expect this, since the game does not have a ton of visual effects. So maybe I’m doing something wrong, or maybe Godot is. Or maybe GPUs are really good at slinging a lot of pixels around but not so good at generative stuff.
I definitely noticed that Material Maker does not have the ability to optimize one common case. And there was another missing feature too, which I just hacked around in the end.
I redesigned the scoring several times. While working on the code to compute straights, I noticed that a single tile could be part of multiple straights. This meant that the most optimal strategy was to ignore all other melds, and just try to maximize the number of straights. I fixed this by adjusting the scoring: I made straights score linearly rather than quadratically in length, and made them slightly lower scoring on average than flushes or n-of-a-kind.
Deciding which tiles got bonuses was also a little tricky too. Initially, I randomly allocated bonuses. But this didn’t work for “meld bonuses”. Meld bonuses are a kind of bonus which stick to the tiles. They are represented by scarabs, feathers, and eyes. If you have all three tiles with scarabs (say) directly adjacent, you get a lot of points. But you can’t do that if all three bonuses end up on edge tiles. So then I moved the bonuses so that they were just on center tiles. But you could still end up in a bad situation: if two identical meld bonuses end up directly across the river from each other: you can’t (except with another bonus which you might not have gotten yet) collect both. This felt unfair, and thus unfun.
I thought of a number of complicated ways to allocate bonuses to try to avoid this, but none of them seemed likely to work. So I decided to just reshuffle the deck until that situation was avoided.
While I was thinking about how to score intersecting straights, I considered a rule that a tile could only count for one meld. But then the melds would have be chosen carefully. There were three unpalatable choices:
The player could choose the melds at the end of the game (creating a tedious task right when the user wants the reward of seeing their final score).
The player could choose them during the game (interrupting flow and forcing them to make choices that they would likely regret).
The game could consider all of the possbilities and choose the best (creating an opaque scoring system).
I decided to do none of these, and to just allow intersecting straights. But I realized that, on its own, the decision problem was actually interesting — it just didn’t fit with the vibe of Mosaic River. So my next game will be about deciding how tiles should be arranged into melds. I’ve tried it out, and I’m really, really excited about it. Watch this space for news!
Previously, I reported on my attempt to use Stable Diffusion.
Dan Luu posted it to Hacker News, and there were some comments. Here are some responses:
Comments suggesting img2img, masking, and AUTOMATIC1111: that’s what I was doing, as I think the images in the previous post make clear.
Comments suggesting that maybe my prompt was no good: I didn’t put in anything like “oneiric”, or “blurry”, or “objects bleeding into each other”, or “please fuck up the edges.” So I don’t think it’s reasonable to blame my prompt for the particular problem that I was complaining about. One commenter suggested that I should have said “pier” instead of “dock”, but actually, judging by Google Images, I was locking for a dock (a place you tie up your boat).
Comments suggesting learning to draw, or that the problem is that I’m not an artist: actually, I am a bit of an artist: I make weird pottery.
I’m just not just not an illustrator. I have dysgraphia, which makes illustration challenging. The example I like to give, when I explain this is: I go to write the letter d, and the letter g comes out. That’s not because I don’t know what the difference is, or because I can’t spell. It’s because somehow my hand doesn’t do what my brain wants. Also, even if I were an illustrator, I would still like to save some time.
The problem isn’t that I can’t figure out the composition of scenes: as the post shows, I was able to adjust that just fine. The problem is that the objects blur into each other.
Others suggested that I could save time by using 3d rendering, as Myst did. This seems preposterous: Myst took a vast amount of time to model and texture. Yes, I would only have to model a place once to generate multiple images. But the modeling itself is a large amount of work. And then making the textures brings me right back to the problem of how to create images when I can’t draw.
Some commenters suggested that in fact I could get away with fewer than 2500 images. On reflection, this might be right. From memory (it’s been a while since I played Myst), the four main puzzle ages each have maybe 20 locations, with an average of, say three look directions per location. Then there’s D’ni (only a few locations), and Myst Island itself, which has roughly one age worth of puzzles per puzzle age. That would be about 500 images. Maybe they are counting all of the little machine bits as separate images? Maybe I am forgetting a whole bunch of interstitial locations? Still, 500 images is also outside of my budget, though less so.
Comments suggesting that it takes a lot of selection: yes, this is after selecting from roughly a dozen images each time. Generating and evaluating hundreds of images would not be a major time savings. If the problem were that I’m particular about composition, it would be reasonable to search through many images to find a good base (and, indeed, that was the part of the test where I was casting the broadest net). The problem is that I’m picky about correctness, and picking through a bunch of images for correctness is slow and frustrating.
Comments suggesting photoshopping afterwards (as opposed to “just draw the approximate color in the approximate place” during img2img refinement): If I could draw, I would just draw.
Comments suggesting many iterations of img2img, photoshopping, back to img2img, etc: 1. Ain’t nobody got time for that. 2. My post shows me trying that: it doesn’t solve my fundamental problem.
Comments suggesting MidJourney: It’s basically a fine-tuning of the Stable Diffusion model, so it’s likely to have the same problems with blurry and incoherent objects. Its house style is pretty fuzzy, which hides some of the incoherence, but for a game like this it’s important to know exactly where you are, and where an object’s edges are. The Colorado State Fair image (which was generated in part by MidJourney) shows some of the incoherence: look at the woman in the center — what’s that stuff on her left side? Part of the lectern? A walking stick held by the third arm coming out of the waist of her dress? Also, trying to do any refinement through a Discord chat seems even more painful than trying to use AUTOMATIC1111, which is already pretty slow and clunky.
One comment with an improved image: well, it’s a physically plausible object now, if you don’t mind that the dock is now made of stone instead of wood. I wonder why I was unable to get that. The image:
Also, the rightmost post is still sort of fading into the dock at the top. Maybe I was just unlucky? I don’t think the prompt was any better than mine. That gives me hope for the future. Next time a new model comes out, I’ll probably try again.
I really want to make a game along the line of Myst. I have been collecting puzzles for years, and I have almost enough. I am flexible about the visual style. I’ve considered making sets out of lego, or cardboard, or cut paper. And I’ve considered AI-generated art.
I am willing to accept compromises on precision: If the palm tree ends up on the left side instead of the right, that’s OK. It’s even OK if it’s a date palm when I visualized a coconut palm. I might even settle for a willow.
But it’s important that it looks like a place you could be in, and that the objects look like objects that could physically exist. This is why I’m so frustrated with Stable Diffusion. It’s so close to giving me what I want. But it’s not there yet, because it does not comprehend physical objects.
I asked for a dock at the bottom of a cliff. It gave me some stairs at the bottom of a cliff (admittedly, some of the other images had some vaguely dock-like things, but none had the perspective I wanted: almost nobody takes a picture of a dock from the water).
Ok, the stairs look great — I’ll just paint in where I want a dock, and have it clean up that part. (I also rearranged the composition a little to make room).
Here’s what I got:
OK, that’s sort of a dock. Like, there’s nowhere to tie up your boat, and it’s got weird protrusions, and it’s somehow below the waterline, but I can work with that. I’ll erase the protrusions, fix the rear, and add some posts.
Then I’ll tell Stable diffusion to just clean up those parts:
Oh look, it decided to put a weird vertical line in the middle of my dock. Why? And also, it keeps wanting to fuck up the right side of the dock. OK, I’ll clean it up with the clone tool:
Sure, we lost a post, but at this point, I don’t care. Stable diffusion, please clean up the clonejunk….
No! You fucked up the right side of my dock again! Don’t you know how solid objects work?
Aargh, I give up. I’ll just hire Mœbius to do the artwork for my game. What’s that you say? He’s dead? Noooooo!
(Yes, I could pay an artist to make art for the game. But I’m not yet good enough at game marketing for this to make sense: The original, 1990s Myst had 2,500 images, which would cost me more than I expect to make this year. Also, it would take an absurd amount of time. So I won’t do that … yet.)
The most important thing is that Surfwords now has a demo available.
I didn’t start out with a demo, because I was worried that it would cannibalize my sales. I am not worried about that anymore, because to a first approximation, I have had no sales. Surfwords briefly reached #7 on the iOS paid word game chart. This is hilarious, because I’ve sold less than 20 copies of Surfwords on iOS (and less on all other platforms put together).
To me, even before I wrote it, it was obvious that Surfwords is the sort of game that I would want to play. I like very hard word games. I know that Super Hexagon is good. Ghost is fun (if you’re stuck in a car and bored of Botticelli). The combination is just obviously going to be fun.
So why haven’t I sold a zillion copies? Or even enough copies to pay the bills? I don’t know, but I’m going to see if having a demo helps.
And then I’m going to go back to working on my next game.
Thanks to the success of Semantle, I decided to become a game developer. I’m going to try it for a year, and see if I can make a living at it. At the end of May, I quit my job, and started working on a new game called Surfwords. Now, at the beginning of August, I’m nearly done. As soon as I get this released, it’s on to the next thing (probably an archaeology-themed solitaire card game, although maybe I’ll do a two-player version too).
I love words, and I love word games. My favorite is Montage, which is a cross between Taboo and a crossword puzzle. You have to figure out a playable word, clue it, and have your partner guess before both opponents do, all within a one-minute timer. That’s the level of intensity I crave.
I was also inspired by Super Hexagon: it’s simple, you lose a lot, and with practice, you can improve. Surviving for a minute is a real achievement. One thing I like about Super Hexagon is that it more-or-less could have been written for the Vectrex in the eighties, but in fact it wasn’t released until 2012. This gives me hope for the world: there are games out there that are destined to become absolute classics, that we could be making right now.
Surfwords is a fast-paced word building game. Letters drop from the top of the screen in two columns. You have to choose which column to take at each row, in order to build up a series of words. It’s dead simple: you can pick it up and immediately start playing it. But it’s not at all easy.
I want to talk about some things that went well, and some things that went poorly, in the hopes that I can learn something from the experience.
One of the easiest things was buying music. I had a bit of a false start: I reached out to a band I like to ask them to make music, and didn’t hear back. Then I reached out to another band I liked, and they quoted me a price which, while totally understandable, was outside of my budget. But then a friend pointed me to Patrick Cornelius. I sent him a “mood board” of tracks that I liked, and he wrote me original music with exactly the sound I was going for, at a price I could afford, and within my timeline. Working with a true professional is wonderful. Next time, I will start buying music and images first thing, to give the maximal possible lead time.
A surprisingly annoying thing was the word list. I started with the word list I had used for Semantle, which I had cobbled together from a variety of Internet sources, but it quickly became clear that this was not going to work: it had too many words that no word game player would like: “nd” (as in 2nd, but without the 2) or “nco” (presumably, an abbreviation for non-commissioned officer, except that would be uppercase, and word games don’t usually allow initialisms). So then I tried the venerable “ENABLE2K” word list, but it was also filled with junk. Oh, unscrupulousnesses, sure, unscrupulousness is a noun, it must be pluralizable. No. Also, as the name implies, it hadn’t been updated in a while. So, no “twerk”, or even “blog”. In the end, I did a ton of work to manually remove thousands of bogus “ness” plurals and add in modern words. Of course, the work is never done: while writing this diary, I thought up a more few missing words, and so I had to go in and add them. There’s nothing more frustrating than a word game that won’t allow a word that you know is real. I have some experience with this: I once sent some raffia to Will Shortz to protest the word’s non-inclusion in Spelling bee.
For Surfwords, it would be equally frustrating for the game to expect you to know an obscure word. When you fail to make a word in Surfwords, the game tells you what you could have done:
But if it shows you a word you didn’t know, you’ll get annoyed. Oh, “pseudocholinesterases”, sure, I definitely should have gone for that. So Surfwords has two word lists: words it expects you to know and words you might know. The first is derived from Google n-grams, but n-grams has a lot of flaws: often a word will be present, but its plural won’t. And some short words are supposedly common, but are actually likely common because they’re typos or OCR errors for more-common words. Finally, some words that I think are commonly known aren’t: several of my testers didn’t know the word “fen”. I readily accept that I have a larger-than-average vocabulary, but I think “fen” is a perfectly ordinary word, and I am baffled that it has turned out to be so obscure.
Today, I’m announcing the release of my word lists. They are licensed as permissively as possible, because I would like them to become standard for word games, to replace the Scrabble word list, which is not freely licensed.
So much for the content. Now, on to the technology. I chose to use the Godot Engine. I’ve been supporting them on Patreon for years, and the price is certainly right. Godot has a decent user experience: it’s got a built-in editor, which is fast and responsive. The built-in debugger is usable, although I miss the ability to evaluate arbitrary code at breakpoints (“wait, what did that function return?”).
Godot has its own programming language, GDScript, which I have been describing as “shitty Python”: it’s a colons-and-indentation syntax with optional static typing. But it doesn’t have function pointers, and you can’t always refer to a class from inside itself.
GDScript is also quite slow. Surfwords stores two sets of words, described above. They’re not exactly big data — the lists total under 200k words, under 2 megabytes. In memory, they’re stored in a trie. But building the trie in GDScript took about 20 seconds on mobile processors. So that had to be fixed. Godot has optional C# support, and the interoperability between GDScript and C# worked fine for me. So my first rewrite of the trie code was in C#. Unfortunately, when it came time to build custom binaries for Android and iOS (stripping out all of the 3d stuff that I wasn’t using to save space), I had a really hard time with the C#.
So I rewrote the loading code again: first, I made a preprocessor in Python to convert the word lists directly to tries (sharing common suffixes) and spit out JSON, and then I wrote code to load the JSON and generate GDScript objects, which Godot can save and load natively. Unfortunately, that was still too slow: each trie node was an object, and the overhead of constructing all of those objects was too high. So my third rewrite stored everything as four large integer arrays (Godot has support for a few types of strongly-typed arrays which are memory-efficient and don’t require boxing). The arrays are: for each trie node, a pointer to its list of children, the number of direct children, a count of total descendants (with the sign bit used to track whether the node can end a word). And for the trie node children, pairs of [letter, child index].
Loading these four arrays could be just a mmap each, although in practice there’s probably a memcpy in there. Finally, it’s fast enough! This has the obvious disadvantage that the code is now incomprehensible gibberish. On reflection, I think I might be able to reduce it to three arrays. But at the beginning of the project, as I wrote my todo list, I wrote a final item: “It doesn’t have to be beautiful code. It has to work.” And the code works now, so I am not going to mess with it to shave a few millisecond off of the game’s load time.
I know that the code works because I have a suite of unit tests. Godot has a third-party unit testing framework, GUT. GUT has a ton of whizzy features, but I mostly just wrote three dozen manual tests for the parts of the game that were easiest to test and hardest to get right: letter selection and failure explanation. I also wrote one exhaustive test for letter selection, which turned up an interesting case that I’ll describe later. But first, I have to explain why letter selection is so tricky.
In the first draft of the game, what’s now called “hard letter selection” was the only setting. This drove testers crazy, because of the problem that I initially called “bash/hue”, but which I now call “hash/hue”, since “bas” is apparently not a common word (what do you mean you’re unfamiliar with ancient Egyptian concepts of the soul? Didn’t you go through an Egyptomania phase as a kid?).
Here, you might be tempted to go for “hash”, since longer words are worth more points. But if you do, you’ll be doomed: none of UZ, UE, QZ, and QE can start any words. So you have to end “has” and start “hue”. This is fair: you can see it coming. But it’s super hard.
Instead, in normal mode, when picking a new letter to add, I consider all four possibilities: - A: prefix + two next letters, then end-of-word - B: prefix + two next letters, continuing - C: prefix + one next letter, then end-of-word, then starting a new word - D: end immediately, then start a new word.
For each of these possibilities, I have to consider each pair of next letters. So, A is really: prefix + left bottom + left middle, prefix + left bottom + right middle , prefix + right bottom + left middle, prefix + right bottom + right middle. Whichever of these choices you make, you need to be able to continue. Case A is easy: any letter can start a word (although there are only three X words in the short list: xenon, xylophone, and xylophones). The other cases are trickier. Here’s one especially tricky one that my exhaustive testing turned up:
What letters should we give here? The user might be thinking of “bail”, or “bails”. But what if they’re thinking of “bailiff”? There’s a problem: if they go for “bail”, the only continuation is “ifs”, so we have to give them a “s”. If they go for “bails”, the only next word must start with either F or X, so the next letter must be one of AEIJLORU (J? oh, fjord, sure). That doesn’t leave room for the terminal F of “bailiff”. So we can’t always support the all of user’s possible choices. But we can support “bail” and “bails”, so we’re still OK.
There’s a related problem with explaining what happened after the user fails: given that we sometimes use random letters, and given that those random letters sometimes make unintended words, how do we tell the user what they should have done? The answer is, frankly, the yuckiest code in Surfwords. It’s totally unprincipled. But it does seem to work, and I’m glad to have the unit tests to prove it.
There are a fair number of things in Godot that don’t work well. Some of them are fixed in the next version, 4.0. I decided not to upgrade yet, because 4.0 is not released, and I think it would be a mistake to depend on pre-release software. Among the issues I hit:
window/stretch/aspect="keep") — I just differentially debugged until it started working.
Speaking of Google Play Games Services: making that work was a total nightmare. Admittedly, some of the fault is mine: in one case, I typoed a method name. But that should have caused Godot to give me an error, and instead, it just silently did nothing. Another time, I wasted a bunch of time because I used the wrong kind of OAuth token. The docs were clear, but the token type was counterintuitive (of course you have to use a “web” token rather than a “Android” token for your Android app). And the docs were very clear:
Note that the Intent returned from the Task must be invoked with Activity.startActivityForResult(Intent, int), so that the identity of the calling package can be established.
Yep, that’s right, it inspects your call stack to figure out your permissions, rather than doing something sensible, like taking permissions as an argument. And it can only inspect that call stack if you use the method that does a callback (even though the callback is not used for anything). That’s quality engineering.
But actually, the design of Play Games Services is evil: it automatically installs a provider, playgamesinitprovider, which asks my users to log in before they even start the game. This is an atrocious user experience: my users don’t know if they care about leaderboards until they play the game. When I remove the provider (using horrible Gradle hackery), logging into Play Games doesn’t work unless the Play Games app is installed, and sometimes it doesn’t seem to prompt the user to install it (sometimes it does — I’m not sure what the difference is).
I think one possible lesson here is that I should have just written my own Play Games Services plugin from scratch to start. And another lesson is that maybe I should have just used dreamlo. But I didn’t want to deal with the identity management, so I didn’t.
Another thing that didn’t work: I wanted to do a cool flowing wave background. I was using Material Maker. I ran into a few minor issues with Material Maker itself — for instance, a slight annoyance which required me to manually hack my shader after export. But it was pretty easy to use, and the model is easy to understand.
The background was going to be really pretty! And working on it was lot of fun, if somewhat time-consuming. Honestly, I was never 100% happy with what I had made. But eventually, I hit the “good enough” point. And that’s where things went wrong. When I exported to Android, I was getting like 30 frames per second on my new-ish phone. So I dug into the generated shader code, and found several micro-optimizations with how gradients were handled. After several hours of messing around, I managed to increase the performance… to 32 frames per second! I scrapped the feature. If I were doing a non-phone game, I would try Material Maker again. But honestly, I think maybe next time I should just find an shader artist to make me a shader.
Speaking of my terrible choices: I decided to make the UI adjust to
the screen size. This led to a bunch of last-second changes as a
playtester requested screen rotation support for tablets. My UI code
was generally terrible. Some of this is due to one of the
aforementioned Godot bugs. Some of it is just that I didn’t have
a good sense of what sorts of UI interactions I would need, and how they
would interact with Godot’s scene system. So I have a lot of special
cases where I ought to have a general system. I spent a few hours debugging
a case where I set
rect_min_size (which doesn’t work:
rect_size is clamped to
rect_min_size). And some of it is because
making the game portion of the UI adjust is really tricky: what size
do users actually want?
But Godot generally doesn’t have great support for
fine-grained manipulation of UI. For instance, I wanted a little
breathing room around the dialog describing “hard endings mode”.
Normally, one would do this by adjusting the margins, or padding, or
something. But the margin settings didn’t work. The only setting
that worked was the
expand_margin_* settings — which move the border
outside of the requested area of the dialog (requiring the dialog to
be manually shrunk to accommodate it).
Playtesters had several useful suggestions. Next time, I’ll definitely start with a color palette in mind, rather than building one as I go. I’ll also think about the tutorial from the beginning; because I added Surfwords’s late in development, it’s not as interactive as I would have liked. I am very glad that I got Surfwords in front of an early tester back before I had done any visual design, since that helped uncover the has/hue problem in time for me to spend a bunch of time fixing it without delaying the release. Special thanks to playtesters Dan Luu, John, Sky, Josh, Praveen, and Rachel for expecially useful feedback, but thanks to all playtesters.
Surfwords is now available for Windows, Mac, and Linux, as well as iOS and Android
For me, Bridger’s narrative-warping powers destroyed Perhaps The Stars as a novel. I don’t think it was the only flaw — but it was the flaw from which the novel could not recover.
The problem with narrative-warping powers is both that it destroys the characters’ agency (even, in Perhaps The Stars, over their own psyches). Narrative-warping powers aren’t the only thing that can do this: sufficient alien mind-control works too. I basically had to pretend that the entire bit about Shards in Worm hadn’t happened so that I could stand to finish it.
It didn’t matter that Mycroft made decisions which lead to his death (twice), because the plot demanded that he return.
To be fair, Mycroft’s second return, in the chapters leading up to and including “No One”, was rather well-written. The way that the prose shifted to include more and more of his distinctive style, leading up to the moment when the fateful words “No one” were uttered, was quite delightful. But I don’t think that impressive prose style is enough to carry the novel; we had already had three volumes of that.
It didn’t matter what arguments Faust made, because he was destined to be Priam. If Faust knew who Mycroft was, how did he not know that he himself was Priam, and Gordian Troy? And if he knew, how did he not expect a Trojan Horse? (For that matter, how did the Trojans not expect a Trojan horse? There’s an earlier Egyptian story, The Taking of Joppa, in which the Egyptians use a similar tactic, and which pre-dates the fall of Troy by hundreds of years. Maybe Priam hadn’t read The Taking of Joppa, which is not an excuse that Faust has available).
So why did Worth The Candle work? Degenerate Cycles (perhaps the bleakest cosmological concept since quantum immortality) showed the GM’s thumb on the scales. It worked because the stakes in Worth The Candle were not whether Juniper would get the good ending. The stakes were whether Wales could come to terms with the loss of his friend. That’s why Fenn’s resurrection wasn’t a cheat. Fenn was resurrected. Arthur wasn’t.
These are stakes that are particularly poignant to me this past week, as I think about the end of Terra Ignota. First, I remember coming upon my copy of Too Like The Lightning when I was cleaning out my brother’s apartment after his death. I didn’t realize it was mine, and we gave it away, and then I had to buy it again to reread in preparation for the release of Perhaps The Stars. And then Tuesday, I was in court fighting my bullshit unreasonable noise ticket (I won), and I remembered the last time I had been in court over some petty bullshit (my landlord dropped my air conditioner out the window and then blamed me for it), and my brother came up to watch, and I know he would have wanted to come up to watch this one too.
I think people will vary in how much the narrative-warping bothers them. If the story had otherwise worked, I think I would might have been willing to treat the entire Homer thing as a symptom of Mycroft’s insanity. But I also was struck by a few more problems that made the whole thing fall apart for me.
Frist, Gordian. Prior to Perhaps The Stars, I sort of assumed that they were a self-improvement cult, like EST or NLP. But actually they’re more like the Bene Gesserit. Or are they? For instance, if they’re so smart, how come they ain’t rich? This is a real question: they’re clearly resource-limited, which is one reason they envy Utopia.
I just started listening to Your Undivided Attention, and the first episode discusses how casinos manipulate players into spending more money. They give an example that Felix Faust would love (my brother would have loved it too):
A good example of this is, I think we talked about this once, that in psycholinguistics if you have two theoretical pain medications, one’s called Pavel, and one’s called Bavel. Which one works faster?
I’m going to leave their answer off, because I replicated this at a very small scale and 4/5 people agreed so and I’m pretty sure that you will too (it helps if you say them out loud). Bouba/Kiki is a more famous example of a similar phenomenon, but nobody is trying to sell you a bouba. The podcast isn’t really about casinos qua casinos. It’s about the tech industry. As Jeff Hammerbacher (of Facebook) noted: “The best minds of my generation are thinking about how to make people click ads.” If Gordian has such a deep level of insight into humanity, then why aren’t they using it to either (a) make money, or (b) become more popular?
(I want to exclude the possibility that the answer is actually the same as Louis Jordan’s original answer: I don’t think 50 hours a week of hard work beats 20 hours a week of Jedi mind tricks).
Also, if Gordian techniques really work, the fact that they are in German wouldn’t stop people from learning them. Like, I understand that in 2012 (when Terra Ignora was initially conceived), machine translation sort of sucked. And I’m sure that it’s very hard to translate deep psychological insight. But if the techniques work well enough to win a war against Utopia, then the incentives are certainly strong enough to get a translation. This article aside, generally useful technologies spread unless something stops them. And German isn’t enough.
One thing that could stop technologies from spreading is patents (especially if they were longer-lasting than our current patents). And this gets to a problem with Terra Ignota as a whole: while it examines religion, history, gender, and government, it seems to treat property as a given. I think it would be uncharitable to say that this is unsurprising from a professor at the University of Chicago, but I do admit that the thought crossed my mind. Two of Kohaku Mardi’s three triggers are about property. But the nature of property is entirely unexamined. What sorts of things can be property? What sort of right is a property right? This is especially hairy in a poly-legal system: I say you’ve trespassed; you say you’re practicing your freedom to roam. I say you’re infringing my eternal patent; you say that patents on mathematics are illegitimate and anyway your patent expired after seventeen years. All this is to say that a land value tax would totally fix the Mitsubishi problem. And some wishy-washy corporate social responsibility thing, which is what they ended up with, would totally not.
One possible explanation for this omission is that the philosophy of property didn’t really get interesting until the 19th century, while Terra Ignota’s philosophical core is in the 17th and 18th centuries. I don’t know if this is actually true: maybe there’s a bunch of interesting stuff in the 18th century, but the 19th has JS Mill, Karl Marx, and Henry George (and arguably William Foster Lloyd). Schelling, in the 20th century, provides another novel argument. But Thomas Carlyle was 19th century, so I’m not sure that the date theory works. Palmer has collaborated with Cory Doctorow, who has certainly written plenty about the nature of property, so I have to admit that I don’t understand this omission.
This also feeds into the weakness of the ending. OK, so Utopia has surrendered — but why doesn’t everyone just quit Utopia and join a new hive, Utopia B, which doesn’t recognize Utopia’s surrender? After all, they’ve already lost their space elevator and given away most of their patents. What’s left that Utopia has that Utopia B doesn’t? Mars itself? But if you believe that Original Utopia owns Mars, then you’re back to geographic nations.
Let me also say that an ending in which J.E.D.D. Mason was successful in reforming the hives was completely unexpected, and rather unsatisfying. What I expected was something more like the ending of The Wave: J.E.D.D. Mason tells everyone that they are fools to follow him no matter his personal charisma, that the idea of salvation is a myth, and that any change that he could impose by fiat would be better imposed through democratic means.
I wonder if this is just a failure to suspend disbelief. Like, I recognize that there’s some special thing that J.E.D.D. Mason has, and that somehow everyone who meets him recognizes. In a real sense, he’s not just one of us. So maybe if I had met him, I, too, would worship. But maybe not. Even if I accept that J.E.D.D. Mason is a god (and I think it’s far more likely that he’s simply the normal, extra-terrestrial-but-not-extra-planar sort of alien and that the entire scene with his death and resurrection was theater; the fact that it is possible to reverse-engineer Bridger’s technology is some evidence for this), that doesn’t mean I have to worship him. I think a lot of people would object to being ruled by an alien god, and I think they would be right to.
I often feel, in philosophical fiction, that my position is not well-represented. This was one problem that I had with Ken Liu’s Reborn. Perhaps The Stars didn’t really have that problem with respect to my political view: my position in the war was that of the the Blacklaw Hiveless: I would have just wanted to be left alone. (I’m actually somewhat sympathetic to OS, but only in the context of a philosophical novel; in actual reality, the unaccountable killers who claim they’re protecting us are stunningly incompetent). And I also understand that my position is unpopular. War is popular. Last Thursday was Veterans Day, and even otherwise sensible people posted bullshit like “thanks for your service” instead of what they ought to have posted, which is “fuck you murderers, I’m not celebrating you.” Which is, somewhat surprisingly, ultimately with J.E.D.D. Mason said.
But my religious views were rather unrepresented: everyone seemed to believe that (a) J.E.D.D. Mason was in fact a god, and (b) that this meant that he was worthy in some way of respect. It seems possible that this was supposed to be unbelievable. That is, whether by questioning Jehovah Mason, we are supposed to question Original Flavor Jehovah, and the logic of theocracy in general. Like, “this is what believing in God looks like from the outside”. The thought experiment carefully separates out a lot of the baggage of religion: there’s no tradition, J.E.D.D. Mason isn’t our creator, and you can’t object to any particular thing that he represents because (until the end), he refuses to tell you what his plans are. I don’t understand why nobody — no Utopian, no Humanist, no Gordian said, “well, imagine that you are some kind of God. So what?”
And “So what?” is, unfortunately, my reaction to the entire denouement of the book.
A few more things:
Whenever I saw Sniper being thwarted, I couldn’t help but imagine Dora the Explorer saying, “Sniper, no sniping!” (She even speaks Spanish, like a good Humanist!). I would have liked to see more of Sniper.
I was extremely surprised to see something named after Aung San Suu Kyi. At least I assume that’s what was going on? That was definitely confusing.
Huxley should have replied to Faust: “Yes, we will bring Distance, but so will you. How much faster will emulated brains run? Reykjavik to Antarctica is already 60ms - but if ems run faster, that would feel like minutes, or hours, or days. And if they run slower, then we waste lifetimes as the sun darkens.”
There were some really good bits: the Odyssey set-piece was fun, Dominic’s return was beautiful, and I enjoyed that Thisbe, being a cinematic sort, had to do a villain speech and that’s what did her in. Oh, and J.E.D.D. Mason’s speech about killings during war is the sort of common sense that is under-appreciated.
Since I last wrote, I have moved my pottery practice from Brickhouse to my basement. This saves me a 45-minute commute, but it means that I have to recycle my own clay and fire my own kiln. I also don’t have as many people to bounce ideas off of. I have found a clay body that I like pretty well: Brown Bear from Kentucky Mudworks. On the rare occasions when I throw, it’s smooth and has good legs. And for handbuilding, it is easy to join and rarely cracks. The only major problem is that it does slump a bit in the kiln. Oh, and it’s brown, which limits my glazing options unless I want to put on a layer of white slip.
Before I left Brickhouse, I started collaborating with John Seroff. I build pieces, and he decorates the surface. This is generally his practice — he has worked with several other artists at Brickhouse as well. So now he comes by my place once a week and we hang out and play with clay. Working with John is tremendously fun. We each admire the other’s work, and neither of us is afraid to take technical or aesthetic risks on a piece. And it’s fun to hang out in the studio and discuss culture and world events. I have to mention this up front because my work with John is a big part of the story of this year.
I have not posted recently because I am a perfectionist, and none of my work is perfect. I keep thinking that the next kiln load will have the perfect piece and then I can finally blog. But my art is improving, and I want to track that. I also keep thinking that I would finish the project of building handles for all of my kitchen cabinets and then post the complete set. But instead, I have mostly been making vases. I am still short three handles, of which two are merely awaiting glaze firing and mounting.
So I am going to start by showing all of the handles that I have completed, and then come back and silently update the post once I finish the last few. Can you spot the one that’s driftwood instead of clay?
Making these animal and human forms was fun, but I sort of burned out a bit on it. So those handles are mostly from late 2018. And a lot of the animals are nonspecific. Oh, it’s a critter, sure. But I think I could get a stronger effect by increasing the mimesis. The hand and foot handles are my favorites, and I think a lot of their power is because they are sculpted from life. The elephant seems to be everyone else’s favorite. I have started to get back to figure sculpting in 2020, but don’t have anything out of the kiln yet.
The bulk of my work lately has been slab-built vases. I can trace two threads of development: first, stacking slabs, and second, polyhedral pieces with tar paper. To start, I want to show my two stacked slab pieces from late 2018. First, I stacked slabs with some overlap.
Then I did the same, but with one vertical strip.
Then I added a head and some arms, to make a finial for one of my fenceposts. Now I just have to make like twelve more finials.
My next idea was to stack without overlap. This is considerably more difficult, because the seams have to be neater. First, I made these two vases that love each other very much. John Seroff did the carving.
Then I made a taller vase with the same general concept. It barely fit in my kiln.
I also made a lidded jar. I actually made two, but the first one was too squat and the glaze didn’t come out the way I wanted it, so I rebuilt it. This one is about 16 inches tall. And of course now that I’m looking at the photo, I see a crack, probably where I inserted the dart to bulge that section. I may have to make a third one. With a less shiny black glaze.
The end, for now, of that line of development is this nine-necked vase. It was in the last kiln of 2019, or, perhaps, the first kiln of 2020, mid-firing as the clock struck midnight. It will be shown at Back to the Table, an exhibit of tableware at the Plaxall Gallery in Long Island City.
I had a really hard time visualizing how the base of this was going to work, and in the end, I had to add that extra foot. I think part of the problem is that building up at an angle tends to cause sagging, so I started out straighter than I had planned. I’m pretty happy with the glaze, especially the mossy green. But I think that this is about the last piece in this line that I will make for a while.
The second thread started with a funerary urn that I made. I wanted something monolithic and stark, and it needed to be fairly large (about one cubic inch per pre-cremation pound of body-weight). So I cut some tar paper forms, and used them to hold up slabs. The result was not amazing, but it definitely looks sufficiently bleak.
John had been watching me grow as a potter, and asked me if I wanted to collaborate. I built a teapot using tar paper templates, and one of my first animal heads. I was going for a fox, but I was not yet strong enough to get there. So I declared that the result was a coyote. The body has pentagonal symmetry. This is a good choice for me, because my work is always a little sloppy. A sloppy square is obviously sloppy. A sloppy hexagon has non-parallel opposing sides. But a sloppy pentagon is basically fine. John’s photo:
Then I got to thinking about what else I could make with this technique. I realized that pottery rarely has what origami artists call “valley folds.” You can get mountain folds by paddling a thrown piece, or by joining slabs. But valley folds require a bit more thought, because they are hard to press together to get a good joint. So here is my first piece with valley folds. It’s foreshortened in this photo and since I gave it away I can’t reshoot — it’s actually quite a bit slimmer than the photo implies:
John next suggested that we do a series, and the first complete set that came to mind was the platonic solids. So I built some platonic solid teapots, and John decorated them. His process is slow and he likes to work with a wide variety of people, so I think I ended up making the pieces a bit faster than they could get decorated. So only two and a half of the five are done (John’s photos; the last one needs to be glazed):
The logical conclusion of this was to go into Blender and design a stupidly complex 36-piece vase, and then have John decorate it. So that is what I did. John’s photo:
It soon became clear that the tar paper is really only necessary for the dead-flat surfaces. By instead bellying out the slab as one would for a pinch pot, I was able to assemble large vertical surfaces. One of the first of these was a nudibranch-inspired vase. This one doesn’t really have true valley folds, as the “wings” are accessible from both sides, but it does use vertically-joined slabs.
Finally, we reach the point where the two threads converge: a piece with multiple necks, bulged vertical slab sides, and valley folds: Cathedral Vase I. Also, I now have enough work that I need to think of names. I am very happy with the glaze on this one even though the teal-and-orange combination is a bit of a cliche.
I say Cathedral Vase I, as John is working on the surface of II now. Hopefully, I will manage to file another update before 2021. No promises.
My answer was that I don’t know how to solve the unwanted communication (spam, brigading, etc) problem.
I don’t think anyone else does, and I think most people are unaware of how hard it is. That’s because it’s a problem of mechanism design in addition to being a problem of engineering. And most people are just not devious enough to design mechanisms that are resistent to adversarial usage. A while ago, I brought the issue up on the mastodon issue tracker, and did not get much traction.
Someone recently proposed an option to diable replies on Mastodon posts. This is, abstractly, not a terrible idea: I don’t have comments on my blog, and I could imagine making certain social media posts where I don’t want comments. There was even the really neat follow-up idea of “no replies except for people who are @mentioned”. But what does “no replies” mean? To understand this, you need to know a little bit about how Mastodon (or, more precisely, the underlying ActivityPub standard) works:
There are a number of servers (e.g. mastodon.social, oulipo.social, etc), and each user belongs to one. If I post an “activity” (roughly, a tweet), it goes into my public outbox, and anyone who has read access to my outbox can read it. A reply is just an activity with the inReplyTo field set. If you post a reply, it (a) goes into your public outbox, and (b) goes to my inbox on my server. My server might, when receiving a reply, forward it on to the folks who saw the original message (that is, my followers, who would otherwise not notice it in your public outbox unless they were also following you).
So things that disabling replies could mean include:
All three things of these things are reasonable to want, but the third only works for “well-behaved” participants. I put “well-behaved” in quotes here, because of course if someone says something mean or false about me and then sets it to no-reply, I might well wish to override the “no-reply” setting so that at least my followers can see my rebuttal. So it was quite surprising to me to see, here, someone suggesting requiring (“must”, in RFC-speak) the third, unenforceable option.
I also saw a suggestion to implement a proof of work system, Hashcash, to reduce the frequency of direct harassment. This seems extremely unlikely to be useful for this, because Hashcash is intended to stop large numbers of messages, but even one message per sender is sufficient to harrass people (the most common risk is one message per person from a thousand people). Also, Bitcoin has shown us that there are something like seven orders of magnitude between the hash rate of an ASIC and that of a typical CPU. This makes setting a correct Hashcash cost impossible. A memory-hard hash function might reduce this gap, but probably not by enough. Also, most “clients” are actually someone else’s server, meaning that the effect would not be felt by the message sender directly.
I wish I knew of better solutions, but at least I am glad that I don’t falsely believe that good there are solutions out there that nobody has the will to implement. That would be depressing.
Since last time I wrote, I’ve made a few more pieces. Note: pieces are not in chronological order. A few technical details are at the end.
We’ll start with a recent one that I’m proud of:
Yep, it’s a vase with rats coming out of it. The black glaze is Marilee’s Lava with 7% Mason 6666 black stain, which I put together myself. I have now manufactured a few glazes, including this; a lichen glaze which slid so dramatically that I haven’t dared to use it on a real piece; and a supposedly mint green which actually came out so much more matte than the reference photo that I suspect I must have fucked up somehow. I’ve also played with oxides some and gotten results varying from unnoticeable to garish to awesome. I’m not sure how I feel about a process with such high-variance results but I’ll probably keep exploring anyway.
Here’s the first piece I made that I still like:
Probably I’ll stop liking it once I improve further. I enjoy the texture, but I wish it were more precise. I still don’t really know how to get precise lines — somehow, even with a ruler, it always comes out messy. So I’ve been trying to learn to make pieces that embrace the mess.
I also made vases as holiday presents for everyone on my team. The project we were working on is called The Aleph (after the Borges story), so all of the vases have Alephs on them. This is my favorite:
One co-worker in particular got excited about the pottery, so I made her a casserole:
My cats insist on photobombing my pottery photos. This is the rare Mutex photobomb — it’s usually Semaphore. The texture on the casserole was made with an old daisy wheel. The piece is really quite large — it cooks^Hholds almost 16 lbs of cat. I used S762 kitchenware clay, a buff stoneware with fine grog. It reportedly goes happily into a cold oven without cracking, so I guess the body lives up to its name. Unfortunately, most of the studio’s glazes, and some commercial glazes come out muddy or crazed on this body, so I’m pretty limited in where I’m willing to use it.
One piece I made out of it was my second orcish teapot. But before I get to the second one, I have to show you the first:
The body here has exactly the hue I wanted, but about two shades too light. That’s significantly better than some other possible outcomes: the glaze combination I used is a bright green celadon on top of a chameleonic red-brown. Too little green, and you get mud; too much and you get blobs of snot.
Other folks insist on calling this a warthog teapot, but what does a warthog need with a teapot? Maybe the orcs used warthog tusks to make it. Another potter at my studio had been doing a bunch of stuff with spikes, and I was a bit inspired. Peter’s spikes are broader than mine, and straight rather than bent. He throws them on the wheel, which I did for these and for my doorknob, but which I’ve since given up: handbuilding them is faster for me. And it’s easier to get close-to-identical copies, at least at my skill level.
I like the idea of a second draft of a piece, and wish I had the patience to do it more often. The casserole above is actually a second draft: the first one was too thin and ended up cracking. The second one has straighter walls and better texture, and I think the handles are nicer too.
Here’s that second orcish teapot:
The second orcish teapot did not come out the way I had planned, but I am not disappointed, because it’s pretty metal. Literally: the black glaze is primarily black copper oxide, and the horns have some red iron oxide stirred into the clear. Copper oxide usually produces green, and I had hoped to reproduce something like the original glaze by adding a bit of copper oxide to a not-green-enough glaze. You can see the normal copper green where the oxide has bled into the white interior glaze. That’s not the color I wanted on the outside either, but it’s attractive if not particularly orcish.
Britt suggests adding bentonite to oxides to get a more even application. Brickhouse’s studio oxide washes don’t have this, so they settle out very rapidly, making it hard to get an even application. I made up a copper oxide wash with some methylcellulose (AKA “CMC gum”), which I have used in the kitchen in the past. It burns off in the kiln, but suspends the oxide enough to get an evener application. However, I think I might have more oxide in this wash than I really want. Copper oxide is quite corrosive: one little drop of the oxide glaze slid off my piece and ruined a kiln shelf.
I know that the standard approach here is to glaze a bunch of test tiles, and not glaze the final piece until the test tiles are done, but the turnaround time on test tiles can be up to three weeks, so I often test on finished pieces. I do take glaze notes inside a crappy webapp I threw together, which at least helps me avoid making the same mistake twice.
All of these horns got me excited about animal forms, so I went back to handbuilding. The rat vase was the first thing I made with animal faces. Then I made a skunk mug:
I have to admit that this one, too, was partially inspired by [Peter]((https://www.instagram.com/potteraguero/)’s work — he had been doing “eat, fart, love” mugs (“I don’t pray”, he explains). So when I made a skunk mug, the “eat, spray, love” slogan came to me in a flash. The face has kind of a funny shape, but I think it’s not too far from what a real skunk’s face looks like. It’s just that our mental image of a skunk has been warped by Pepé Le Pew.
Another thing that inspired me to make animal forms was this Pikamug:
Once I had made this for one cousin, I knew I would have to make something for his sister, and their mom suggested Ponyta:
One rule I have is that everything I make has to be at least somewhat functional. This constraint is somewhat arbitrary — just about anything hollow could be a vase. But it does mean that I am forced to pay attention to how a piece could be used, and think about smoothness and weight. I should probably institute a “no vases” rule at some point, since I basically never use a vase for anything. Maybe I’ll ban teapots too, except that I have yet to make a teapot that’s technically even base-level competent yet. For instance, the first orcish teapot doesn’t pour very well because the glaze covered up the holes. The second’s spout is too low. So I may have to make a few more of those.
Here’s a completely boring bowl where I like the glaze; it reminds me of a night sky:
The waiting is a real struggle: the most recent work I can show is some jars that I threw in late December, and then sculpted the lids of in January, and then glazed a few weeks ago, and just got out of the kiln. In fact, the third pot’s lid didn’t look great after glaze firing, so I’ve reglazed it and am refiring it. Here are the remaining two jars: a French bulldog, and a demon:
This delay means I can’t show you my alligator teapot or my Baba Yaga’s hut teapot, or my seed pod vase, or my second doorknob, which is completely different than the first one. So I guess I’ll have to post again.
I’m working at Brickhouse Ceramic Arts Center in Long Island City. My primary clay body is the studio’s brown stoneware, but I’ve also used Laguna B-Mix and S762 from Ceramics Supply. The studio fires at Cone 6 in oxidation. I use the studio’s glazes, as well as some commercial glazes from Amaco, Mayco, Coyote, and Potter’s Choice. If you like any of the glazes above and want more details, let me know and I’ll happily share.
Reiner Knizia is one of my favorite board game designers. One thing I really admire is that he’s willing to noodle on a theme (e.g. his four early tile-laying games) until he’s satisfied with it. He’s gone through a few versions of Lost Cities, including Keltis: Das Kartenspiel (hereinafter, “Keltis” — there are a few other Keltis variants, but this is the one I’ve been playing.
First, I’ll briefly explain the rules of Lost Cities, and then the changes in Keltis. Then I’ll explain why these changes produce lower variance. Finally, I’ll explain why I’ve been thinking about this.
The Lost Cities deck consists of twelve cards in each of five suits. Nine cards per suit are numbered 2-10; the rest are identical “investment” cards, which multiply a player’s score in that suit. Each player has a hand of eight cards. On their turn, they either play or discard. Plays and discards are both by suit. After playing, they draw either from the deck or any discard pile. As soon as the last card is taken from the deck, the game ends. There are two things that make the game interesting: 1. You can only play cards in each suit in-order: first any investment cards, then the numbers in ascending order (with gaps permitted). 2. If you don’t play any cards in a suit, you get zero points for that suit. Otherwise, your score in a suit is negative twenty points plus the sum of the values of the cards played in that suit. This generally means that you only open a suit if you’re pretty sure you’re going to make 20 points in it.
Keltis has a few differences from Lost Cities, but from our perspective, the most important ones are: 1. The value of each card is approximately the same. Cards still have numbers, but the point value for a suit depends only on the number of cards in that suit. 2. You can play a suit in either ascending or descending order.
Here’s how this leads to lower variance: In Lost Cities, opening with a hand of, say, the 9 and 10 of each of four suits is somewhat unlucky. You don’t want to discard anything, because your opponent will snap it up from the discard pile. But you also don’t particularly want to open a suit, because you’re guaranteed to lose a point on it. In general, getting cards in the wrong order can turn what would be a good suit bad. There’s nothing more frustrating than ending the game with the 7-8-9 of a suit and missing six points just because of bad timing. In Keltis, that would be an acceptable opening hand, since the 10s are all immediately playable.
And in Lost Cities, if you have 3-4-6 in a suit (13 points already), you’ll surely open that suit since you expect to get approximately two of the 7-8-9-10 cards. But in a quarter of games you’ll get just one, and in a quarter of games you’ll get three. And it’s possible to get zero or all four. In Keltis, this is approximately true as well (the card distribution is a bit different, so not exactly). But in Keltis, this will result in a swing of a few points — not 30 points (or more with investment cards).
It’s always nice to have data to back up a theory, so I found this page. It claims that, in fact, Keltis (listed as “Keltis Card”) is lower-variance. Well, more precisely, it makes a more-complicated claim about Elo ratings, but I think the effect is the same.
Subjectively, I think Lost Cities might be a slightly more fun game, and this says bad things about me. There’s a real excitement as things come down to the wire: will I suck out and get that blue ten (which is now worth 40 because of investments), or won’t I? That part of the game is pure gambling, and while it’s fun, it’s not something I feel proud of enjoying. But at least I’m not alone: Keltis gets 6.7 on BGG, while Lost Cities gets 7.1.
I have been thinking about this because I just had opposite feedback about dynamic range in two of my prototypes. In Sekhmet, the range was considered too low: a given tile could score between 1/2 and 2 points. In Banshee, the tile values are between 1 and 10, and the player who happened to draw the 10-point tiles was very likely to be able to use them and win. Similar problems don’t necessarily demand parallel solutions, so while I’m going to replace all the 1s with 2s in the next test of Banshee, I’ll probably fix Banshee by completely replacing the way that tiles score — and in the process, maybe reduce the range.