<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Occasional Thoughts]]></title>
  <link href="https://novalis.org/blog/atom.xml" rel="self" />
  <link href="https://novalis.org/blog" />
  <updated>2025-12-18T12:00:44.631609-05:00</updated>
  <id>https://novalis.org/blog</id>
  <author>
    <name><![CDATA[David Turner]]></name>
    <email><![CDATA[novalis@novalis.org]]></email>
  </author>


  <entry>
    <title type="html"><![CDATA[Is it a joke?]]></title>
    <link href="https://novalis.org/blog/2025-11-06-is-it-a-joke.html"/>
    <published>2025-11-06T09:12:06.168405-05:00</published>
    <updated>2025-12-18T12:00:35.197069-05:00</updated>
    <id>https://novalis.org/blog/2025-11-06-is-it-a-joke.html</id>
    <content type="html"><![CDATA[<p>I listen to a lot of podcasts, because I can listen while making art
for <a href="https://highmountainabbey.com">the diorama-based game</a> I am
working on. I discovered the podcast
<a href="https://www.imaginaryadvice.com/">Imaginary Advice</a> because
MetaFilter linked to
<a href="https://soundcloud.com/ross-sutherland/109-a-christmas-carol-snes-1993">its episode on the SNES game A Christmas Carol</a>.
That’s a game that doesn’t exist – Ross Sutherland just made it up,
and then recorded a whole podcast episode about it. The episode
doesn’t acknowledge, at any point, that the game is fake. It’s
hilarious.</p>
<p>Sometimes I can’t tell whether something is a joke or not. I couldn’t
tell whether <a href="https://semantle.com">Semantle</a> was a joke until I started getting fan mail.
And speaking of podcasts, apparently I’m not the only one with this
problem. I just heard on
<a href="https://99percentinvisible.org/episode/hl-06-segagaga/">99% Invisible</a>
that when Tez Okano pitched Sega on Segagaga, one of the last
Dreamcast games, the execs thought his entire pitch was a joke, so he
had to pitch it again.</p>
<p>I’m not as good a writer as Ross Sutherland.  That’s why a lot of
people didn’t see the humor in <a href="https://novalis.org/blog/2025-10-27-blue-prince-1989.html">my post about the (fictional) 1989
Blue Prince</a>,
and thought I meant to actually fool people.  Fooling people was
really an accident – I just put in a little bit too much work on the
visuals. Actually, I meant the commentary as a serious critique: Blue
Prince has a very high busywork-to-puzzle ratio, and this is its
weakest point (also see
<a href="https://novalis.org/blog/2018-02-26-variance-and-dynamic-range-in-lost-cities-and-keltis.html">my previous note on gambling</a>;
Blue Prince literally has slot machines, and it’s sometimes optimal to
use them). But there is a lot of puzzle there too – several people
assumed that the floppy disk flipping bit referred to one specific
room in the actual Blue Prince. Nope. I hadn’t gotten to that area at
the time I wrote the post, and I still haven’t solved that
puzzle. Instead, I was inspired by learning about Karateka’s
upside-down disk Easter egg on
<a href="https://lateralcast.com/episodes/148/">Lateral</a>. Yep, another
podcast.</p>
<p>Sometimes I feel like I’m wasting my time listening to all these
podcasts, but I was heartened to see that Adrian Tchaikovsky mentioned
that his Philosopher Tyrants series was inspired by
<a href="http://empirepoduk.com/">Empire</a> and
<a href="https://www.patreon.com/Revolutions">Revolutions</a>. It’s among
Tchaikovsky’s best work, and I can’t wait for the next one.  And
nobody can accuse Tchaikovsky of unproductivity. To bring it
full-circle, science fiction also inspires podcasts; after ten seasons
on actual historical revolutions, and after a two-year hiatus, the
Revolutions podcast returned with a season on the Martian Revolution
of 2247, presented totally straight-faced.</p>
<p>Two more notes that didn’t fit anywhere else:</p>
<ol>
<li><p>I actually used
<a href="https://github.com/Swordfish90/cool-retro-term">cool-retro-term</a>, not
RetroArch, which is why the font isn’t quite right. I thought about
using RetroArch but it looked like it was good to be a hassle to get
an Apple II running, plus then I would have had to maybe write
Applesoft BASIC.  Anyway, I decided to settle for good enough.  So
that’s why the font isn’t quite historically accurate.</p></li>
<li><p>I really enjoyed reading <a href="https://news.ycombinator.com/item?id=45824252">Egypt Urnash’s IF-style Blue Prince
scene</a>. I did consider
whether an IF Blue Prince would be better, but I think seeing the map
is really useful, and while you could incorporate a map into an IF
game (as <a href="https://ifdb.org/viewgame?id=aearuuxv83plclpl">Counterfeit Monkey</a>
does), it sort of strains the medium a bit.</p></li>
</ol>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Blue Prince (1989)]]></title>
    <link href="https://novalis.org/blog/2025-10-27-blue-prince-1989.html"/>
    <published>2025-10-27T14:22:54.133162-04:00</published>
    <updated>2025-10-27T14:30:41.284743-04:00</updated>
    <id>https://novalis.org/blog/2025-10-27-blue-prince-1989.html</id>
    <content type="html"><![CDATA[<p>In 1989, I turned nine.  For my birthday, my dad got me a copy of Blue
Prince for the Apple //e, which had been released earlier that year.
I fell in love with it, spending hours plumbing its secrets. So when
the remake was released this year, I decided to try out the new
version.  On reflection, I think I actually prefer the original.  You
can see a bit of gameplay that I recorded using RetroArch:</p>
<video controls="" height="688" loop="" width="688">
<source src="https://novalis.org/blog/images/blueprince.mp4" type="video/mp4"/>
A video showing a green-on-black screen, with the distortions typical
of a 1980s CRT. Everything is ASCII-art. First, a Blue Prince
Logo. Then the fountain and 'Day 13' and then the manor scrolls into
view. The manor moves to the left of the screen, and the entrance
hall's text description appears to the right. Next, a drafting screen,
showing how the player would select among the Wine Cellar, Pump Room,
and Drawing Room. The player selects the Pump Room, and, after
showing the description of the room, a diagram of the pump
configuration.
</video>
<p>Here are some things I like about the original:</p>
<ol>
<li><p>This is a bit of a spoiler, but one puzzle required you to reach an
object on the ceiling of one of the rooms.  To solve it, you had to
take the game’s actual floppy disk out of the drive and put it in
upside-down, which turned the whole room upside down. It’s perhaps the
best lateral-thinking puzzle in any game I’ve ever
played. (Admittedly, I didn’t fully solve it myself – my next-door
neighbor Stephen, who was year or two older, had to give me a hint).
Of course, the 2025 version can’t have that puzzle (well, I guess it
could use a laptop’s accelerometer, but it might be a bit hard to turn
a desktop computer upside-down), and the replacement, which I won’t
spoil, isn’t as good.</p></li>
<li><p>Rooms directly described their contents. So the Security Room’s
feature which tells you what objects you missed was much less
necessary (it’s still there because of spreading, but you only need it
later in the game). Does someone actually enjoy using the metal
detector to hunt around every room for coins, at least after the first
time?</p></li>
<li><p>The game was much quicker to play. Instead of having to wander
around a (beautifully rendered, admittedly) 3d space in order to
explore a room, you could just read a few lines of text, and press an
arrow key.  The keyboard is, of course, <a href="https://danluu.com/keyboard-latency/">wonderfully
responsive</a>. This is my main
complaint with the 2025 remake: why use all of this 3d technology just
to make the game take longer to play?</p></li>
</ol>
<p>Anyway, if you bounced off the Blue Prince remake because of the slow
pace, do yourself a favor and try the 1989 version.  Once you get used
to the minimalist aesthetic, you might like it better. The floppy-disk
image is available on any of the usual sites, and it can be played on an
Apple emulator.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Responses to the Hacker News comment on Six Mistakes]]></title>
    <link href="https://novalis.org/blog/2025-03-26-responses-to-the-hacker-news-comment-on-six-mistakes.html"/>
    <published>2025-03-26T13:03:38.170121-04:00</published>
    <updated>2025-03-26T13:07:29.010332-04:00</updated>
    <id>https://novalis.org/blog/2025-03-26-responses-to-the-hacker-news-comment-on-six-mistakes.html</id>
    <content type="html"><![CDATA[<p>Recently, <a href="https://novalis.org/blog/2025-03-13-six-mistakes-i-made-and-one-i-avoided.html">I discussed some mistakes</a> I made working on my game.
I still don’t have a Hacker News account, because I still wish to
waste less time on the Internet.  Fortunately, I have very good
friends who post sometimes my blog posts
<a href="https://news.ycombinator.com/item?id=43364368">there</a>.  The friend who submitted this post, MJD, is <a href="https://mathstodon.xyz/@mjd/114223189381583430">looking for a
job</a>.  He’s brilliant
and empathetic and you should hire him.</p>
<p>Anyway, here are some responses to the Hacker News comments:</p>
<h1>Veneer</h1>
<p>I arbitrarily picked the number six for the number of mistakes, but
I’ve actually made way more than that.  For instance, when I got my
veneer, what I should have done is asked my dad how to use it.  He’s a
real woodworker, and undoubtedly the advice he would have given would
have matched that of
<a href="https://news.ycombinator.com/item?id=43398933">mauvehaus</a> on HN: a
complicated gluing and clamping procedure for a tricky material.</p>
<p>I also probably could have gotten away without gluing the veneer at
all, but I was worried about it wiggling around while trying to
position things on it.</p>
<h1>Non-Steam versions</h1>
<p>Someone asked if I would release High Mountain Abbey anywhere other
than Steam. Definitely – it’s the right thing to do, it’s not much
more hassle, and maybe it’ll get me some more sales.  I’ve created <a href="https://novalis-dmt.itch.io/high-mountain-abbey">an
entry on Itch</a>. Note
that the price may change – I have very little idea how to price
games.</p>
<h1>Wild walls</h1>
<p><a href="https://news.ycombinator.com/item?id=43396702">gmueckl</a> made two
suggestions:</p>
<p>His first was “wild walls”, a film production technique where walls
can be removed.  I’ve consider this, but:</p>
<ol>
<li><p>This screws up the lighting much more than holes. I think film has
really bright lights, which means any light leakage through a wild
wall would be minimal.  But getting that kind of lighting into a tiny
diorama is tricky.</p></li>
<li><p>If my dioramas were really precise, there wouldn’t be gaps between
the wild wall and the rest of the set.  But they’re not. It’s
particularly tricky to avoid gaps in the cave walls, which are not at
all flat.</p></li>
<li><p>I actually do this where it’s feasible.  For instance, in one room,
the floor is “wild” – the rest of the walls lift up.  Rocks hide the
seam.  In another, the ceiling lifts off.  And in a third, the side
wall is wild, and I hide the edges with some columns.</p></li>
</ol>
<h1>Git</h1>
<p>User gmueckl’s second suggestion was to use a SCM other than <code>git</code>.
If I were collaborating with other devs using this SCM, I would worry
about what was best for collaboration, or maybe, most space- and
bandwidth-efficient.  But I’m honestly mostly using a SCM because it’s
how I’m used to building software.  I almost never need to look at
history.  And in the unlikely even that my primary dev machine dies,
and I need to clone a few hundred gigs to restore it, I can afford to
wait a few hours or even a day – I’ll just spend the time working on
some other part of the game.</p>
<p>The big advantage of <code>git</code> is that I know it really, really well –
I’ve even contributed a little code to <code>git</code> myself.</p>
<p>Someone else suggested using <code>git-lfs</code>. This would, in theory, help –
I wouldn’t need to download all of the raw assets if all I need is the
game portion.  But I can already do that with <a href="https://git-scm.com/docs/partial-clone">partial
clones</a>. Github has some
better pricing for LFS storage, but (a) I prefer to avoid Github
because I think monocultures are bad for the web, and (b) most of my
files aren’t actually large – it’s just that there’s a large number
of moderately-large files (about 20k files so far) and (c) I don’t
trust git-lfs because of <a href="https://github.com/git-lfs/git-lfs/issues/197">their treatment of a bug report I
filed</a>.  I recognize
that this last one might be somewhat petty – after all, lots of
people successfully use git-lfs.  But I get frustrated by having my
bug reports closed <a href="https://www.jwz.org/doc/cadt.html">without anyone checking if they’re still
bugs</a>.</p>
<h1>Qualifications</h1>
<p>Another commenter wrote:</p>
<blockquote>
<p>Yeah, this plus the apparent lack-of-planning regarding lenses &amp;
  field of view make me wonder if OP had any of the background they
   should have had in stop-motion animation?”</p>
</blockquote>
<p>This one is easy to answer: absolutely not!  Instead, I have
relentless enthusiasm and a willingness to make mistakes.  It’s
working out well so far!</p>
<p>I’m a mostly self-taught programmer.  This has given me the
arrogance to believe that I can do almost anything.</p>
<p>Dioramas weren’t my first choice for art.  They were my third choice,
after finding two illustrators who failed to work out.  I think if I
had had the choice, I would have rather signed on to this particular
game as just a puzzle designer and programmer, leaving the art and
story to someone else.  But that didn’t happen, so I’m muddling
through. I think the results speak for themselves: nearly everyone
I’ve shown this game thinks it looks cool.</p>
<p>I say “do almost anything” above, because there are at least two
things I know I can’t do: illustrations and music.  My inability to
illustrate is why I’m using dioramas.  For music, finding a composer
has been really tough – between a small budget and rather
idosyncratic tastes, I don’t have a lot of options.  I’ve actually got
a composer under contract, but I don’t want to say more until I’ve got
at least a few rough mixes in hand.</p>
<p>Anyway, the point of the post is: you can make a lot of mistakes and
still succeed in making a cool game.</p>
<h1>The process</h1>
<p>A few folks mentioned enjoying learning about my process.  For you,
here are two videos:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=AYT1aSpAYwE">Kerning, the hard way</a></li>
<li><a href="https://www.youtube.com/watch?v=Okw63SJDIlE">Making books for High Mountain Abbey</a></li>
</ul>
<p>Speaking of comments, someone at a meetup suggested that I should film
my work process, because everyone likes YouTube craft videos.  It’s
easy, he said.  Well, no, it’s not easy – it’s yet another craft.</p>
<p>That kerning video, for instance, omits the bit where I fix up the
kerning after taking a photo, because it turns out that it’s not quite
right for the aspect ratio Steam wants.  And the books video took me
three tries, because the first time, my hands ended up out of the
frame, and the second time, the hands were out-of-focus because the
camera (that is, my phone) preferred to focus on the background.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Six mistakes I made and one I avoided]]></title>
    <link href="https://novalis.org/blog/2025-03-13-six-mistakes-i-made-and-one-i-avoided.html"/>
    <published>2025-03-13T18:23:35.777041-04:00</published>
    <updated>2025-03-20T10:20:16.187162-04:00</updated>
    <id>https://novalis.org/blog/2025-03-13-six-mistakes-i-made-and-one-i-avoided.html</id>
    <content type="html"><![CDATA[<p>I’m still working on my point-and-click puzzle game made from dioramas.</p>
<p>Often when you watch videos of people doing crafts on the internet,
they’re people who have been doing it for years.  They don’t make
mistakes, or if they do, they don’t really show them to you.  I
haven’t been doing any of these crafts for years.  So I’ve made lots
of mistakes, and I want to show them to you, so you don’t get the
impression that this is easy.</p>
<p>Before you read further: Please wishlist <a href="https://store.steampowered.com/app/3469350/High_Mountain_Abbey/">High Mountain Abbey on Steam</a>.</p>
<h2>1. Tapestries</h2>
<p>Machine-woven tapestries (which I’m using for rugs) are very
low-res – 14ppi (which is, at my scale, 14 pixels per foot, which is
not very realistic, but it’s probably forgivable).  The way they work
is really neat (but requires some pre-planning): they have six colors
of yarn: red, green, yellow, blue, white, and black. Depending on the
color of each pixel of your image, a different color ends up on top.
I wish I had known about this in advance, so that I could have
designed my images to do my own dithering, but this doesn’t seem to be
a supported mode of operation for the services I found.  I guess
palletized pixel work is a dying art.</p>
<p><img alt="Hallway" src="https://novalis.org/blog/images/carpet.jpg" title='A close-up of a "carpet", showing some poor dithering choices.  Part of a hallway with a flagstone floor and William Morris wallpaper.'/></p>
<h2>2. Git hosting</h2>
<p>I quickly learned that git hosting was going to be an expense.  I
started with Gitlab’s free tier, but that has a limit of 10GB.  I
would have liked to give them money, but their pricing for additional
storage is $0.50/GB/mo, which is outrageous – S3 charges
$0.023/GB/mo, which is less than a twentieth of the price.  I assume
that Gitlab charges such high prices to account for the data transfer
costs, but my data is basically write-only, so it’s a bad deal for me.</p>
<p>With seven rooms photographed so far, my repo right now is 53 GB,
since I’m storing all of the photos that go into each focus-stack, as
well as the raw (xcf) versions of each shot so that I can edit and
color-correct without repeated JPEG compression.  I ended up just
running my own Gitlab on a cheap Hetzner VPS, which was trivial to set
up, and not very expensive.  It probably has less reliability than
Gitlab’s service, but I have Hetzner’s backups and also my own
desktop’s backups, so I am not too worried.</p>
<h2>3. Animation</h2>
<p><a href="https://yosefk.com/blog/the-state-of-ai-for-hand-drawn-animation-inbetweening.html">Yossi warned me about this</a>, but I didn’t listen: AI isn’t actually
good at tweening.  It worked really well when I just had wool roving moving
around:</p>
<video controls="" height="720" loop="" width="928">
<source src="https://novalis.org/blog/images/wool-animation-2.mp4" type="video/mp4"/>
    A video of a weird machine: on the right, a bronze circular frame has
    an inner rim made of blue wool roving.  Around the frame are three
    knobs.  When a knob is clicked, the wool roving retracts around
    the circle before growing again to its original shape.  Inside the
    circle, there are seven dots which move around, and on the left is
    a hopper with eleven red wool balls.  A ball falls into one of two
    wooden boxes as the wool animation runs.
</video>
<p>But then I tried to use it to tween a solid object rotating 60 degrees:</p>
<video controls="" height="126" loop="" width="104">
<source src="https://novalis.org/blog/images/bad-rife-rotation.mp4" type="video/mp4"/>
    A chartreuse needle-felted dial turns on a gray felt background. There's
    blurring and warping.
</video>
<p>This is surprisingly bad.  But I thought: maybe it’s just that
rotation is bad?  So I tried with a door sliding down. Actually I
tried it with a door sliding up, but I didn’t save the result, and
then when I went to re-create it for this blog post, the images ended
up in reverse order, so I guess it’s sliding down now.  I’m not
counting this as one of my six mistakes – you get that one for free.</p>
<video controls="" height="640" loop="" width="382">
<source src="https://novalis.org/blog/images/door.mp4" type="video/mp4"/>
    A door made out of horizontal slides up.  There is significant
    blurring.
</video>
<p>Admittedly, the motion on the door is a bit shaky (that’s the joy of
stop-motion), but I would have expected better.  I guess the wool only
worked because it was already, well, wooly.  So I will have to live
with a low framerate on most of my animations.</p>
<p>I can sometimes use some trickery to improve the framerate.  For the
animation of something rotating, what I actually do is have Godot
rotate each frame while fading in the next frame.  I still have a bit
of the stop-motion look, since the object moves unevenly (and it’s
made out of felt, so it wiggles too).  And I still have decent
shading, since the keyframes are photographed in situ with the correct
light.</p>
<h2>4. Shooting in confined spaces</h2>
<p>I had thought that I could do all of the photography by placing the
camera inside the dioramas.  But for narrow hallways, this doesn’t
work – the camera ends up too close to the wall to get a wide enough shot.</p>
<p>So I ended up doing something a little weird: I cut holes in the
walls, and shot the side views from the outside, through the holes.
Then, to make the insides look right, I put paintings or lamps or other
decorations over the holes.</p>
<p><img alt="Hole in the wall" src="https://novalis.org/blog/images/hole-in-the-wall.jpg" title="A photo of a diorama from the outside.  The bottom half shows the outside of a foamcore wall, which has a tiny square hole.  The top looks over the wall, into the diorama, at the top of a wooden door."/></p>
<p>That hole fits a camera lens – I’m still suffering from my camera’s
narrow field of view, but at least you can see the door.  And when
I’m shooting from the inside of the diorama, I pop a lamp into the
hole and you would never know it’s there.</p>
<h2>5. Steam marketing</h2>
<p>I put up my <a href="https://novalis.org/blog/2024-10-18-building-a-game-with-the-real-engine.html">previous blog post</a>, which got some traction on Hacker
News. Great, I thought, everyone will want to buy my game!  But I
forgot a step: first, people have to learn about the game, and not
the seventeen people who follow my blog.  It turns out that the way
to do this is to get lots of people to wishlist the game on Steam.</p>
<p>So what I should have done is: first, create the Steam page for the
game, <em>then</em> post the first blog post.  Well, better late than never:
please <a href="https://store.steampowered.com/app/3469350/High_Mountain_Abbey/">wishlist the game</a>.  The more folks wishlist it, the more Steam will feature
it at launch, and the more folks will buy it.</p>
<h2>6. Veneer</h2>
<p>So then I started working on the Steam page.  Steam requires nine
graphics, each with a different aspect ratio.  Normal people make
these graphics in Photoshop or Illustrator.  But High Mountain Abbey
is not a normal game; it’s made of physical objects.  So, of course,
the Steam graphics must also be made of physical objects.  I started
with a piece of walnut burl veneer. Veneer is supposed to be flat, but
burl wood has wild grain, so when I tried to glue the piece down, it
warped like crazy.  Probably I should have clamped it hard, instead of
just tossing a board on top of it and hoping.  Or used a
non-water-based glue.</p>
<p><img alt="Steam assets" src="https://novalis.org/blog/images/steam-the-assets.jpg" title="On a messy desk, a piece
 of warped walnut burl veneer holds a sheet-brass bird skull
 silhouette with glass lens eyes and unlit filament LEDs coming out of
 its nortrils, some blue wool spelling ‘High Mountain Abbey’ and a
 sparrow wing."/></p>
<p>Oh well, it adds character, I tell myself.</p>
<h2>One mistake I didn’t make</h2>
<p>I love the idea of Rust: big abstractions, safety, performance. I feel
unease with non-memory-safe languages in 2025 even though I actually
really enjoy programming in C.  But it would have been <a href="https://loglog.games/blog/leaving-rust-gamedev/">a mistake</a> to build
High Mountain Abbey in Rust. There’s always the temptation to make a
<a href="https://handmade.network/">custom engine</a> for any game.  But for this
game, Godot is just fine, and I think I regret even the slight amount
of weird custom stuff that I built to avoid dealing with Godot’s
resource format.</p>
<h2>Conclusion</h2>
<p>High Mountain Abbey will be released in 2026.  I can’t wait for you
to play it.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Building a game with the Real Engine]]></title>
    <link href="https://novalis.org/blog/2024-10-18-building-a-game-with-the-real-engine.html"/>
    <published>2024-10-18T12:40:17-04:00</published>
    <updated>2025-03-20T10:13:12.918694-04:00</updated>
    <id>https://novalis.org/blog/2024-10-18-building-a-game-with-the-real-engine.html</id>
    <content type="html"><![CDATA[<p>Some people make games using the Unreal Engine.  That’s nice, but I
wanted something a little different.  That’s why I’m using the Real
Engine.</p>
<p><img alt="Real Engine Logo" src="https://novalis.org/blog/images/real-engine.png" title="A logo that looks like Unreal Engine’s, except instead of a spiky U it’s a spiky R and instead of saying ‘Unreal’ it says ‘Real’"/></p>
<p>(OK, I’m not really calling it “Real Engine”; Epic please don’t sue me).</p>
<p>What’s the Real Engine?  Simple: instead of modeling a space in
Blender and then texturing it, I’m building a diorama and taking some
pictures of it.  Then I import it into the point-and-click game engine
I built and connect up the pictures into a space.  If something needs
to move, I either do stop-motion animation, or I photograph the
components separately and animate it within the engine.</p>
<p>Here’s an example:</p>
<p><img alt="Screenshot" src="https://novalis.org/blog/images/high-mountain-abbey-screenshot-1.jpg" title="A bookcase sits against a speckled, streaked, white wall. A book lies open, spine-up, on the floor.  The floor is marble tiles in red and gray.  In the foreground, there’s a church pew viewed edge-on.  A streak of light from above shines on the bookcase."/></p>
<h2>Why?</h2>
<p>Why would I do a cockamamie thing like this?  Well, it’s not the first
thing I tried.  The first thing I tried was reaching out to an artist
whose work I’ve been enjoying for decades, who lives in my city, and
who claimed to be inspired by Myst.  He agreed to work with me on the
project, which was just perfect.</p>
<p>Then I guess he thought better of it, and he ghosted me.</p>
<p>So I found another artist who wanted to work with me.  He didn’t ghost
me.  He just didn’t do the work, and eventually told me that he wasn’t
going to do the work.  I think there was some sort of illness
involved.  So we parted ways.  It’s too bad, because he clearly
understood where I was coming from, and had some great ideas.</p>
<p>So at that point, I could have gone and found yet another artist.  But
if two artists had failed, why would I think a third one would do any
better?  As Einstein supposedly said (but didn’t actually), “the
definition of insanity is doing the same thing over and over and
expecting different results.”  Also, I had to consider my emotions:
it’s heartbreaking to think you have a partner, and then realize that,
actually, you don’t.  I didn’t want to put myself through that again.</p>
<p>Now that I’ve started working on this myself, I realize that it’s
possible that I was asking too much of the artists.  I’m going to end
up spending three times as many hours doing the art as I’ve spent on
the code, at least.  I’ve had thirty years of experience as
a programmer, and much less as an artist, so it’s not really a fair
comparison.  But it’s still the truth.</p>
<h2>How long will this take?</h2>
<p>To get started, I prototyped a single room.  Actually, I only did one
end of the room, because it was just a quick test.  My prototype only
took a few days.  So I thought that maybe it would only take a few
months to do a full game.  I was wrong.  Here’s the room:</p>
<p><img alt="Prototype model" src="https://novalis.org/blog/images/real-prototype.jpg" title="A model of a scriptorium at dollhouse scale.  It’s kinda janky looking, and large areas are made of construction paper."/></p>
<p>Looking at that image, I hope you’ll see why I thought this was a good
idea.  But look a little closer, and you’ll see why I was wrong about
the timing.  There are four major issues (and some minor ones):</p>
<ol>
<li><p>Light leaks. The edges aren’t well sealed, because I wasn’t
thinking hard about light.</p></li>
<li><p>You’ll notice that you can see a nubbly gray thing behind the
scroll niches.  That’s a random blanket that I put there to block
light.  I actually needed to do a bunch more construction to hide that
background correctly (replacing the blanket with duvetyne would help
too).  Anyway, the visual design of that scroll case could use some
work – the niches should be diagonal, and go less close to the walls.</p></li>
<li><p>The table has tiny dowels for legs, and the top is plain
construction paper.  I would rather have something that looks a little
more like wood, and legs that aren’t so spindly – even if it’s just
faux finishing.</p></li>
<li><p>The windows don’t have glass in them, and in fact, the muntins (or
cames, or whatever the bits between the glass are called in this
context) are made of the same paper as the walls.</p></li>
<li><p>The ceiling is flat and boring.</p></li>
<li><p>The depth of field is not great, about which more later.</p></li>
</ol>
<p>This is the same problem that AI art has: it’s fine on first glance, and then
you get closer and it all falls apart.  As <a href="http://johnsalvatier.org/blog/2017/reality-has-a-surprising-amount-of-detail">John Salvatier notes,  "Reality has a surprising amount of detail"</a>.</p>
<p>The thing is: I could fix most of these – but fixing them basically
means rebuilding the entire room.</p>
<p>So “a few days” becomes a few weeks or a month, and now I’m looking at
a much longer timeline.  Fortunately, nobody is going to scoop my idea,
because nobody else is insane enough to build a game this way.</p>
<h2>Prior Art</h2>
<p>OK, maybe someone else is.  There’s <a href="https://slow-bros.com/harold-halibut">Harold
Halibut</a>.  They’ve built real
objects and then used photogrammetry to put them into a traditional 3d
engine.  It’s a neat idea, but my idea involves one fewer step.</p>
<p><strong>Update</strong>: Also apparently <a href="https://store.steampowered.com/app/205020/Lumino_City/">Lumino City</a>,
<a href="https://youtu.be/ZVhtuKleLuI">Papetura</a>, and
<a href="https://en.wikipedia.org/wiki/The_Neverhood">The Neverhood</a> use
similar physical modeling techniques.</p>
<h2>Why not Blender?</h2>
<p>Why don’t I just use Blender like everyone else?</p>
<ol>
<li><p>I hate Blender.  I mean, I understand that it’s the standard thing
that everyone uses, and I know that I would eventually get used to the
UI.  But almost every time I use Blender, I end up mangling the
geometry in some way that requires either me to take a hundred years
of clicky work to fix it, and in the end I wish I had remade the part
from scratch.</p></li>
<li><p>I’m not much good at textures.  I could just buy a bunch of
textures, but getting them to look nice together would be tough.  And
I would still end up with a bunch of repetition, because there’s just
no way a solo dev can get enough textures.  Cyan manages it – when
playing Firmament, I didn’t notice any texture repetition (I did
notice that the music was an incomprehensible drone, except for the totally perfect <a href="https://www.youtube.com/watch?v=IzKjFTAbhjg">VNV Nation
track</a> at the end).  But
this seems to scale with studio size.  In this screenshot from <a href="https://querngame.com/">Quern:
Undying Thoughts</a>, take a look at the wood
texture on the dock.  They get a little extra mileage by mirroring the
texture on alternate boards, but it’s still the same texture:</p></li>
</ol>
<p><img alt="Quern" src="https://novalis.org/blog/images/quern-textures.jpg" title="A. screenshot from Quern: Undying
 Thoughts. A wooden dock extends out into the ocean under a cloudy
 sky. The weathered boards of the dock all use the same texture."/></p>
<p>Zadbox, which created Quern, is smaller than Cyan.  Going down to a
single-person studio, <a href="https://haven-moon.com/">Haven Moon</a> is a noble
effort, but I got awfully bored of seeing the exact same brick wall in
dozens of places.</p>
<p>I didn’t want to do that to my players.  The whole point of games like
this is to explore a new world.  But if you’ve already seen all of the
textures on the first island, then you’re not really exploring a new
world.</p>
<p>By contrast, here’s what my staircase looks like (before I install it
– it’ll be in a stone tunnel, so the details might be harder to see
in situ):</p>
<p><img alt="Stairs" src="https://novalis.org/blog/images/stairs.jpg" title="A photograph of a model
staircase in dark wood.  The stairs are worn and cracked, and the
angles are not quite square.  It sits atop a ‘stone’ rectangle, which
sits on a piece of cardboard."/></p>
<p>Every stair is different.  Some of the angles are a little off square,
which is totally fine, since it’s supposed to be sort of beat up and
ramshackle.</p>
<h2>Why not AI art?</h2>
<p><a href="https://novalis.org/blog/2023-05-30-turds.html">I’ve addressed this before</a>.  But also
consider the following prompt:</p>
<blockquote>
<p>Painting based on Goya’s Saturn Devouring His Son, but with a giant
  eagle eating a tiny headless monk in a brown robe. The eagle holds the
  monk’s in its giant claws. Crimson fluid leaks from the monk’s neck.</p>
</blockquote>
<p><img alt="Fuck Midjourney" src="https://novalis.org/blog/images/fuck-midjourney.jpg" title="Four images: an eagle
 feeding blood to a child in a brown robe. An eagle dripping blood
 onto the hand of a youth in a brown robe; the child’s hand and face
 are bloody and the hand only has three fingers but not because one
 was eaten. A child with no legs holding back the claw of an
 eagle. The best one but still no good: an eagle with its beak at the
 face of a man; maybe it’s eating him or maybe it’s feeding him.  The
 eagle has distorted, weirdly large human hands wrapped around the
 man’s neck."/></p>
<p>So, AI is bad at prompt following.  But also, it would be really hard
to have it do two images of the same room from different locations.  I
would probably have to generate one image, then convert it to a 3d
model, and then use controlnet.  I’m not sure this is less work than
any of the other methods.</p>
<p>And even if I did build a gray box model to use with controlnet,
Midjourney doesn’t even understand that if there are arches and
columns, the arches have to be on top of the columns.</p>
<h2>Process</h2>
<p>So given that I’m going to use the Real Engine (Okay, okay, Epic, I’ll
stop now), how will I do it?</p>
<h2>What kind of space?</h2>
<p>Myst and Riven are set on a series of islands.  Haven Moon is set on a
series of islands.  Quern is set on a series of islands.  Firmament is
set in… well, I won’t say to avoid spoilers, but a small number of
relatively enclosed spaces.  In a game like this, any time the player
tries to walk off the edge of the map and just hits an invisible wall,
it’s immersion-breaking.  That’s why there are so many islands.</p>
<p>So I needed space without a lot of freedom.  I decided on an abbey
high in the mountains.  The mountains will be a matte painting, and
most of the game will take place indoors.  It’s not exactly <a href="https://en.wikipedia.org/wiki/The_Name_of_the_Rose">an
original setting for a
mystery</a>, but I
think I’ve put my own twist on it.  The setting then gave me enough
inspiration to put together a story.  And the story has then suggested
certain aspects of the puzzles.</p>
<h2>Roughing out</h2>
<p>First, I drew a floorplan in Inkscape.  (I’m not sharing any maps
here because I don’t want to spoil the fun of exploring the space once
the game is released).  This just marked out the walls and doors of
each room, so I could get a sense of how the pieces fit together.</p>
<p>Then I copied that floorplan into Blender, building up the volumes of
the space.  This let me more easily see how the roof lines would
appear, and fly around to get a sense of scale.  I guess some people
can do this mentally from just a floorplan, but since I plan to have
complex roofs, Blender was easier. I left some interior spaces out of
the model, since they don’t have roofs.</p>
<h2>Scale</h2>
<p>Dollhouse scale is usually 1:12 (for a delightful note on this,
<a href="https://clairelevans.substack.com/p/the-queens-dolls-house">search this page for "Mervyn O’Gorman"
</a>).  This
makes the arithmetic easy for Americans like me who grew up with
“customary units": an inch is a foot.  And it’s workable for
interiors: you can fit a large room on your table, if you have a big
table, and you can fit a phone camera into a small room and still get
things in focus.</p>
<p>But if you want an exterior of the entire abbey (and you definitely
do!), you either need a bigger workshop than I have, or you need to
take a hint from model railroading and go to 1:48 scale, which the
model railroading folks call “O scale”. Having two different scales is
annoying, because it means that you can’t seamlessly blend – if you
want a door from the interior at 1:12 to the exterior at 1:48, you
can’t just put the two dioramas next to each other, you have to put a
green screen on both doors and then later paste in to each the
appropriate photograph of the other one.</p>
<p>I think I actually will end up using a third scale because 1:12 is
too teensy for some of the really complex bits, but hopefully that’s
just for a room or two.</p>
<p>For another wonderful article of scaling, see John McPhee’s article
<em>The Ships of Port Revel</em>, in his collection <em>Uncommon Carriers</em>.  “At
scale the mallards are thirty feet long,” is a line I often think of
as I work on this project.</p>
<h2>Photography</h2>
<p>I had initially planned on shooting the whole thing on my phone
camera.  There’s a problem with this: my phone is six inches wide, and
the camera is at one end, so if I have a narrow hallway, I can’t have
the camera centered unless I hold it vertically (which loses
resolution, since the game will be designed for 16:9).  Also, the
phone camera is very smart, which means that I’ll be constantly fighting
it to get consistent lighting.  I know there are APIs for manual mode, but
building a custom Android camera app would be a lot of work.</p>
<p>A SLR was right out; they are giant compared to the space I’m
shooting, and even macro lenses typically have too-large minimum focal
distances.</p>
<p>Keep in mind: the camera must operate inside an entirely enclosed
space, and I need to see the pictures as I go in order to make sure
I’m getting what I want, and I need to do this without picking up
the camera to look at a screen.</p>
<p>So I decided to build a camera.  Well, I bought a Raspberry Pi camera
module (and then a second one when the first one wasn’t good enough),
and built a tiny Flask app which runs on the Pi to take pictures and
allow me to adjust the exposure and focal length over wifi.  The Pi
is powered by one of those phone battery packs, which is cheap and
runs about all day before needing a recharge.  It sits on some wooden
blocks so that the photos are all from the same eye level.  The camera
is a bit noisy, but long exposures help a lot.</p>
<p>Actually, I ended up buying a third camera and a second Pi.  The
OwlSight only has a 68 degree horizontal field of view.  My aspect
ratio is 16:9 (1.77:1), but for most shots it’s actually 1.956:1,
because I leave a little margin around the edges so that I can show it
as you rotate, making the direction of rotation clearer. So I ended up
having to move the camera very far away from the wall to get enough
into view.  With a second camera at a slight angle to the first, I can
stitch two photos into a panorama.</p>
<p>I’m also doing focus stacking.  The idea is that a macro lens has a
relatively shallow depth of field.  This is a distinctive look: things
shot in macro look like they are shot in macro.  If you want to make
large things look like macro, you use tilt-shift photography to fake
this effect.  If you want the opposite, you use focus stacking: take
photos at multiple depths of field, and choose the in-focus parts of
each.  The stacking happens before the panorama, since then I don’t
have to worry about panotools picking the same points of
correspondence for each image pair in the stacks.</p>
<p>The Pi doesn’t have enough RAM to easily run focus stacking software,
so my Flask app just scps the files up to my desktop, and then runs
the focus-stacking software there.  Then it copies the composited
image back for display.  Then if I like the pic, I can press a button
to copy it back into the game’s assets directory (named
appropriately).  I also save the images from which I built
each focus stack, in case I want to do more editing later.</p>
<p>The whole thing is slightly janky, but there’s a trade-off between
spending time improving the app and actually making the game.  By
nature, I’m very excited about working on tools.  As an indie game
dev, that’s a trap.  Because of the long exposures at multiple focus
levels, I do have a bit of time between shots to futz with the camera
code and write the post that you are reading now.</p>
<p>Every room I build, I learn something.  For instance, the OwlSight
camera’s auto white balancing seems to blow out reds.  I didn’t notice
that until I tried to shoot some red-orange needle-felted balls.  So
I’ve added manual white balancing control.</p>
<p>The second room I built has a rough floor.  This means that the camera
stand (which is literally some random wood blocks that I had laying
around) doesn’t sit flat.  Or maybe the floor just isn’t level to
begin with – there was definitely some warping when I applied the
air-dry clay to the masonite, and I’m not sure gluing braces on later
quite got it all out.  Mostly, I don’t care if if the camera is a bit
off level, but in one case, I have a machine on the wall that needs to
be dead square to avoid annoyances during animation. So I built a
camera leveler with another wood scrap.  It has threaded inserts at
the corners, so I can turn screws to adjust the height of the four
corners of the cameras.</p>
<p>The third room ended up having insufficiently bright lighting. I
bodged together a partial solution, but it’s still going to be the
dimmest room in the game.  Next time I’ll use brighter LEDs.</p>
<h2>Architecture</h2>
<p>Architecture is really hard.  Consider the chapel: I picked the shape
for it based on where it fit into the rest of the monastery.  There
are some subtle constraints – like, I really wanted one of its walls
to be blocking the view from the door to the front hall, because
otherwise that door would open into the garden, which is at O scale.
And I did a flat angled roof because a gable roof would be hard to
square with the six-sided floorplan. Also, I think a gable roof with
elaborate decorative skylights might be weird, and skylights are the
only hope for lighting a room of this size.</p>
<p>After examining the model in Blender, I decided that it could be a
chapel.  A bit 1960s looking, but OK.  Unfortunately, this meant
trapezoidal walls, and compound angles.</p>
<p>The skylight wasn’t going to be quite enough light, so I added a bunch
of fenestration.  I decided on stained glass, and tried several ways
to make it look right. In the end, one of the windows has a complex
pattern which I printed on acetate, and the others have simpler
patterns which are alcohol-based ink on acrylic.  The acetate is
brighter, but the acrylic is good enough and comes in larger sizes.</p>
<p>Of course, the windows have to be high enough that you can’t see much
out of them, because outside the windows is the garden, which is still
a different scale.  I guess I could have just planted some trees right
outside, and built two scales of tree, but then I wouldn’t as much
extra light.  With high windows, the sky will still be visible.  So I
just painted a rough blue-white gradient on some cardboard, which,
through the acrylic, is good enough.</p>
<p>If this were actually built in the 1960s, the windows would be
aluminum rectangles.  But rectangles are boring.  I went with
bird-inspired shapes, which are hopefully a bit Gaudi-esque. Birds are
a big theme in this game, for reasons players will discover.</p>
<p>I made the chapel floor with “stone” tiles.  To make tiles, I used
<a href="https://jenniferrizzo.com/how-to-do-acrylic-paint-pouring-for-beginners/">poured paint</a>
on paper, cut into squares.  This was a bad decision, because I had to
pour like a dozen sheets to get enough squares, and then I had to glue
them down (I used gray paint as the glue, so it could double as
mortar).  The good decision I made was to align it diagonally, which
meant that I could hide some of the unevenness.  But then I didn’t do
a great job of getting straight lines, so I had to trim some of the
tiles.  Probably nobody will notice.  Also the tiles peeled some,
which means that the floor looks kind of cracked.  Fortunately, the
story of the game makes this not totally unreasonable, so I’ll just
knock over some of the pews and throw some prayer books around, and say
there some sort of catastrophe here.</p>
<p>The walls are covered with Thai kozo paper.  But where the paper
joins, it doesn’t look great, so I built some columns to cover those
places up.  The columns are foam covered with more kozo paper.  For a
couple of the interior corners, I used some wood framing.  There are
a lot of little decisions like this: I need to cover an edge or a
corner, so I add a little trim, which ends up adding visual interest
to the space.</p>
<h2>Tools and materials</h2>
<h2>Premade dollhouse furniture</h2>
<p>No. If I do that, my game will look like everyone else’s dollhouse.
Also, in theory it’s copyright-infringing, although in practice, I’m
unlikely to get sued.  I tried to use some lighting marketed for
dollhouses just to avoid wiring my own LEDs, but they ended up not
being bright enough.  Dollhouses usually have one open wall so that
you can <a href="https://youtu.be/j9V4s75yivg?si=cWux63_ptdKJZYTJ&amp;t=273">get Sandy Toksvig inside
them</a>, so
lighting inside a dollhouse is for looks not for illumination.  So I
won’t try that again.</p>
<h2>3d Printing</h2>
<p>I want to avoid 3d printing as much as possible, because 3d printed
stuff lacks that handmade look.  Also, it means I have to use Blender.
Well, when I’m lucky, OpenSCAD.  I have needed a few prints.  First I
ordered online, then I borrowed <a href="https://thingswemake.com/">my
brother-in-law’s</a>, and now my wife brought
me home a 3d printer that someone in her office was just giving away
for some reason (this is how the rich get richer).</p>
<p>The other bad thing about 3d printing is layer lines.  I had some
bench parts printed, and I thought I could cover up the layer lines
with acrylic paint, but it it turned out that even two layers of gesso
followed by two layers of paint didn’t solve the problem.  When your
camera is four inches from the subject, every little line shows.  The
actual solution is
<a href="https://www.smooth-on.com/product-line/xtc-3d/">XTC-3D</a>, which is a
rather unpleasant product: expensive, short pot life, hard to apply
thinly, and weird-smelling.  But it does the job, which is the
important thing.</p>
<p>Speaking of extremely fine details, my workshop is unfortunately also
inhabited by two long-haired cats.  Every time I see them, I think
“Did he who made the lamb make thee, and if so, why did he make you
shed so damn much?”  Keeping the hair out of the dioramas is quite
tricky, and I often find that I have to remove a stray hair and
reshoot.</p>
<p><img alt="Cats are bad" src='https://novalis.org/blog/images/cats-are-bad.jpg "A piece of sonotube with a veneered inside.  Inside the tube is a janky-looking collection of electronics and a large silver Maine Coon cat." '/></p>
<h2>Clay</h2>
<p>Even though I have a full pottery studio with a kiln, I’m going to use
very little ceramic clay for this project.  One reason is that the
cycle time is high: I need to accumulate enough stuff to fill a kiln,
and then run the kiln, and then glaze, and then run the kiln again.</p>
<p>Ceramics has a very distinctive look, which is mostly not what I want
for this space.  I do have plans for a couple of pieces – which,
given the cycle time, I should probably start on.</p>
<p>Some of the door moldings are made from DAS air-dry clay.  It’s
nowhere near as nice to work with as real clay, but it’s surprisingly
strong – you can pick up a piece of molding that’s 1/16” thick and 7”
long by one end, and it won’t break.  Try that with green stoneware
clay and you’ll have a bad day.  And you can cut it with a knife even
when it’s dry.  I also made a vase out of it, but getting something
round at that scale with that clay is tricky.  I should probably just use
real clay for that.</p>
<p><a href="https://avesstudio.com/shop/apoxie-sculpt/">Epoxy clay</a> is really nice
to work with, if you’re quick.  I made doorknob parts with it, and filled in
some of the cracks in the door moldings.  It’s hard as a rock once it’s
dry, so you don’t want to be too sloppy, but it remains sandable when hard.</p>
<h2>Needle felting</h2>
<p>Instead of glowing screens, I’m probably going to do most of the
screen-like puzzles using needle felting.  I think in my ideal world,
every puzzle would have a reasonable and diegetic hardware
manifestation, but that’s not quite how the puzzle design ended up
going.</p>
<p>So far, it’s a lot of fun. I’m not anywhere near the level of <a href="https://www.youtube.com/watch?v=CMKxk0Xu52s">Andrea
Love</a>, but I can make
cool stuff.  For my first animation, I made ten frames (for each of
the three animations), then I used
<a href="https://github.com/nihui/rife-ncnn-vulkan">RIFE</a> to add three frames
in between each of my originals.  I think this was especially helpful
at the end of the animation, since my animation loops back to the
first frame, but the felt didn’t end up exactly perfect.  At 20 FPS,
it still looks like stop-motion, which I think matches well with the
handmade look of the rest of the game.  I’ll probably reduce the
frame rate of the other animations in the scene, and add a little
jitter, to match.</p>
<p>(This video has a white rim which will be masked out in the actual
game – doing alpha channels in video is tricky, so I’ve just written
little shader which applies a mask at runtime)</p>
<video controls="" height="688" loop="" width="688">
<source src="https://novalis.org/blog/images/high-mountain-abbey-circle.mp4" type="video/mp4"/>
    A video of a blue needle-felted circle shrinking to a point, and
    being refilled from the other side in cyan.
</video>
<h2>Release</h2>
<p>I’m really excited to be working on this project.  I go to work every
day happy, and I fall asleep thinking about what I’ll do next.  I can’t
wait to show you the world I’ve built.</p>
<p>High Mountain Abbey will be released once I have designed,
constructed, and photographed a lot of dioramas.  Hopefully 2025 but
early 2026 is more likely.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Middles updates, design, and prior art]]></title>
    <link href="https://novalis.org/blog/2023-11-10-middles-updates-design-and-prior-art.html"/>
    <published>2023-11-10T20:05:43-05:00</published>
    <updated>2025-03-20T10:13:12.982694-04:00</updated>
    <id>https://novalis.org/blog/2023-11-10-middles-updates-design-and-prior-art.html</id>
    <content type="html"><![CDATA[<p>Here’s an update on my game <a href="https://middlesgame.com">Middles</a>.</p>
<p><a href="https://blog.plover.com/">Dominus</a> told me that <a href="https://community.wolfram.com/groups/-/m/t/2287865">Bill
Gosper</a> was also
inspired by …MEOW…, and made a version of this game. His version
allows only four-letter substrings, and allows those substrings to
occur anywhere in the word (so GULC would be valid).  When Dominus
mentioned Gosper’s work, I assumed that it was in, like, 1983, since
Gosper is fifteen years older than my parents, but it was actually
just a couple of years ago.  So I’m not that far behind the
curve. <em>Update</em>: No, actually I am way late.  Dominus further informs
me that he learned about it in <a href="https://archive.org/details/moremathematical0000unse/page/114/mode/2up">More Mathematical
People</a>(1990), p 114.  Gosper attributes it to a friend of his.</p>
<p>A former co-worker mentions <a href="https://www.wordiply.com/">Wordiply</a>, a
Guardian game with non-unique middles.  I hate it, because the longest
words are very often a mess of affixes.  Consider “utel": the best
word is “absofuckinglutely”, which contains both an infix and a
suffix; the best word they are likely to actually accept is is
“irresolutely”, which contains both a prefix and a suffix.  And they
let you riff on affixes, so you can do things like remitting,
remittingly, unremittingly; this is often a totally reasonable
strategy.  There’s nothing wrong with affixes, but there’s also
nothing interesting about affixes.</p>
<p>A game that plays somewhat like Middles is Superghost; <a href="https://www.kith.org/words/1997/02/16/ghost/">Jed Hartman
describes it nicely</a>;
there, the goal is <em>not</em> to make a word.  Another friend
mentioned it in the context of a <a href="https://www.newyorker.com/magazine/1951/09/29/do-you-want-to-make-something-out-of-it-or-if-you-put-an-o-on-understo-youll-ruin-my-thunderstorm">James Thurber piece from
1951</a>
(paywalled; your library may have New Yorker archive access). The
logical next step is, of course, Superduperghost, which allows
inserting letters at any position.  Jed Hartman also describes this
version; Wikipedia says it wasn’t invented until 1970, which seems
surprising.</p>
<p>Hartman also mentions “the occasional several-minute wait between
letters”, which points to a problem with this whole category of games:
without a time limit, you can often spend hours thinking about a turn.
<a href="https://boardgamegeek.com/boardgame/39635/prolix">Gil Hova’s Prolix</a>
solves this problem with a timer.  This is a problem I complain about
whenever someone wants to play
<a href="https://boardgamegeek.com/boardgame/178900/codenames">Codenames</a>.
Yes, Codenames comes with a timer, but nobody uses it, and it’s too long
anyway.  This is one reason I wanted a game like
<a href="https://surfwords.com">Surfwords</a>.</p>
<p>There are often a lot of ways to approach the same game concept.
Today I was at <a href="https://momath.org/">MoMath</a> and discovered <a href="https://www.thinkfun.com/products/balance-beans/">Balance
Beans</a>. I had
definitely considered making a game on this premise, but mine was
going to be a computer game, and it was going to involve trucks trying
to drive across the balance beam, with some slop in the system to
allow a truck to be driven onto just one side.  Also, my trucks were
going to have different weights at the same one-square size, as
opposed to having size and weight conflated and having connected
groups.  After playing it, I think their choices might be better. But
mine would have offered some neat sequencing puzzles.  (Just a note:
their physical design is a bit crap; if you aren’t careful while
removing a piece from the heavy side, the motion will disrupt some of
the other pieces).</p>
<p>PS: I’ve also corrected a flaw in Middles.  Dominus and another player
mentioned that yesterday’s EYAN could be the somewhat obscure word
ABEYANCE instead of the expected CONVEYANCE. I’ve added a button for
this situation, which lets you enter an alternate answer and (if your
alternate answer is on my long word list and you entered a letter that
would have been correct for the alternate answer) gives you a point
back.  This is a weird solution, but I didn’t want to just accept
alternate answers as you type them, since that could lead a user to a
word that they think is obscure.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Middles: A Daily Word Game]]></title>
    <link href="https://novalis.org/blog/2023-10-30-middles-a-daily-word-game-.html"/>
    <published>2023-10-30T14:18:19-04:00</published>
    <updated>2025-03-20T10:13:12.950694-04:00</updated>
    <id>https://novalis.org/blog/2023-10-30-middles-a-daily-word-game-.html</id>
    <content type="html"><![CDATA[<p>I made <a href="https://middlesgame.com">Middles</a>, a daily word game.</p>
<p>A while ago, I worked a company whose initials were TS.  This led to
some fun times: Accounts that started with TS were assumed to be
system accounts, so when a human named Tsutomo (or something) joined
the company, his account got treated weirdly.  IIRC we renamed his
account rather than changing the system.</p>
<p>I was working on version control, and we wanted to find a name for the
new system, so I suggested “nuTShell”, being the best word I could
find that contains the letters “ts” in the middle.  My team lead
immediately replied, “O God, I could be bounded in a nut shell and
count myself a king of infinite space.”  Which is exactly what I was
thinking.  But nobody else seemed to appreciate the Shakespeare, so we
went with a different name.</p>
<p>And then there’s <a href="https://lesserjoke.tumblr.com/post/149942489360/macleod-list-of-words-containing-meow-meow/amp">this Tumblr
post</a>.
(It will probably get lost, so for future reference, it reads: “List
of words containing “meow”: meow, meowed, meowing, meows,
homeowner"). The original version of that Tumblr post (since deleted)
is from 2016; I don’t remember when I saw it.  But it’s been living in
my head ever since, and eventually, I realized that there was a game
there.</p>
<p>The game works like this: I give you the middle of a word, and you try
to guess the rest, one letter at a time. Every time you guess wrong,
you lose a point. At zero points, you lose.  The secret word is chosen
so that its middle is unique among commonly-known words (ignoring
plural nouns and singular verbs).  For instance, the middle OBC
appears in the common word BOBCAT and no other common singular word
(it also appears in the uncommon word MOBCAP, a kind of bonnet that
nobody has heard of).</p>
<p>There are a lot of words that have unique middles that nonetheless are
bad candidates.  DUSTRIO is bad because it’s obviously INDUSTRIOUS.
WJ is bad because it’s NSFW.  INGEM is bad because while INFRINGEMENT
is the more common word, IMPINGEMENT is common enough that some
players will know it.  For this determination, I used a combination of
<a href="https://doi.org/10.3758/s13428-018-1077-9">Brysbaert, M., et al</a> and
my own personal judgement (they think impingement is non-prevalent,
but I think it’s prevalent, possibly wrongly, because it’s something
I’ve experienced).  Also, Brysbaert is lemmatized, which makes life
harder.</p>
<p>But I have about 4,000 words (I still might remove some when I take
another look), which is over a decade of game before repating.  Not quite
Wordle, but not bad.</p>
<p><a href="https://middlesgame.com">Give it a try</a>.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[A review of one puzzle from Quern: Undying Thoughts]]></title>
    <link href="https://novalis.org/blog/2023-07-26-a-review-of-one-puzzle-from-quern-undying-thoughts-.html"/>
    <published>2023-07-26T14:14:13-04:00</published>
    <updated>2025-03-20T10:13:13.014694-04:00</updated>
    <id>https://novalis.org/blog/2023-07-26-a-review-of-one-puzzle-from-quern-undying-thoughts-.html</id>
    <content type="html"><![CDATA[<p>I don’t want to review the whole game.  But I do want to talk about
one puzzle that I found infuriating.  <a href="http://gameshelf.jmac.org/2016/12/quern-undying-thoughts-design-ruminations/">No, not that one, which could so
easily have been improved</a>.  A different one.  Not because it was hard (it
wasn’t).  But because it had a bizarre design.  I’m going to spoil
some minor aspects of the puzzle, but not the interesting part.</p>
<p>Here’s the set-up.  Actually, here’s the pre-set-up: puzzles in the
game are both entirely arbitrary and entirely diegetic: some asshole
has stranded you on this puzzle archipelago and is forcing you to solve his
puzzles.</p>
<p>OK, now the set-up: You’re on an island.  There are two other islands,
one to the South and one to the North, and you can’t presently get to
either island.</p>
<p>There’s a green laser thing shooting out of a crystal.  You can rotate
a reflector doohickey to make it point to another crystal on the North
island, at which point you can press a button and “ride” the laser
across.  There’s also a crystal on the South island, but you can’t
point to that one because it’s too high up.  There are other reflector
doohickeys visible but not reachable.</p>
<p>When you get to the North island, you find a machine (actually, two,
but they function in tandem), and more reflectors.  The machine
controls (in a way that I will leave vague) the enablement and
orientation of all of the reflectors.  You also find a piece of paper
which describes a particular set of reflector orientations that it
wishes you to achieve.</p>
<p>If you manipulate the machine appropriately, you can make the
reflectors assume this orientation (and enable them all).  This
machine is pretty cool.  Not the world’s most innovative puzzle, but
(unlike many of Quern’s puzzles), not readily susceptible to brute
force. I did not regret the minutes I spent figuring out how to make
it do the thing.</p>
<p>Completing the pattern gives you a new way to travel back to the
central island.  It also makes a lever pop up, which lets you adjust
the initial reflector upwards so you can hit the crystal on the South
island.</p>
<p>This is stupid.</p>
<p>The path that the new pattern sends you on takes you around the
otherwise inaccessible back side of the central island.  Instead of
having the South island crystal high up, they should have had it
obstructed so that it could only be reached from the back.  You would
still need to do roughly the same reflector manipulation, but instead
of doing it because a piece of paper told you to, you would be doing
it because it would directly let you reach your goal.  There’s no need
for the lever, in that case, and no need for the piece of paper.
(This also requires either a slight change in the mechanics of
crystals, or one more crystal, but neither would break the rest of the
game).</p>
<p>This would have a subtly different effect, in that you couldn’t travel
directly from the central island to the South island.  But that’s not
a path you need to take more than once (OK, twice, I didn’t notice
something the first time I was there).  And anyway, once you’re there,
a fast return path could have been provided (Quern does a lot of
this).</p>
<p>The reason my design is better is:</p>
<ol>
<li><p>It is more interesting to figure out how to use a tool to
accomplish your goal than it is to figure out how to input a pattern
because a piece of paper told you to.</p></li>
<li><p>The lever is an unnecessary piece of hardware that doesn’t
contribute to making the puzzle harder or more interesting.</p></li>
</ol>
<p>Possibly even better would be to have the reflectors arranged roughly
as they currently are, but while you’re riding the laser the long way
around the back of the island, you can see something that you would
then need to use to decide how to change the routing. I am not sure
this idea would actually be better, because I found the laser-riding
to be headache-inducing.  But at least it would have fully used the
possibilities of the set-up.</p>
<p>Maybe you could argue that it’s diegetic that the puzzle has this
weird lever epicycle (because the <a href="https://www.rickandviv.net/index.php/2004/08/18/crimes-against-mimesis/">dude who has trapped you here</a> is
just not a good puzzle designer), but that is the last refuge of the
scoundrel.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Turds]]></title>
    <link href="https://novalis.org/blog/2023-05-30-turds.html"/>
    <published>2023-05-30T11:08:19-04:00</published>
    <updated>2025-03-20T10:13:13.006694-04:00</updated>
    <id>https://novalis.org/blog/2023-05-30-turds.html</id>
    <content type="html"><![CDATA[<p>Have you noticed the turds?</p>
<p>Before I begin, let me say that I’m not dissing
<a href="https://blog.luden.io/generated-adventure-the-postmortem-of-a-game-made-with-chatgpt-and-midjourney-prompts-included-f87e7e615204">Generated Adventure</a>
or the people who created it.  They made a very impressive tech demo in
72 hours, and if you don’t look too closely, it’s rather pretty.  They
were under tight time pressure, and they were specifically aiming to
use only AI tools.  They did better than I would have in 72 hours
(although as a parent, the idea of devoting 72 straight hours to
anything is totally unimaginable).  It’s good enough to make me
consider Deform over Godot for a project like this (I’m sure either
could handle it, but they did it so fast!).</p>
<p>But I feel like something that gets lost in the discussion of
AI-generated artwork is the turds.  Here’s an example of what I mean:
it’s one of the sets of images that Midjourney generated for Generated
Adventure (I don’t think any of them ended up being used for the game).</p>
<p><img alt="Four AI-generated isometric view of bedrooms in a fantasy game style" src="https://novalis.org/blog/images/turds-orig.png"/></p>
<p>At first glance, it’s fine.  But then you notice the turds.</p>
<p><img alt="The above image, marked up with colors indicating the problems; there are dozens of markings" src="https://novalis.org/blog/images/turds.png"/></p>
<p>Here’s what I mean.  Green marks blurry object edges, which I’ve
complained about before.  Some of these might be the webp compression
of the image from the <a href="https://blog.luden.io/generated-adventure-the-postmortem-of-a-game-made-with-chatgpt-and-midjourney-prompts-included-f87e7e615204">Medium
post</a>,
so I haven’t been too harsh here.  Purple marks bad angles: shadows
that don’t match, a wall that’s also a floor, and different-length
legs on a … well, I have no idea what that thing is.  Blue generally
marks things that are unidentifiable, although in the top-right one,
it marks the only floor-tree (?) that has a pot.  Unidentifiable stuff
is a venial sin; it’s a fantasy game, and sometimes there’s weird stuff
in a fantasy world.</p>
<p>Red is the real turds.  Stuff that is so our-of-place as to break
immersion.  Often it’s unidentifiable, but sometimes it’s just in the
wrong spot (like the faucet in the top left which isn’t over a sink).
The bottom left has a fractal turd: the roof of the hutch has a weird
asymmetrical fold at the top, but also, a bedroom should not contain a
hutch with an outdoor roof.</p>
<p>Once you start looking at AI-generated art, the turds are everywhere.
Midjourney often “solves” this by doing images that are impressionistic rather
than representational. I googled for “Midjourney dragon”, and this was the first hit:</p>
<p><img alt="A Midjourney-generated water dragon" src="https://novalis.org/blog/images/turds-dragon.jpg"/></p>
<p>Other than the inexplicable human figure (?) in the center of the
image walking on water, this doesn’t have major turds – but it’s also
clearly intended to impressionistic rather than to represent a real
scene.  I should note that several of the other images from <a href="https://www.artstation.com/artwork/9NbNDQ">that
source</a> do have turds, such
as phantom Chinese-looking characters.  Side note: I wonder why the
dragons are disproportionately looking to the left.  In one image, the
main dragon head is looking to the right, but clearly that was
unacceptable, so there’s also a secondary head-turd looking to the
left.</p>
<h2>Music</h2>
<p>I’m not any good at music, so I can’t immediately identify the musical
turds in the AI-generated music from <a href="https://aiva.ai/">AIVA</a>.  This
is what Generated Adventure used.  AIVA seem to be generating MIDI
files, so they won’t have the same sorts of errors as AI image
generators, which operate on a pixel level.  But I can say that their
prompt following is bad.  I uploaded the first track of the
<a href="https://surfwords.com">Surfwords</a> soundtrack to AIVA.  Here’s what it
sounds like:</p>
<p><audio controls="">
<source audio="" mpeg"="" src="https://novalis.org/blog/turds-orig.mp3” type="/>
</audio></p>
<p>That’s a track composed by a <a href="https://www.patrickcornelius.com/">human</a>.
One of the tracks that I sent him as inspiration was this one (skip to 0:24):</p>
<iframe seamless="" src="https://bandcamp.com/EmbeddedPlayer/album=1606899972/size=large/bgcol=ffffff/linkcol=0687f5/tracklist=false/artwork=small/track=923078007/transparent=true/" style="border: 0; width: 100%; height: 120px;"><a href="https://moonhooch.bandcamp.com/album/moon-hooch">Moon Hooch by Moon Hooch</a></iframe>
<p>He nailed it! Patrick’s track is maybe a little less skrawnky, but it
definitely captures the feeling and instrumentation.</p>
<p>Compare AIVA (I uploaded Patrick’s track rather than the Moon Hooch as
a “influence”, since I have the rights to it):</p>
<p><audio controls="">
<source audio="" mpeg"="" src="https://novalis.org/blog/turds-gen.mp3” type="/>
</audio></p>
<p>Sure, the BPM is the same (according to a random online BPM detector).
Maybe the key signature is also the same?  But it’s not even the right
instruments – AIVA suggested “Clean Rock Ensemble” for this track,
but my track is brass. (AIVA’s generated tracks with the same
influence on the Brass Ensemble setting sound even less like the
original).</p>
<p>If you don’t have a vision in mind for what your music sounds like,
AIVA is maybe fine.  Like, it sounds like generic music.  But if you
do have a vision in mind (as I did for the
<a href="https://surfwords.com">Surfwords</a> music), AIVA is not there yet.</p>
<h2>Conclusion</h2>
<p>Please don’t tell me about how I could fix this by twiddling the
Midjourney or AIVA prompts.</p>
<p>AIVA’s config options seem to be designed for people who understand
music much better than I do.  Maybe it’s a good tool if that’s your
situation.  But why offer to let me upload an influence, if you aren’t
going to do anything other than extract the BPM and key signature?  At
least get the instruments right!</p>
<p>And yes, you can paint out the turds in Midjourney and tell it to fill
in the area again until it gets it right.  But the shadows are still
going to be annoying, and the iteration time is painfully slow.</p>
<p>Soon, this might be fixed.  But not today.  It’s frustrating to be so
close, and to have everyone hyping how close we are, and to be
stuck with turds
.
(Also please don’t say mean things about the Generated Adventure
folks, who set out to do a thing and successfully did the thing; none
of this is directed at them).</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Dev journal for Deco Deck, my new indie game]]></title>
    <link href="https://novalis.org/blog/2023-05-12-introducing-deco-deck-my-new-indie-game.html"/>
    <published>2023-05-12T10:02:27-04:00</published>
    <updated>2025-03-20T10:13:12.882694-04:00</updated>
    <id>https://novalis.org/blog/2023-05-12-introducing-deco-deck-my-new-indie-game.html</id>
    <content type="html"><![CDATA[<p><a href="https://decodeckgame.com">Deco Deck</a> is my fourth indie game.  It’s available today
on <a href="https://apps.apple.com/us/app/deco-deck/id1672666901">iOS</a>,  <a href="https://play.google.com/store/apps/details?id=com.decodeckgame.decodeck">Android</a>, and <a href="https://store.steampowered.com/app/2296050">Steam</a>.</p>
<h2>About the game</h2>
<p>Deco Deck is a new kind of logic puzzle.  If you like KenKen or Two Not Touch, you might like Deco Deck.</p>
<p>Here’s what a mini puzzle looks like:</p>
<p><img alt="A screenshot of the game Deco Deck: mini, unfilled" src="https://novalis.org/blog/images/deco-deck-mini-small.jpg"/></p>
<p>Every card has one of five suits, and a number from 1-9.</p>
<p>The goal is to link up the cards in connected groups of five, such
that each group forms a valid “hand”.  The hands are: straight, flush,
full house, five-of-a-kind, and rainbow.  A rainbow is one card of
each suit.</p>
<p>Each puzzle has only one solution.</p>
<p>To solve, just link up the cards:</p>
<p><img alt="An animation Deco Deck: a trivial mini, being solved" src="https://novalis.org/blog/images/deco-deck-mini-partial-small.jpg"/></p>
<p>Of course, they’re not all that easy.  That puzzle is easier than any
puzzle in the game itself.  It is the trivial puzzle that I use in the
tutorial.  I chose it so that there’s no way to go down a wrong path.
And it’s got the flush of blue hexagons, which the tutorial is able to
describe as “blue” (for people with normal vision), or “hexagons” (for
colorblind people).  The other shapes don’t have short, unambiguous
names.</p>
<p>Here’s a harder puzzle:</p>
<p><img alt="A screenshot of the game Deco Deck: mini, partially filled" src="https://novalis.org/blog/images/deco-deck-mini-partial-small.jpg"/></p>
<p>Both of the above hands, marked in gold, are valid hands – but one of
them isn’t part of the actual solution.</p>
<p><img alt="A screenshot of the game Deco Deck: large, unfilled" src="https://novalis.org/blog/images/deco-deck-large-small.jpg"/></p>
<p>Puzzles come in four sizes.  The above is a “large”, which is 90
cards.  You already saw mini (30); there are also medium (60) and huge
(120) puzzles.  Of course, it would be possible to make puzzles of
nearly any size, but it wouldn’t be reasonable to put them on a phone
screen.  Even the huge is pushing the limits of finger dexterity on
smaller phones.</p>
<h2>Design</h2>
<p>As I mentioned at the end of <a href="https://novalis.org/blog/2022-12-12-mosaic-river-my-third-indie-game.html">my post about Mosaic
River</a>,
a dilemma in the design of the tile placement subgame put me in mind
of logic puzzles.  So I built a puzzle generator.  The first version
just spat out the puzzle in tab-separated value format:</p>
<table style="border:1px solid black">
<tr><td style="border:1px solid black"> A3 </td><td style="border:1px solid black"> A4 </td><td style="border:1px solid black"> A5 </td><td style="border:1px solid black"> B6 </td><td style="border:1px solid black"> C9 </td></tr>
<tr><td style="border:1px solid black"> D2 </td><td style="border:1px solid black"> D5 </td><td style="border:1px solid black"> E1 </td><td style="border:1px solid black"> C5 </td><td style="border:1px solid black"> C7 </td></tr>
<tr><td style="border:1px solid black"> B4 </td><td style="border:1px solid black"> A2 </td><td style="border:1px solid black"> A1 </td><td style="border:1px solid black"> C4 </td><td style="border:1px solid black"> C7 </td></tr>
<tr><td style="border:1px solid black"> C7 </td><td style="border:1px solid black"> A2 </td><td style="border:1px solid black"> A2 </td><td style="border:1px solid black"> A9 </td><td style="border:1px solid black"> D9 </td></tr>
<tr><td style="border:1px solid black"> B2 </td><td style="border:1px solid black"> E3 </td><td style="border:1px solid black"> E2 </td><td style="border:1px solid black"> B1 </td><td style="border:1px solid black"> A9 </td></tr>
<tr><td style="border:1px solid black"> C8 </td><td style="border:1px solid black"> A8 </td><td style="border:1px solid black"> D5 </td><td style="border:1px solid black"> B9 </td><td style="border:1px solid black"> A9 </td></tr>
</table>
<p>Then I popped it into a spreadsheet and used the coloring functions
there to mark the hands.  (I guess I could have printed it and used a
pencil, but I don’t keep my printer connected).  This proved that puzzles
were (a) solvable by humans and (b) fun to solve.  I immediately sent the
uncolored spreadsheet to some friends, with instructions.  But then
I realized that building a front-end in Godot would be really easy.</p>
<p><img alt="A screenshot of an early prototype the game Deco Deck: programmer art" src="https://novalis.org/blog/images/deco-deck-proto-1.png"/></p>
<p>OK, not the most beautiful, but it only took me a few hours to bang
together.  Godot spat out a HTML5 version, and I told my friends to
disregard the spreadsheet and try the interactive version.  The
feedback was positive.  One friend noticed that the difficulty range
wasn’t very large – later, I’ll explain how I solved that.</p>
<p>I decided to put in some more work to make it prettier:</p>
<p><img alt="A screenshot of a different early prototype the game Deco Deck: programmer art" src="https://novalis.org/blog/images/deco-deck-proto-2.png"/></p>
<p>I recognize that this is not in fact much prettier.  I wasn’t really
sure what it should look like.  Then a friend introduced me to his
friend, who happened to be a graphic designer.  I hired him to do the
visual design.  We considered all sorts of themes: Japanese flowers,
butterflies, amoebas, and 90s cyberpunk. But I decided that I liked
Art Deco best.  It’s very much a programmer’s sort of art – produced
by the intersections of simple shapes at common angles.  Designed to
be built by craftspeople rather than artists.</p>
<p>Without Benjamin, Deco Deck would not have looked nearly this good.  I
tried to make some Deco-style cards, but they ended up visually busy,
and not really very Deco (that is, not <a href="https://dacuteturtle.livejournal.com/961529.html">vertically
symmetric</a>).  It’s
actually a little tricky in 2023 to do Art Deco, because our eyes have
been trained by modern styles.  So, we expect bezier curves instead of
circular arcs, since that’s what’s easy to do in vector editors.</p>
<p><img alt="Some ugly almost Art Deco cards" src="https://novalis.org/blog/images/deco-deck-my-deco.png"/></p>
<p>Later, I tried to design the card backs (a visual flourish seen only
for an instant during loading), and instead of Art Deco, I ended up
with Fart Deco.</p>
<p><img alt="An Art Deco abstract pattern that looks a bit like a person's rear end with a spray coming out of it" src="https://novalis.org/blog/images/deco-deck-fart-deco.png"/></p>
<p>So I’m very glad that I had a good designer to work with.</p>
<h2>Rainbows</h2>
<p>When I first designed the game, I didn’t think of rainbows, because
they’re not a standard poker hand.  If they were a poker hand, they
wouldn’t be a strong one: with this deck of cards, they would lose to
a straight.  But I got to thinking about how suits were only used for
flushes, and what a shame that was, and then I remembered that I had
five suits.  Once I added rainbows, I found myself hooked.  The
rainbow’s weakness as a poker hand is its strength as a puzzle
component: it increases the number of hands that each card can be part
of, making the puzzle harder.  This fixed the difficulty range problem
that my friend had identified.</p>
<h2>Puzzle generation</h2>
<p>Building a puzzle generator was straightforward: I started by building
a little library that would generate a random pentomino tiling of
given dimensions.  The simplest representation of such a board during
the generation process is a bitmask (which fits in a register for even
huge boards, so long as you’re willing to use SSE registers).</p>
<p>Then I implemented the constraint propagation algorithm from <a href="https://norvig.com/sudoku.html">Norvig’s
Sudoku solver</a>, with the additional
wrinkle that it would report if multiple solutions were possible.
Instead of marking squares with a list of possible numbers, I marked
cards with a list of possible “situated pentominos” that it could be
part of.  A situated pentomino is a pentomino, possibly rotated and
reflected, with a given top-left coordinate.  Or, if you prefer, a
list of five coordinates, which are orthogonally connected.
Propagation consists of two different inferences: (1) if a card is
part of only one pentomino, then no different pentominos may contain
that card.  (2) if all pentominos for two cards share some third card,
then the third card can only include pentominos from the set of shared
cards.  The second of these isn’t strictly necessary, but it does make
solving much faster.</p>
<p>So
generating a puzzle works like this:</p>
<ol>
<li>Tile the board with random pentominos</li>
<li>Generate a random hand for each pentomino</li>
<li>Check how many solutions the puzzle has.
<ol>
<li>If zero: there’s a bug.</li>
<li>If more than one: pick a random card which could belong to
multiple polyominos; re-randomize the polyomino that it’s supposed to
belong to.</li>
<li>If one: ship it!</li>
</ol></li>
</ol>
<p>Of course, there was a bug in my first version of this – the annoying
kind of bug which causes correct results, but too slowly. So I
thought, “oh well, I’ll have to reimplement it in C++”.  Half way through
the reimplementation, I went to sleep, and when I woke up I realized what
the bug was.  So I threw away the C++.</p>
<p>As I generate puzzles, I also track the maximum depth that the search
has to go down to.  The theory is that deeper searches correlate with
harder puzzles.  So does a wider set of initial possibilities – that
is, more possible pentomino per card.  In theory, I could have tracked
the size of the entire search tree, but in my testing, it didn’t seem
to make much difference (and the size of the tree depends on the
search order, since a lucky search choice can propagate out to
eliminate zillions of possibilities).  This is one of the two axes
on which I rate puzzles.</p>
<p>The other axis is quality.  A puzzle that has all of its complexity in
one corner is boring.  A puzzle that’s mostly one color is ugly (and
the solve gets easy once you know the trick).  A puzzle that has
flushes on the top and straights on the bottom is less good than one
that has them intermixed.  I have eight quality metrics.  A weighted
sum of these metrics is the puzzle’s quality.  I generated millions of
puzzles, and the final game contains only the top few percent of them.
(Of course, it would have been possible to change the puzzle generator
to incorporate the quality metrics, but by the decide I knew what the
quality metrics should look like, I had already generated zillions of
puzzles).</p>
<h2>Money</h2>
<p>I decided to try a third revenue model.  I was inspired here by
<a href="https://playknotwords.com/">Knotwords</a>: daily free puzzles, and a
subscription for addicts.  Like the New York Times Crossword, and like
Knotwords, Deco Deck puzzles are easy on Monday and get harder as the
week goes on.  Unlike Knotwords, Deco Deck puzzles don’t get bigger as
the week goes on.  The mini is always free, and each day, one of the
other three sizes is free; I loop through them.  So, on day 1 there’s
a free medium, on day 2 there’s a free large, on day 3 a huge, and on
day 4 back to a large. So free users get to experience all of the
sizes at all of the difficulty levels over the course of three weeks.</p>
<p>The Steam version is just a straight up one-time payment.  I didn’t
feel like dealing with a whole other in-app purchasing system.</p>
<p>I do all of the puzzles very day (although I do sometimes use a hint
on the large or huge Saturday or Sunday puzzles).  I’m totally hooked,
and I hope you’ll get hooked too.</p>
<h2>Development</h2>
<p>This one took much longer than expected.  When I started this project,
I told my wife that I would aim for four or five games in my first
year.  I’m barely hitting three.  One reason is that my kid’s
preschool unexpectedly shut down for a month, leaving me with extra
childcare duties.</p>
<p>Also, getting the visual design right took a long time.  One minor
example: on the Monthly puzzles screen, it needs to be clear that you
can scroll within each difficulty level.  So the layout needs to be
tweaked so that, regardless of screen size, a puzzle is half-exposed
on the right.</p>
<p><img alt="Deco Deck's monthly puzzle screen" src="https://novalis.org/blog/images/deco-deck-monthly-small.jpg"/></p>
<p>There are also two exciting new developments in my practice: First, I
discovered <a href="https://posthornpr.com/">Post Horn PR</a>, a group that does
PR for indie games.  So as this blog post goes out, a press release
will also hit hundreds of game journalists’ inboxes.  I’m grateful
to them for their help.</p>
<p>Second, I was playing Deco Deck on the train while taking my kid
somewhere, and she wanted to try it out.  She is four, so she doesn’t
fully get what’s going on.  But she can enjoy the sensation of linking
and unlinking the numbers, and watching them turn colors.  And as I
suggest connections, she is learning: now she knows what a flush is. I
think she especially loves Deco Deck because it’s something her dad
made.</p>
<p>Most of the other tablet games that we’ve found for her are, frankly,
crappy.  There’s the awful critter one which really wants you to spend
money on one or more of their in-game currencies.  There’s the one
that’s supposed to teach math, where getting the question wrong offers
a more fun animation than getting it right.  Also, one of its
subgames is supposed to teach something about even numbers or
division, but actually just teaches trial-and-error.  Oh, and it had a
gratuitous Christmas thing.  I’m an evangelical atheist. I don’t need
my kid being proselytized to.  Can’t we have math without religion?
(I wouldn’t object to the existence of an explicitly Christian math
game, but I also wouldn’t get it for my kid).</p>
<p>Oh, and then there’s the one that’s supposed to teach reading, where
after every lesson, no matter how badly you do, you get a sticker
which you then have to place in your sticker book.  Sticker book?  Who
needs a fucking sticker book?  Reading is the key that opens the world
of books!  You don’t need a sticker: your reward is that you
accomplished the task.  You learned that C makes the sound at the front
of “cat” (it’s always “cat”.  Always.)  Also, it doesn’t do voice
recognition, so it can’t possibly teach reading, and also also some of
its early tasks are timed, which makes no sense at all for a tiny kid
first learning a skill.</p>
<p>And there’s another that has a bunch of different subgames, but one is
so much more fun than the others that they have to gate it: you have
to play a bunch of the less-fun games before they let you have one go
at the fun one.  Their actual reason is probably that the fun one is
this: you draw on an egg, and then the egg hatches into a critter with
your drawing mapped onto its skin.  Then they have to store that
critter and display in your menagerie, and they don’t want to use up
all of your storage space.  But that’s not the right solution: the
right solution would be to have a hard limit on the number of
critters.  Then either allow re-coloring an existing critter, or allow
you to send excess critters to a farm upstate.</p>
<p>So I am going to make a game that I want my kid to play.  It’ll be
between ten and twenty small games or other activities.  They will
mostly not be explicitly educational – no arithmetic worksheets or
anything like that.  But they will require cognitive skills.  They will
have intrinsic rewards: yes, there’s a fanfare sound when you solve
one, but the real reward is that you did the thing.  You accomplished
something hard.  So far, I’ve got prototypes of four of the games: a
working memory game (the game gives you a sequence, you repeat it), an
inductive logic game, a game where you move a chess knight, and a
graph isomorphism game.  What’s a graph isomorphism game?</p>
<p><img alt="Eleven hexagons, each with a bee at its center.  Some bees are connected to others by lines." src="https://novalis.org/blog/images/intrinsic-alpha-iso.jpg"/></p>
<p>I’m glad you asked.  My original idea was that you would have two
graphs, and you would have to prove that they were isomorphic by
rearranging the nodes in one to match the other.  (I had this idea
because I was thinking about how the aspect ratio on modern phones is
roughly 2:1 and I wondered what I could do with two squares).  But
when I showed the original concept to a friend, he didn’t really get
it. And then I realized that I could just do direct manipulation, and
that the concept was simple enough for a four year old.</p>
<p>One nice thing about building a game for my kid is that I have a
tester right there, and she is very excited to try things out.  So I
get immediate feedback on what’s working.  And also unsolicited
advice: everything in the game has to be bugs, because once she
saw the bees, she got excited.</p>
<p>Intrinsic (working title) is coming probably in late 2023 or early
2024.  Tablets and desktop only.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Rarely seen game mechanics]]></title>
    <link href="https://novalis.org/blog/2023-05-02-rarely-seen-game-mechanics.html"/>
    <published>2023-05-02T11:34:59-04:00</published>
    <updated>2025-03-20T10:13:13.050694-04:00</updated>
    <id>https://novalis.org/blog/2023-05-02-rarely-seen-game-mechanics.html</id>
    <content type="html"><![CDATA[<p><a href="https://blog.plover.com/notes/alien-poker.html">Dominus wrote about games played by
aliens</a>.  He believes
(and I agree) that aliens play Go, and something like poker.  And he
wonders at the paucity of auction games (I should note that they are a
bit more common among hobby board games: Reiner Knizia has five, and
<a href="https://danluu.com">Dan Luu</a> was just telling me about <a href="https://boardgamegeek.com/boardgame/164698/fresh-fish">Fresh
Fish</a>, which
I’m eager to try).</p>
<p>Before I even go into some other game mechanics, I want to digress a
bit about poker.</p>
<p>Everyone knows that poker is pointless unless played for real money.
This is because the right thing in poker is to fold most of the time,
but folding is boring.  The only thing that will convince you to play
right is the prospect of losing money.  But what if there’s another
way?  Imagine a game that plays exactly like Texas Hold’em
(no-rebuys and tournament-style, meaning that everyone starts with the
same amount of chips), but with the following change: when you win a
hand, the chips you win get turned into victory points and added to
your VP total.  You can’t use them as chips again.  Now, if you go
all-in, you will not play another hand even if you win.  But maybe you
will win enough VP to wind up the eventual game winner.  This game
still sucks by modern standards, because it involves player
elimination, but I wonder if it could be the basis of a more
reasonable game. You could fix the player elimination by giving
everyone a few chips at the start of every hand, but then you need
some way to end the game.  Maybe the first one to 500 points wins?</p>
<p>Ok, end digression.  On to some infrequently-used game mechanics.</p>
<h1>Perception</h1>
<p>Some time ago, I invented a game where you try to determine physical
quantities.  Like, you’re given a box full of weights, and you have to
determine how many grams it is, just by hefting it. Or you’re given a
rod and asked to figure out how long it is (probably no touching or
measuring against your hands allowed).  You could do temperature (but
only within a narrow range, and it would be tricky to implement),
luminous intensity, and time too.  My friend Jay suggested absolute
pitch, which I hate because I am totally non-musical, but it clearly
fits the game.</p>
<p>One of my favorite experiments involves pitch (in some sense): it
turns out that the <a href="https://www.npr.org/sections/thesalt/2014/04/17/290896594/sichuan-peppers-buzz-may-reveal-secrets-of-the-nervous-system">frequency of the tingle of Sichuan peppercorns is
50Hz</a>.</p>
<p>One of the few perception games I know of is played in Ethiopia.  A
friend of mine went there to design games for girls.  She said that
the girls never wanted to use randomness in their games.  To select a
first player or whatever, they would instead hide three stones in one
hand and four in another, and ask another player to figure out which
hand had more stones.  Of course, this is also a deception game.</p>
<h1>Short-term memory</h1>
<p>Many card games that involve counting use the short-term memory.  But
I’m imagining something where the memory is explicitly the mechanic.
Like <a href="https://en.wikipedia.org/wiki/Simon_(game)">Simon</a>, but
multiplayer.</p>
<p><a href="https://www.youtube.com/watch?v=nTgeLEWr614">Watch a chimp kick our asses at a short-term memory game</a>.</p>
<h1>Pain tolerance</h1>
<p>Dominus suggests a version of chess where you can make your opponent
take a move back by chopping off one of your fingers.  This is rather
permanent (at least for humans).  But what about temporary pain?</p>
<p>In Philip K. Dick’s <em>Eye In The Sky</em>, a character sticks
his hand over a cigarette lighter to prove how holy he is.</p>
<blockquote>
<p>“Ordeal by fire,” Brady explained, igniting the lighter. A flash of
  yellow flame glowed, “Show your spirit. Show you’re a man.”</p>
</blockquote>
<blockquote>
<p>“I’m a man,” Hamilton said angrily, but I"ll be damned if I’m going to
  stick my thumb into that flame just so you lunatics can have your
  frat-boy ritualistic initiation. I thought I got out of this when I
  left college.”</p>
</blockquote>
<blockquote>
<p>Each technician extended his thumb.  Methodically, Brady held the
  lighter under one thumb after another.  No thumb was even slightly
  singed.</p>
</blockquote>
<blockquote>
<p>“You’re next,” Brady said sanctimoniously.  “Be a man, Hamilton.
  remember you’re not a wallowing beast.”</p>
</blockquote>
<p>This is, of course, not about pain – the technicians really are being
protected by God (or, what passes for God in the reality that Hamilton
finds himself stuck in).  But it gets the idea across: this is a
game that people could play, if only we weren’t such wimps.</p>
<p>If you wanted to make a safe version of the cigarette lighter game,
you could use <a href="https://en.wikipedia.org/wiki/Thermal_grill_illusion">the thermal grill
illusion</a>. I
would actually buy a thermal grill illusion device if someone made a
commercial version.</p>
<p><a href="https://en.wikipedia.org/wiki/World_Sauna_Championships">The World Sauna
Championships</a>
were, I guess, a version of this.  One competitor described it as
“quite possibly the world’s dumbest sport”.  As you can probably
predict, someone died and they canceled the event.</p>
<p><a href="https://en.wikipedia.org/wiki/Robert_Yang">Robert Yang</a> made a game
about a video of men hurting each other. Competitively?  Definitely in
some sense. <a href="https://www.youtube.com/watch?v=O_TAeq9pJNY">Hard Lads</a>
is among the safest-for-work of Yang’s games, but I still would not
watch it in any office I have ever worked in.  I don’t claim Yang’s
game itself is an instance of pain as a game mechanic – but rather
that it might portray such a game.</p>
<h1>Conclusion</h1>
<p>I mostly just wanted an excuse to quote PKD and link to Robert Yang
and the Sichuan peppercorn thing.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Mosaic River, my third indie game]]></title>
    <link href="https://novalis.org/blog/2022-12-13-mosaic-river-my-third-indie-game.html"/>
    <published>2022-12-13T13:46:29-05:00</published>
    <updated>2025-03-20T10:13:12.866694-04:00</updated>
    <id>https://novalis.org/blog/2022-12-13-mosaic-river-my-third-indie-game.html</id>
    <content type="html"><![CDATA[<h2>Game overview</h2>
<p>I just released a new game!</p>
<p><a href="https://mosaicriver.fun">Mosaic River</a> 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.</p>
<p>You can
try it now: it’s free (ad-supported) on <a href="https://apps.apple.com/us/app/mosaic-river/id6444349912">iOS</a> and <a href="https://play.google.com/store/apps/details?id=fun.mosaicriver.mosaicriver">Android</a>.</p>
<p>It’s perhaps easiest to explain by describing some of the influences.</p>
<h2>Influences</h2>
<p>The first is Uwe Rosenberg’s
<a href="https://boardgamegeek.com/boardgame/163412/patchwork">Patchwork</a>, 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).</p>
<p><img alt="A screenshot of the game Mosaic River: the river" src="https://novalis.org/blog/images/mosaic-river-river.jpg"/></p>
<p>Another influence is <a href="https://en.wikipedia.org/wiki/Diffusion-limited_aggregation">Diffusion-limited aggregation
(DLA)</a>.
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.</p>
<p><img alt="A screenshot of the game Mosaic River: the mosaic" src="https://novalis.org/blog/images/mosaic-river-mosaic.jpg"/></p>
<p>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 <a href="https://www.egyptianhistorypodcast.com/">History Of Egypt</a>
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.</p>
<h2>Ads</h2>
<p>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.</p>
<p>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.)</p>
<p>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.</p>
<h2>Challenges</h2>
<h3>Scaling</h3>
<p>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%).</p>
<p>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.</p>
<h3>Google’s Kafkaesque process</h3>
<p>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.</p>
<h3>Godot-Admob bugs; Apple bugs</h3>
<p><strong>edit</strong></p>
<p>Of course, as soon as I released, someone pointed me to <a href="https://github.com/Poing-Studios/godot-admob-ios/issues/34">an
issue</a>
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 href="https://developer.apple.com/forums/thread/90725">a random Apple bug</a>
that Apple, of course, didn’t report on their system status page.  It
eventually fixed itself.  The fixed version is now released.</p>
<p><strong>end edit</strong></p>
<h3>Art direction</h3>
<p>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.</p>
<p>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.</p>
<h3>Shader performance</h3>
<p>I used <a href="https://www.materialmaker.org/">Material Maker</a> 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.</p>
<p>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.</p>
<p>I definitely noticed that Material Maker does not have the ability to
optimize <a href="https://github.com/RodZill4/material-maker/issues/536">one common
case</a>.  And
there was <a href="https://github.com/RodZill4/material-maker/issues/476">another missing
feature</a> too,
which I just hacked around in the end.</p>
<h3>Scoring and bonuses</h3>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<h2>Discovering America</h2>
<p>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:</p>
<ol>
<li><p>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).</p></li>
<li><p>The player could choose them during the game (interrupting flow and
forcing them to make choices that they would likely regret).</p></li>
<li><p>The game could consider all of the possbilities and choose the best
(creating an opaque scoring system).</p></li>
</ol>
<p>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!</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Response to some Hacker News comments on Stable Diffusion]]></title>
    <link href="https://novalis.org/blog/2022-12-10-response-to-some-hacker-news-comments-on-stable-diffusion.html"/>
    <published>2022-12-10T20:52:12-05:00</published>
    <updated>2025-03-20T10:13:12.978694-04:00</updated>
    <id>https://novalis.org/blog/2022-12-10-response-to-some-hacker-news-comments-on-stable-diffusion.html</id>
    <content type="html"><![CDATA[<p><a href="https://novalis.org/blog/2022-12-05-i-am-frustrated-with-stable-diffusion.html">Previously</a>, I reported on my attempt to use Stable Diffusion.</p>
<p><a href="https://danluu.com">Dan Luu</a> posted it to <a href="https://news.ycombinator.com/item?id=33902248">Hacker
News</a>, and there were
some comments.  Here are some responses:</p>
<p>Comments suggesting img2img, masking, and
<a href="https://github.com/AUTOMATIC1111/stable-diffusion-webui">AUTOMATIC1111</a>:
that’s what I was doing, as I think the images in the previous post
make clear.</p>
<p>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).</p>
<p>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.</p>
<p><img alt="A blue and orange ceramic vase with two necks" src="https://novalis.org/blog/images/leaning-vase.jpg"/></p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<p><img alt="A better version of the dock image, but now the dock seems to be made of stone" src="https://novalis.org/blog/images/dock-hn.jpg"/></p>
<p>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.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[I am frustrated with Stable Diffusion]]></title>
    <link href="https://novalis.org/blog/2022-12-05-i-am-frustrated-with-stable-diffusion.html"/>
    <published>2022-12-05T17:19:13-05:00</published>
    <updated>2025-03-20T10:13:12.950694-04:00</updated>
    <id>https://novalis.org/blog/2022-12-05-i-am-frustrated-with-stable-diffusion.html</id>
    <content type="html"><![CDATA[<p>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
<a href="https://www.youtube.com/watch?v=SzikIwPPle0">cardboard</a>, or cut
paper.  And I’ve considered AI-generated art.</p>
<p>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.</p>
<p>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.</p>
<p>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).</p>
<p><img alt="dock1" src="https://novalis.org/blog/images/dock1.jpg"/></p>
<p>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).</p>
<p><img alt="dock2" src="https://novalis.org/blog/images/dock2.jpg"/></p>
<p>Here’s what I got:</p>
<p><img alt="dock3" src="https://novalis.org/blog/images/dock3.jpg"/></p>
<p>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.</p>
<p><img alt="dock4" src="https://novalis.org/blog/images/dock4.jpg"/></p>
<p>Then I’ll tell Stable diffusion to just clean up those parts:</p>
<p><img alt="dock5" src="https://novalis.org/blog/images/dock5.jpg"/></p>
<p>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:</p>
<p><img alt="dock6" src="https://novalis.org/blog/images/dock6.jpg"/></p>
<p>Sure, we lost a post, but at this point, I don’t care.  Stable diffusion,
please clean up the clonejunk….</p>
<p><img alt="dock7" src="https://novalis.org/blog/images/dock7.jpg"/></p>
<p>No!  You fucked up the right side of my dock again! Don’t you know how
solid objects work?</p>
<p>Aargh, I give up.  I’ll just hire
<a href="https://en.wikipedia.org/wiki/Jean_Giraud">Mœbius</a> to do the artwork
for my game.  What’s that you say?  He’s dead?  Noooooo!</p>
<p>(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.)</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Surfwords update]]></title>
    <link href="https://novalis.org/blog/2022-09-01-surfwords-update.html"/>
    <published>2022-09-01T12:32:43-04:00</published>
    <updated>2025-03-20T10:13:12.938694-04:00</updated>
    <id>https://novalis.org/blog/2022-09-01-surfwords-update.html</id>
    <content type="html"><![CDATA[<p>The most important thing is that Surfwords now has a <a href="https://surfwords.com/demo.html">demo</a> available.</p>
<p>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.
<a href="https://surfwords.com">Surfwords</a> 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).</p>
<p>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.
<a href="https://en.wikipedia.org/wiki/Ghost_(game)">Ghost</a> is fun (if you’re
stuck in a car and bored of
<a href="https://en.wikipedia.org/wiki/Botticelli_(game)">Botticelli</a>).  The
combination is just obviously going to be fun.</p>
<p>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.</p>
<p>And then I’m going to go back to working on my next game.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[My second solo indie game]]></title>
    <link href="https://novalis.org/blog/2022-08-03-dev-diary--surfwords.html"/>
    <published>2022-08-03T16:40:38-04:00</published>
    <updated>2025-03-20T10:13:13.030694-04:00</updated>
    <id>https://novalis.org/blog/2022-08-03-dev-diary--surfwords.html</id>
    <content type="html"><![CDATA[<p>Thanks to the success of <a href="https://semantle.com">Semantle</a>, 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
<a href="https://surfwords.com">Surfwords</a>.  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).</p>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/2TAOtNNRyNc" title="YouTube video player" width="560"></iframe>
<p>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.</p>
<p>I was also inspired by <a href="https://superhexagon.com/">Super Hexagon</a>:
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.</p>
<p>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.</p>
<p><img alt="prefix OWNE; incoming left: X H A; incoming right: R R E" src="https://novalis.org/blog/images/surfwords-screenshot-3-small.jpg"/></p>
<p>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.</p>
<p>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 <a href="https://www.patrickcornelius.com/">Patrick
Cornelius</a>.  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.</p>
<p>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: <a href="https://www.nytimes.com/2020/10/16/crosswords/spellingbee-puzzles.html">I once sent some raffia to Will Shortz</a>
to protest the word’s non-inclusion in Spelling bee.</p>
<p>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:</p>
<p><img alt="OWNE is not a word; you should have gone for OWNER" src="https://novalis.org/blog/images/surfwords-screenshot-4-small.jpg"/></p>
<p>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.</p>
<p>Today, I’m announcing the release of <a href="https://gitlab.com/novalis_dt/words">my word
lists</a>.  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.</p>
<p>So much for the content.  Now, on to the technology.  I chose to use
the <a href="https://godotengine.org/">Godot Engine</a>.  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?").</p>
<p>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 <a href="https://github.com/godotengine/godot/issues/27491">refer to a class from inside itself</a>.</p>
<p>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
<a href="https://en.wikipedia.org/wiki/Trie">trie</a>.  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#.</p>
<p>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].</p>
<p>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.</p>
<p>I know that the code works because I have a suite of unit tests. Godot
has a third-party unit testing framework,
<a href="https://github.com/bitwes/Gut">GUT</a>.  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.</p>
<p>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?).</p>
<p><img alt="prefix: HAS; incoming left: H U Z; incoming right: A Q E" src="https://novalis.org/blog/images/surfwords-screenshot-hashue-small.jpg"/></p>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<p><img alt="prefix: BAI; incoming left: A, S, F; incoming right: L I X" src="https://novalis.org/blog/images/surfwords-screenshot-bailiff-small.jpg"/></p>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<ul>
<li>On a M1 Mac, building for the simulator doesn’t work.</li>
<li><a href="https://github.com/godotengine/godot/issues/62783">Rounded corners on mobile devices are not well
supported</a></li>
<li><a href="https://github.com/godotengine/godot/issues/56320">General polyline
badness</a></li>
<li>Slow text rendering (if you notice some choppiness during the splash
screen, that’s what’s going on in the background).  I wasted like a week
trying various ways to get around this, including doing my own text
rendering, but in the end, I gave up and accepted that I would have to have
jank somewhere and put it in the splash screen.</li>
<li>Regular Buttons don’t support different icons for
hover. TextureButtons do, but they aren’t styled like buttons.</li>
<li><a href="https://github.com/godotengine/godot-proposals/issues/867">No built-in set data
type</a></li>
<li>The Google Play Games Services plugin has three different versions
(corresponding to different Godot versions, none of which is the
current version), and they’re all based on v1 of the API, which
requires full internet permissions. To be fair, Google’s Play Games Services
examples are, as of this writing, also based on v1, and Google’s
messaging on this could use some help.  In the end, I rewrote just
the portion that I cared about to use v2.</li>
<li><a href="https://github.com/godotengine/godot/issues/61055">Out line font fading doesn’t work
right</a>.  I
decided to just live with this, but it is ugly.</li>
<li>Full screen didn’t work on OS X due to some random setting (possibly
<code>window/stretch/aspect="keep"</code>) – I just differentially debugged
until it started working.</li>
<li><a href="https://github.com/godotengine/godot/issues/47005">Dialogs get weirdly long</a></li>
</ul>
<p>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:</p>
<blockquote>
<p>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.</p>
</blockquote>
<p>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.</p>
<p>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 <a href="https://novalis.org/blog/play-games-hack.patch">remove the
provider</a> (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).</p>
<p>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
<a href="http://dreamlo.com/">dreamlo</a>.  But I didn’t want to deal with the identity
management, so I didn’t.</p>
<p>Another thing that didn’t work: I wanted to do a cool flowing
wave background.  I was using
<a href="https://www.materialmaker.org/">Material Maker</a>.  I ran into a few
minor issues with Material Maker itself – for instance, <a href="https://github.com/RodZill4/material-maker/issues/476">a slight
annoyance which required me to manually hack my shader after
export</a>.  But
it was pretty easy to use, and the model is easy to understand.</p>
<p>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.</p>
<p>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 <code>rect_size</code> before <code>rect_min_size</code> (which doesn’t work: <code>rect_size</code> is clamped to <code>rect_min_size</code>).  And some of it is because
making the game portion of the UI adjust is really tricky: what size
do users actually want?</p>
<p>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 <code>expand_margin_*</code> settings – which move the border
outside of the requested area of the dialog (requiring the dialog to
be manually shrunk to accommodate it).</p>
<p>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 <a href="https://danluu.com">Dan Luu</a>, John, Sky, Josh, Praveen, and
Rachel for expecially useful feedback, but thanks to all playtesters.</p>
<p>Surfwords is now available for <a href="https://novalis-dmt.itch.io/surfwords">Windows, Mac, and
Linux</a>, as well as <a href="https://apps.apple.com/us/app/surfwords/id1633315523">iOS</a> and
<a href="https://play.google.com/store/apps/details?id=com.surfwords.surfwords">Android</a></p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Perhaps The Stars]]></title>
    <link href="https://novalis.org/blog/2021-11-15-perhaps-the-stars.html"/>
    <published>2021-11-15T10:42:31-05:00</published>
    <updated>2025-03-20T10:13:12.962694-04:00</updated>
    <id>https://novalis.org/blog/2021-11-15-perhaps-the-stars.html</id>
    <content type="html"><![CDATA[<p>This post includes spoilers for:
- <cite>Perhaps The Stars</cite>
- <cite>Worm</cite>
- <cite>Worth The Candle</cite>
- <cite>The Wave (1981 film)</cite></p>
<p><br/>
<br/></p>
<p>For me, Bridger’s narrative-warping powers destroyed <cite>Perhaps The
Stars</cite> as a novel.  I don’t think it was the only flaw – but it
was the flaw from which the novel could not recover.</p>
<p>The problem with narrative-warping powers is both that it destroys the
characters’ agency (even, in <cite>Perhaps The Stars</cite>, 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.</p>
<p>It didn’t matter that Mycroft made decisions which lead to his death
(twice), because the plot demanded that he return.</p>
<p>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.</p>
<p>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, <cite><a href="https://en.wikipedia.org/wiki/The_Taking_of_Joppa">The
Taking of
Joppa</a></cite>, 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 <cite>The
Taking of Joppa</cite>, which is not an excuse that Faust has
available).</p>
<p>So why did <cite>Worth The Candle</cite> work?  <cite>Degenerate
Cycles</cite> (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.</p>
<p>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 <cite>Perhaps The Stars</cite>.  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.</p>
<p>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.</p>
<p>Frist, Gordian.  Prior to <cite>Perhaps The Stars</cite>, 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.</p>
<p>I just started listening to <cite><a href="https://www.humanetech.com/podcast">Your Undivided
Attention</a></cite>, 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):</p>
<p>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?</p>
<p>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?</p>
<p>(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).</p>
<p>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.  <a href="https://slatestarcodex.com/2014/08/16/an-iron-curtain-has-descended-upon-psychopharmacology/">This
article</a>
aside, generally useful technologies spread unless something stops
them.  And German isn’t enough.</p>
<p>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 <a href="https://en.wikipedia.org/wiki/Freedom_to_roam">freedom to
roam</a>.  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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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 <a href="https://en.wikipedia.org/wiki/One_of_Us_(Joan_Osborne_song)">one of
us</a>. 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.</p>
<p>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.  <cite>Perhaps The Stars</cite> 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 <a href="https://crookedtimber.org/2004/06/18/by-the-power-of-stipulation-i-have-the-power/">philosophical
novel</a>;
in actual reality, the unaccountable killers who claim they’re
protecting us are <a href="https://www.reuters.com/world/asia-pacific/us-military-says-10-civilians-killed-kabul-drone-strike-last-month-2021-09-17/">stunningly
incompetent</a>).
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.</p>
<p>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?”</p>
<p>And “So what?” is, unfortunately, my reaction to the entire denouement
of the book.</p>
<p>A few more things:</p>
<ol>
<li><p>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.</p></li>
<li><p>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.</p></li>
<li><p>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 <a href="https://ageofem.com/">ems</a> run
faster, that would feel like minutes, or hours, or days. And if
they run slower, then we waste lifetimes as the sun darkens.”</p></li>
<li><p>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.</p></li>
</ol>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Pottery, at the beginning of 2020]]></title>
    <link href="https://novalis.org/blog/2020-02-01-pottery-at-the-beginning-of-2020.html"/>
    <published>2020-02-01T23:19:37-05:00</published>
    <updated>2025-03-22T11:04:29.275372-04:00</updated>
    <id>https://novalis.org/blog/2020-02-01-pottery-at-the-beginning-of-2020.html</id>
    <content type="html"><![CDATA[<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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?</p>
<video controls="" height="480" loop="" width="640">
<source src="https://novalis.org/blog/images/ceramics-2/handles.mp4" type="video/mp4"/>
</video>
<p>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.</p>
<p>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.</p>
<p><img alt="Stacked slabs 1" src="https://novalis.org/blog/images/ceramics-2/stacked-slabs-1-small.jpg" title="Stacked slabs 1"/></p>
<p>Then I did the same, but with one vertical strip.</p>
<p><img alt="Stacked slabs 2" src="https://novalis.org/blog/images/ceramics-2/stacked-slabs-2-small.jpg" title="Stacked slabs 2"/></p>
<p>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.</p>
<p><img alt="Finial" src="https://novalis.org/blog/images/ceramics-2/finial-small.jpg" title="Finial"/></p>
<p>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.</p>
<p><img alt="Two vases who love each other very much" src="https://novalis.org/blog/images/ceramics-2/love-small.jpg" title="Two vases who love each other very much"/></p>
<p>Then I made a taller vase with the same general concept. It barely fit
in my kiln.</p>
<p><img alt="Two vases who love each other very much II" src="https://novalis.org/blog/images/ceramics-2/twisted-small.jpg" title="Two vases who love each other very much II"/></p>
<p>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.</p>
<p><img alt="Vase with folded arms" src="https://novalis.org/blog/images/ceramics-2/folded-arms-small.jpg" title="Vase with folded arms"/></p>
<p>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
<a href="https://www.licartists.org/back-to-the-table">Back to the Table</a>, an
exhibit of tableware at the Plaxall Gallery in Long Island City.</p>
<p><img alt="Nine-necked Vase" src="https://novalis.org/blog/images/ceramics-2/nine-small.jpg" title="Nine-necked Vase"/></p>
<p>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.</p>
<p>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.</p>
<p>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:</p>
<a href="https://www.instagram.com/p/BpKTo5-gWDg/">
<img alt="Coyote Teapot" src="https://novalis.org/blog/images/ceramics-2/coyote-teapot-small.jpg" title="Coyote Teapot"/>
</a>
<p>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:</p>
<p><img alt="Vase with Valley Folds" src="https://novalis.org/blog/images/ceramics-2/valley-1-small.jpg" title="Vase With Valley Folds"/></p>
<p>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):</p>
<a href="https://www.instagram.com/p/BtlKoTBgfuU/?utm_source=ig_web_copy_link">
<img alt="Icosahedron Teapot" src="https://novalis.org/blog/images/ceramics-2/icosahedron-small.jpg" title="Icosahedron Teapot"/>
</a>
<a href="https://www.instagram.com/p/Bozt1nXAwna/?utm_source=ig_web_copy_link">
<img alt="Tetrahedron Teapot" src="https://novalis.org/blog/images/ceramics-2/tetrahedron-small.jpg" title="Tetrahedron Teapot"/>
</a>
<a href="https://www.instagram.com/p/BpmpptCBFfc/?utm_source=ig_web_copy_link">
<img alt="Octahedron Teapot" src="https://novalis.org/blog/images/ceramics-2/octahedron-small.jpg" title="Octahedron Teapot"/>
</a>
<p>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:</p>
<a href="https://www.instagram.com/p/B7B-whvgPfg/?utm_source=ig_web_copy_link">
<img alt="Alien apple" src="https://novalis.org/blog/images/ceramics-2/alien-apple-small.jpg" title="Alien Apple Vase"/>
</a>
<p>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.</p>
<p><img alt="Nudibranch Vase" src="https://novalis.org/blog/images/ceramics-2/nudibranch-small.jpg" title="Nudibranch vase"/></p>
<p>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.</p>
<p><img alt="Cathedral Vase I" src="https://novalis.org/blog/images/ceramics-2/cathedral-vase-1-small.jpg" title="Cathedral vase I"/></p>
<p>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.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[A problem I don&#39;t know how to solve]]></title>
    <link href="https://novalis.org/blog/2018-09-04-a-problem-i-dont-know-how-to-solve.html"/>
    <published>2018-09-04T01:27:06-04:00</published>
    <updated>2025-03-20T10:13:13.038694-04:00</updated>
    <id>https://novalis.org/blog/2018-09-04-a-problem-i-dont-know-how-to-solve.html</id>
    <content type="html"><![CDATA[<p>A friend asked: “Why aren’t you working on the development of a
decentralized communications platform?”</p>
<p>My answer was that I don’t know how to solve the unwanted
communication (spam, brigading, etc) problem.</p>
<p>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
<a href="https://github.com/tootsuite/mastodon/issues/698">mastodon issue tracker</a>,
and did not get much traction.</p>
<p>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
<a href="https://www.w3.org/TR/activitypub/">ActivityPub</a> standard) works:</p>
<p>There are a number of servers
(e.g. <a href="https://mastodon.social">mastodon.social</a>,
<a href="https://oulipo.social">oulipo.social</a>, 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).</p>
<p>So things that disabling replies could mean include:</p>
<ol>
<li>I configure my server to not notify me about replies (i.e. they do not appear in my inbox)</li>
<li>I configure my server to not forward replies.</li>
<li>I add a field to my message indicating that I do not wish for
people to reply to it, and other servers will enforce this in their
UI.</li>
</ol>
<p>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,
<a href="https://github.com/w3c/activitypub/issues/319">here</a>, someone
suggesting requiring ("must”, in RFC-speak) the third,
unenforceable option.</p>
<p>I also saw a suggestion to implement a proof of work system,
<a href="https://en.wikipedia.org/wiki/Hashcash">Hashcash</a>, 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.</p>
<p>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.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Ceramics update]]></title>
    <link href="https://novalis.org/blog/2018-02-26-ceramics-update.html"/>
    <published>2018-02-26T23:31:52-05:00</published>
    <updated>2025-03-20T10:13:12.974694-04:00</updated>
    <id>https://novalis.org/blog/2018-02-26-ceramics-update.html</id>
    <content type="html"><![CDATA[<p>Since <a href="https://novalis.org/blog/2017-06-12-greebled-teapot.html">last time</a> I wrote, I’ve made
a few more pieces.  Note: pieces are not in chronological order.
A few technical details are at the end.</p>
<p>We’ll start with a recent one that I’m proud of:</p>
<p><img alt="rat vase" src="http://novalis.org/minceram/photos/2018-01-01T18-00-54.jpg" title="A black, pumice-textured, conical vase with sculpted gray rat heads
 and pink rat tails coming out of it"/></p>
<p>Yep, it’s a vase with rats coming out of it.  The black glaze is
<a href="https://glazy.org/recipes/1342">Marilee’s Lava</a> 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.</p>
<p>Here’s the first piece I made that I still like:</p>
<p><img alt="deco pot" src="http://novalis.org/minceram/photos/2017-07-10T19-42-19.jpg" title="A pot in a vaguely art-deco style"/></p>
<p>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.</p>
<p>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:</p>
<p><img alt="aleph vase" src="http://novalis.org/minceram/photos/2017-09-12T08-56-25.jpg" title="My hand holding a small rounded vase with slip decoration; an aleph is carved into the slip"/></p>
<p>One co-worker in particular got excited about the pottery, so I made
her a casserole:</p>
<p><img alt="casserole" src="http://novalis.org/minceram/photos/2018-02-26T17-57-29.jpg" title="A brown casserole containing a silver Maine Coon cat.  The lid is on, and the cat’s head is sticking out."/></p>
<p>My <a href="https://twitter.com/BigFloofs">cats</a> 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 <a href="http://shop.ceramicsupplyinc.com/s762-kitchenware---c-6-9.aspx">S762 kitchenware
clay</a>,
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.</p>
<p>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:</p>
<p><img alt="orcish teapot 1" src="http://novalis.org/minceram/photos/2017-10-25T08-27-06.jpg" title="A gray-green teapot with two pairs of horn-colored horns on the spout, one on the body and one on the lid."/></p>
<p>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.</p>
<p>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.  <a href="https://www.instagram.com/potteraguero/">Another potter</a> 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.</p>
<p><img alt="three-horn doorknob" src="http://novalis.org/minceram/photos/2018-02-26T18-11-28.jpg" title="A doorknob (in situ) consisting of three horns arranged radially around a black center"/></p>
<p>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.</p>
<p>Here’s that second orcish teapot:</p>
<p><img alt="orcish teapot
v2" src="http://novalis.org/minceram/photos/2018-02-26T18-14-45.jpg" title="A
metallic black teapot with two pairs of horns on the body, two at the
top of the handle, two on the spout, and a triad of horns as a lid
handle"/>.</p>
<p>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.</p>
<p><a href="http://johnbrittpottery.com/shop/the-complete-guide-to-mid-range/">Britt</a>
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.</p>
<p>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.</p>
<p>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:</p>
<p><img alt="skunk mug" src="http://novalis.org/minceram/photos/2018-01-24T07-10-10.jpg" title="A mug with a skunk head and tail.  Text on the mug reads ‘eat, spray, love’"/></p>
<p>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.</p>
<p>Another thing that inspired me to make animal forms was this Pikamug:</p>
<p><img alt="Pikachu mug" src="http://novalis.org/minceram/photos/2017-09-12T08-35-32.jpg" title="A mug representation of Pikachu: two bulges, yellow, red dimples and black smile"/> <img alt="Pikachu mug: tail" src="http://novalis.org/minceram/photos/2017-09-12T08-35-03.jpg" title="Same mug, rear view: brown stripes and a lightning bolt tail"/></p>
<p>Once I had made this for one cousin, I knew I would have to make
something for his sister, and their mom suggested Ponyta:</p>
<p><img alt="Ponyta mug" src="http://novalis.org/minceram/photos/2018-02-26T18-19-33.jpg" title="A mug
representation of the Pokemon Ponyta, with a head, a flaming tail, and
hooves"/></p>
<p>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.</p>
<p>Here’s a completely boring bowl where I like the glaze; it reminds me
of a night sky:</p>
<p><img alt="bowl of stars" src="http://novalis.org/minceram/photos/2018-02-12T08-57-39.jpg" title="A soup bowl with brown glaze and a spray of turquoise"/></p>
<p>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:</p>
<p><img alt="Bulldog jar" src="http://novalis.org/minceram/photos/2018-01-25T07-56-49.jpg" title="A blue jar with a light blue French bulldog sitting on the lid"/></p>
<p><img alt="Demon jar" src="http://novalis.org/minceram/photos/2018-02-26T19-50-12.jpg" title="A jar with a demon on the lid.  The demon has green skin, curly
horns, a ruff, a body that looks like a fluted column, a tail that’s a
series of rounded bulges with a black trifurcated end.  The lid has
black pumice-textured glaze."/></p>
<p>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.</p>
<p>Technical details:</p>
<p>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.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Variance and dynamic range in Lost Cities and Keltis]]></title>
    <link href="https://novalis.org/blog/2018-02-26-variance-and-dynamic-range-in-lost-cities-and-keltis.html"/>
    <published>2018-02-26T10:24:26-05:00</published>
    <updated>2025-03-20T10:13:13.034694-04:00</updated>
    <id>https://novalis.org/blog/2018-02-26-variance-and-dynamic-range-in-lost-cities-and-keltis.html</id>
    <content type="html"><![CDATA[<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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).</p>
<p>It’s always nice to have data to back up a theory, so I found <a href="https://www.reddit.com/r/boardgames/comments/4gu5w1/measuring_skill_in_games_lost_cities/">this
page</a>.
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.</p>
<p>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: <a href="https://boardgamegeek.com/boardgame/40832/keltis-das-kartenspiel">Keltis gets 6.7
on
BGG</a>,
while <a href="https://boardgamegeek.com/boardgame/50/lost-cities">Lost Cities gets
7.1</a>.</p>
<p>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
<em>reduce</em> the range.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Visual cryptography]]></title>
    <link href="https://novalis.org/blog/2017-10-17-visual-cryptography.html"/>
    <published>2017-10-17T01:42:20-04:00</published>
    <updated>2025-03-20T10:13:12.942694-04:00</updated>
    <id>https://novalis.org/blog/2017-10-17-visual-cryptography.html</id>
    <content type="html"><![CDATA[<p>There’s a really neat technique for doing simple encryption that
you can decrypt with your eyes.  It goes like this, assuming
that your data is a black-and-white image:</p>
<p><img alt="pixels" src="https://novalis.org/blog/images/visual-cryptography/pixels.png" title="A 16x16 pixel peace sign"/></p>
<p>First, make a new image with the same size as your original image.
Fill it in totally randomly.</p>
<p>Now, resize your random image to have twice as many pixels in each
dimension. Each 2x2 pixel square of the resized image gets
one of these “macropixels":</p>
<p><img alt="macropixels" src="https://novalis.org/blog/images/visual-cryptography/macropixels.png" title="Two 2x2 squares as described in the text"/></p>
<p>One has the top-left and bottom-right pixels black; the other has the
top-right and bottom-left pixels black.  Let’s say that we’ll replace
black pixels with the left image and white pixels with the right
image.  Your new image will have exactly half of its squares black,
and the other half white.  This is your key (although it doesn’t
actually matter which side is the “key” and which is the “data").
Here’s an example:</p>
<p><img alt="key" src="https://novalis.org/blog/images/visual-cryptography/key.png" title="A random-looking image"/></p>
<p>Now, take your original image, and encode it like this: where there’s
a black pixel, take the macropixel that’s <em>different</em> from your key,
and where there’s a white pixel, take the one that’s the <em>same</em> as
your key.</p>
<p><img alt="ciphertext" src="https://novalis.org/blog/images/visual-cryptography/ciphertext.png" title="Another random-looking image"/></p>
<p>Notice that this new ("ciphertext") image has no information from the
original image. If your original pixel was black, there’s a 50-50
chance that it will be the same as the black pixel from the key, and a
50-50 chance that it will be different.  It’s the visual version of
an xor-based one-time-pad.</p>
<p>Now comes the really cool part: to decrypt the image, you can
print the key on a transparency, and overlay it on the ciphertext:</p>
<p><img alt="decrypt" src="https://novalis.org/blog/images/visual-cryptography/decrypt.png" title="A plausible-looking decryption"/></p>
<p>You’ll see fully-black macropixels where the original image was black,
and half-tone where it was white.  No special hardware needed – just
apply eyeballs.</p>
<p>As part of the Museum of Math’s opening puzzle hunt in 2012, I used
this to create a fun reveal.  They had transparent disks designed to
be overlayed to display moiré patterns.  Instead, I encrypted a
puzzle answer, and printed the key on one disk and the ciphertext on
the other.  When the disks were rotated to the right angle, the answer
image would pop out.  Of course, this isn’t very secure – if you look
at the images, you’ll see the grid axes, and then there are only four
possible rotations.  But if you don’t have one of the disks, it’s
totally secure.  And it’s a cool effect.  When I visited the museum
recently, the museum staff mentioned that the Fitzwilliam Museum had
been inspired by my little toy, and have a version of it in their
upcoming <a href="http://www.fitzmuseum.cam.ac.uk/calendar/whatson/codebreakers-and-groundbreakers">codebreaking
exhibit</a>
(opening October 24th).  So if you happen to be in Cambridge (the one
in the UK) between next week and next April, please drop by and take
it for a spin.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Set Tactics]]></title>
    <link href="https://novalis.org/blog/2017-09-13-set-tactics.html"/>
    <published>2017-09-13T22:38:56-04:00</published>
    <updated>2025-03-20T10:13:13.034694-04:00</updated>
    <id>https://novalis.org/blog/2017-09-13-set-tactics.html</id>
    <content type="html"><![CDATA[<p>The game of Set is not a strategic game.  Nonetheless, there are
techniques that good Set players use that new players ought to learn
in order to get competitive more quickly.  Since I recently taught a
few new folks how to play, I thought I would discuss the strategies I
use.  For background, keep in mind that each pair of cards has a
unique third card that makes a set with it.</p>
<p>Step one is to just scan the whole board, without any particular
feature in mind.  This strategy will almost never find sets for new
players, because they haven’t got their pattern recognizers wired up
right.  But it’s good to do anyway, because you’ll need it for the
next step.</p>
<p>Step two is to look only at the most-common attribute.  If there are
six red cards, pop out the reds and look just at those. Since you’ve
just scanned the board, you’ll be able to find the attribute quickly.
Among the cards with that attribute, you’ll be able to see a set if
there is one.  If not, you can quickly check the greens and purples.
If you still haven’t found a set, you’ll know you need differing
colors.  Here, it’s often easiest to start with the smallest two
categories: if there are three green and three purple cards, you only
have nine pairs of cards to look at.  And since you’ve scanned the
board, you can often simply remember whether a pair’s third card is
available.</p>
<p>When new cards are dealt (especially when there are no sets among the
twelve cards on the board), it’s a good idea to look at those cards
first.  And if you’ve been tracking the distribution of attributes,
you’ll know what’s common.  On a board with lots of ovals, a new
oval is exciting because it’s very likely to complete a set.</p>
<p>At the beginning of the game, the average number of sets on the board
is almost three.  Pretty often, even if someone else got one, there
will still be one remaining.</p>
<p>As an aside, very few board and card games discuss strategy in their
rule books, which I think is a shame.  Sure, there’s some fun to
learning the early tricks on your own.  But with most games, the real
depth happens after you’ve played a few rounds.  Adding a tiny
strategy guide to game manuals would help new players to enjoy games
more.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Robust game designs]]></title>
    <link href="https://novalis.org/blog/2017-06-27-robust-game-designs.html"/>
    <published>2017-06-27T21:14:24-04:00</published>
    <updated>2025-03-20T10:13:13.050694-04:00</updated>
    <id>https://novalis.org/blog/2017-06-27-robust-game-designs.html</id>
    <content type="html"><![CDATA[<p>Some game designs seem more robust than others.</p>
<p>Dominion is a very robust design.  They recently reprinted the base
game, and replaced six of the original twenty-five cards because they
were too underpowered or too situational.  What other game could not
only survive having nearly a quarter of its components being nearly
useless, but manage to sell millions of copies despite this?  Maybe
we can look at some of the reasons behind this robustness, and learn
something that we can apply to our own games.</p>
<ol>
<li><p>Underpowered is better then overpowered.  If
<a href="https://dominionstrategy.com/2013/04/15/dark-ages-rebuild/">Rebuild</a>
had been in the base game, folks would have complained a lot more.
It’s a one-card engine that’s basically a must-buy.</p></li>
<li><p>High variance adds to robustness.  It’s harder to detect a bias
in a noiser signal.</p></li>
<li><p>Nobody is forced to take a bad card (except through something like
Swindler, where the availability of bad cards is arguably a perk).
Having a choice available that nobody ever takes are is terrible.
The effect is that the designer has wasted some time, and there’s a
bit of additional cognitive load.  Otherwise, it’s fine.  If there’s a
whole subgame that’s useless, that’s bad because players shouldn’t
have to learn a useless subgame.  But if the choice is just one card
vs another, it turns out, it’s workable to have a few less-good
choices.</p></li>
</ol>
<p>There are other reasons that Dominion is a great game, but I don’t
know if there are other reasons why it’s a robust game.</p>
<p>It’s OK for a game to be less robust.  With a less robust design, the
flaws in those six Dominion cards might have been discovered during
development, and they would not have been printed.  But I think that
overall, robustness is a virtue.  Once a game gets out into the world,
players will <a href="https://blog.forrestthewoods.com/the-unbalanced-design-of-super-smash-brothers-3fbc9b346e15">discover, over the course of many
years</a>,
how the game ought to be played.  A robust game will better survive
that experimentation process.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Greebled Teapot]]></title>
    <link href="https://novalis.org/blog/2017-06-12-greebled-teapot.html"/>
    <published>2017-06-12T02:49:52-04:00</published>
    <updated>2025-03-20T10:13:12.994694-04:00</updated>
    <id>https://novalis.org/blog/2017-06-12-greebled-teapot.html</id>
    <content type="html"><![CDATA[<p>I made a greebled teapot:</p>
<p><a href="https://novalis.org/blog/images/greebled-teapot-1.jpg"><img alt="Greebled teapot" src="https://novalis.org/blog/images/greebled-teapot-1-thumb.jpg"/></a></p>
<p>I was inspired by <a href="http://nostalgebraist.tumblr.com/post/159119005169/zonecassette-like-this-post-if-you-are-a-cube">nostalgebraist</a> (re)posting this image, entitled “A cube and its greebled version":</p>
<p><a href="https://commons.wikimedia.org/wiki/File:Greeble.png"><img alt="md5-60c001daf99f6832a38fb898a54694a2A cube and its greebled version. Rendered by Gargaj / Conspiracy.md5-60c001daf99f6832a38fb898a54694a2, CC-BY-SA" src="https://novalis.org/blog/images/Greeble.png"/></a></p>
<p>Of course, mine is more regular (but, being handmade, is also much
more irregular).  It’s slab-built: first I carved an annular sector
and a circle on a slab.  Then I cut and rolled the sector (making a
truncated cone), and molded the circle over a dome to make the bottom.
I attached the two pieces, and cut a hole for the spout.  The spout is
a coil with a hole poked through it, hand-molded, with both carving
and additions to get the greebling.  The handle was a thinner slab,
also with both carving and addition.  As the piece was drying, the
handle cracked, so I had to repair it with paper clay (which, as far
as I can tell, is some kind of magic).  Then I had to make a lid, and
I realized that I had not thought at all about what the handle should
be like.  So I just whipped up something that would work with the
texture.</p>
<p>The glaze is three coats of Coyote’s Really Red (two on the bottom,
which turned out to be plenty).  I thought that a complicated form
should have a simple glaze.  Also, having spent like fifteen hours
greebling the thing, I wasn’t about to spend another fifteen painting
it.  And I recently had some bad luck with the studio glazes; I tried
to make a mug that was yellow, black, and red-brown, and got
greenish-brown, brown, and green (respectively) instead.  So I stuck
with something I knew would work.</p>
<p><a href="https://novalis.org/blog/images/greebled-teapot-2.jpg"><img alt="Greebled teapot" src="https://novalis.org/blog/images/greebled-teapot-2-thumb.jpg"/></a></p>
<p>I’ve been messing around with ceramics for nine or so months now, and
this is the piece that I’m proudest of.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Variables and constants]]></title>
    <link href="https://novalis.org/blog/2017-04-10-variables-and-constants.html"/>
    <published>2017-04-10T01:47:30-04:00</published>
    <updated>2025-03-20T10:13:12.998694-04:00</updated>
    <id>https://novalis.org/blog/2017-04-10-variables-and-constants.html</id>
    <content type="html"><![CDATA[<p>It’s increasingly popular for variables to be immutable by default.
This makes the word “variable” a bit funny.</p>
<p>Also, I had a code review recently where a co-worker asked me to
change some hard-coded strings to be constants.  The strings, in this
case, were argument names for a JSON API.  So the API took e.g.</p>
<pre><code>{
    "function" : "launchMissiles",
    "args" : {
        "target" : "Moscow",
        "type" : "ICBM",
        "count" : 17
    }
}
</code></pre>
<p>The co-worker wanted all of the strings to be constants (except I
think “Moscow” and “ICBM” came from user input and were thus
variables).  I thought it was reasonable to have “target”, “type”, and
“count” be hard-coded.  That’s because:</p>
<ol>
<li><p>Imagine that they were constants – what would you name them?
<code>final String ARG_FIELD_TYPE = "type"</code>?  That seems to make the code
harder to read.  Also, it repeats the value of the constant in its
name.  If tomorrow the value were changed to “model”, should we also
change the name of the constant?  To do so would be insane: changing
a constant’s value shouldn’t entail changing its name.  But to leave
it the same would be monstrous: future readers would have no way of
matching the function call to the API docs without resolving the value
of each constant.</p></li>
<li><p>Would it prevent misspellings?  Not really.  You could just as
easily misspell a constant’s value as a hard-coded string’s value.  If
the string were repeated often, then maybe it could get occasionally
typoed, but these weren’t repeated very often.</p></li>
<li><p>And even if they were repeated, there would be no logical
connection between the instances.  The <code>launchMissiles</code> function
happens to have a <code>target</code> argument, but so does the <code>strstr</code>
function.  But in the next release, maybe they’ll correct <code>strstr</code> to
have better names (<code>needle</code> and <code>haystack</code> are the only correct names
for <code>strstr</code>’s args).</p></li>
</ol>
<p>Anyway, the point is that constants are often valuable for things that
we do expect to change, and often less valuable for things that we
don’t expect to change. So the “constant” name is a little funny too.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Rules; Reverence for religion]]></title>
    <link href="https://novalis.org/blog/2017-02-27-rules-reverence-for-religion.html"/>
    <published>2017-02-27T01:48:47-05:00</published>
    <updated>2025-03-20T10:13:12.946694-04:00</updated>
    <id>https://novalis.org/blog/2017-02-27-rules-reverence-for-religion.html</id>
    <content type="html"><![CDATA[<p>I was talking to my friend C about work benefits, and I mentioned a
particular benefit that I had taken advantage of in some job I had
ever had.  I’m going to be a little vague here, because maybe someone
else had the same idea I did, and I don’t want to kill a good thing.
Basically, this was a benefit intended for some religious minority
that happened to be useful to me as well.  It might have been (but
wasn’t) that on free ice cream day there were kosher (parve) ice
creams, and I’m lactose-intolerant so I ate one.</p>
<p>Anyway, C claimed that this was disrespectful, since the benefit was
intended for religious minorities, but I was taking advantage of it.
I pointed out that being atheists are in fact quite a small religious
minority.  This is somewhat disingenuous as, normally I consider
atheism to be a lack of religion.  But when we discuss matters of
religious discrimination, atheists are a group against which there
is discrimination on the basis of religion.</p>
<p>I guess maybe there was one fewer ice cream available for folks who
keep kosher, but (a) I don’t think they measure the exact number of
folks who keep kosher and order precisely that many units, and (b)
this was a zero-sum situation; one of us was going to go without and
it didn’t really matter which, and (c) they could always just order
more next time and (d) I work in the software industry and basically
all of my co-workers can afford more dessert than they could possibly
eat.  (Since this ice cream thing is not the real thing that C and I
were discussion, the details aren’t really important; the actual
situation was non-rivalrous but I also didn’t have the lactose
intolerance excuse. I just wanted the benefit).</p>
<p>In my conversation with C, I also mentioned a hypothetical, which I
think I took from Eugene Volokh but now can’t find the source for.
The idea is that some company ordinarily requires everyone to work on
Saturday.  They grant an exemption to Michael, because he’s an
observant Jew.  But Frank is a divorced father, and his custody
arrangement only lets him see his kid on Saturdays.  Why is it fair
that Michael gets the exemption, but not Frank?  From an atheistic
perspective, Michael is making a non-existent being happy, while Frank
would be making his actually-existing kid happy. Of course, that’s not
how Michael sees it!  But the point is the at people have many
compelling reasons to want exemptions to generally-applicable rules,
and while it’s quite reasonable to grant these exemptions liberally,
it’s problematic to do so only when the exemptions are religious in
nature.</p>
<p>I don’t think any of this was super-convincing to C.</p>
<p>Anyway, I was telling E about this conversation, and E pointed out
that when we think about rules, there are at least three levels: the
letter of the law, the spirit of the law, and broad moral principles.
I tend to care about broad moral principles and about the letter of
the law (which I was, in the case at hand, following; the hypothetical
ice cream was labeled as “kosher”, but not labeled as “for observant
Jews only").  But the spirit of the law often moves me less.  C, on
the other hand, cares a lot about the spirit of the law.  It’s
unsurprising that I care strongly about the letter of the law, as both
my parents worked as lawyers for most of my life.  Also, I’m a
software engineer and software is a field that is about the letter of
the law (though <a href="https://twitter.com/hashbreaker/status/668711936578732032?lang=en">recent discussions</a>
about undefined behavior in C are often about how strongly to adhere
to an ill-thought-out standard, so maybe this isn’t a universal
professional deformation).</p>
<p>I also think it’s possible that there are different moral principles
at play.  Religious folks (I don’t know whether or not C is religious,
or has this belief) often think of respect for religion as a terminal
value.  Some non-religious folks think this true.  So if, for example,
someone describes the Book of Mormon as kind of Bible fanfic, that
comparison will rankle (even if they personally believe that in fact,
Mormons are mistaken and that Joseph Smith composed the Book of Mormon
himself).  This generic reverence for religion is not a value I share.
Of course, if it comes up in conversation that someone is a member of
religious group X and your first response is to say “X is false and
bad”, that’s just being a jerk.  But in an abstract philosophical
conversation, I don’t think there’s a huge problem with comparing
religious texts to non-religious texts – even low-status
non-religious texts like fanfic.  (The low-status bit is actually
pretty important; the title of <a href="https://en.wikipedia.org/wiki/The_Greatest_Story_Ever_Told">The Greatest Story Ever
Told</a>
compares the Gospels to literature, and it is not regarded as
disrespectful).</p>
<p>Also, I think that even among people who do have this value, it tends
to reinforce existing power structures.  For example, I have read that
no non-Christian group has ever won a free exercise clause (of the US
Constitution; RFRA is different) Supreme Court case.  So it seems to
me that one’s idea of which religious practices fit into this sort of
reverence is colored by one’s personal experiences of religion, and
those that one is exposed to through mainstream culture.  That is, it
often ends up being a facet of status quo bias: an inability to look
at things with fresh eyes.</p>
<p>I don’t really have a conclusion here.  I just thought E’s comment was
so interesting that I decided to dress it up in a bunch of bloviation.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Underground Airlines and the point of democracy]]></title>
    <link href="https://novalis.org/blog/2016-12-13-underground-airlines-and-the-point-of-democracy.html"/>
    <published>2016-12-13T01:17:03-05:00</published>
    <updated>2025-03-20T10:13:13.054695-04:00</updated>
    <id>https://novalis.org/blog/2016-12-13-underground-airlines-and-the-point-of-democracy.html</id>
    <content type="html"><![CDATA[<p>I loved Ben H. Winters’s <em>Underground Airlines</em>.  It’s about an
alternate history where instead of the civil war, there’s a variant of
the <a href="https://en.wikipedia.org/wiki/Crittenden_Compromise">Crittenden
Compromise</a>.  So there’s
still slavery in a few states.</p>
<p>There was just one problem: a throwaway line about Carolina.  That’s
the state formed, in this alternate history, by the merger of North
and South Carolina.  This would never happen.  The US political system
gives more power to smaller states.  What state would give up a
senator (and maybe a representative) to join another?  None.  Ever.
And this gets to the heart of why there was a Civil War in the first
place.</p>
<p>In 1860, the (then chiefly southern) Democratic party had won three of
the past six presidential elections.  The slave states had between
them about 40% of the Electoral College votes.  They had about 45% of
the Senate.  But they only had about 1/3 of the population (and under
1/4 excluding slaves, who certainly weren’t going to fight for the
South).  The combination of the three-fifths compromise and the
Electoral College led the South to dramatically overestimate their
true strength.  This, in my view, was a major cause of the Civil War.
Nobody starts a war they don’t expect to win.  But it’s very easy
to fool yourself into thinking that you might win.</p>
<p>The way that democracy helps prevent civil wars, is that a faction
that loses an election knows that it’s outnumbered.  By screwing with
this function, the Electoral College increases the odds of a civil war
in this country.  (So do <a href="https://www.prisonpolicy.org/importing/importing.html">weird ways of counting
prisoners</a>).
Leaving aside the fundamental unjustness of it, this is the true
reason we ought to get rid of it.</p>
<p>Side note: The fourteenth amendment made the Electoral College
unconstitutional at least at the current population numbers, but
somehow no court has noticed this yet.  <a href="https://en.wikipedia.org/wiki/Reynolds_v._Sims">Reynolds
v. Sims</a> found a
state-level Electoral-College-like system unconstitutional.  But
there’s no reason that the logic of the case doesn’t apply to the
federal system as well.  The Senate too, of course.</p>
<p>All this is to say that you should read <em>Underground Airlines</em>, but
ignore the Carolinas bit.  It doesn’t affect the story at all.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Analogies for Git]]></title>
    <link href="https://novalis.org/blog/2016-11-13-analogies-for-git.html"/>
    <published>2016-11-13T00:22:06-05:00</published>
    <updated>2025-03-20T10:13:12.978694-04:00</updated>
    <id>https://novalis.org/blog/2016-11-13-analogies-for-git.html</id>
    <content type="html"><![CDATA[<p>I’ve done some development on Git.  I’m pretty proud of it, because it’s
a tool that powers so much of modern software development.</p>
<p>At
<a href="http://gamecenter.nyu.edu/events/practice/practice-2016/">Practice</a>,
I was asked to describe the difference between SVN and Git, and also
between Perforce and Git.</p>
<p>The answer I gave goes like this:</p>
<p>“<a href="http://jbr.me.uk/chrono.html">A Guide to SF Chronophysics</a>”
describes four types of time travel plots.  Type 1 is deterministic –
whatever happens, was what was destined to happen.  There’s only one
timeline.  Type 3 is the one where someone steps on a butterfly and
Trump is elected president.  Type 2 is half way in between – you can
change things, but they tend to converge back to the original
timeline.  And finally, type 4 involves multiple universes – every
change (including time travel) creates a new timeline.</p>
<p>SVN is type 1.  Git is type 4.  When you “amend” a commit in Git, you
actually create a whole new commit, forking off from the same parent
as the previous one.  You can use your time machine’s “reflog”
functionality to see the old one.  Similarly, rebase creates a new
timeline from some point in the past.</p>
<p>Perforce, I’m told, is somewhat like git, but it treats changesets
rather than snapshots ("commits” in gitspeak, although in ordinary
usage the term commit often refers to a changeset) as fundamental.</p>
<p>This is an instance of the mathematical notion of
<a href="https://en.wikipedia.org/wiki/Duality_(mathematics)">duality</a>.  The
first example of duality I learned was polyhedra: if you swap the
faces of a polyhedron with vertices, you get a different polyhedron.
The dual of a cube is an octahedron (known by gamers as a d8).
Instead of six faces and eight vertices, it’s got eight faces and six
vertices..  The dual of a dodecahedron (d12) is an icosahedron (d20).
The dual of a tetrahedron (d4) is itself.  The Japanese addressing
system is almost a dual of the US addressing system.  In the US, we
give addresses in terms of strees.  In the Japanese system, blocks are
the fundamental unit.  I have been meaning for some time to design a
game around the concept of duality, but I have not yet figured out
quite how to do it.</p>
<p>Anyway, the graph of changesets is just the graph of snapshots with
the vertices and edges swapped.  Duality.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Against generality]]></title>
    <link href="https://novalis.org/blog/2016-09-27-against-generality.html"/>
    <published>2016-09-27T20:00:31-04:00</published>
    <updated>2025-03-20T10:13:12.890694-04:00</updated>
    <id>https://novalis.org/blog/2016-09-27-against-generality.html</id>
    <content type="html"><![CDATA[<p>So <a href="https://twitter.com/davidbalbert/status/780595121616199680">David Albert</a>
wrote a tweetstorm about Plan 9 and about generality. I’ve reassembled some
paragraphs for ease of quoting:</p>
<blockquote>
<p>There is a ton of symmetry between messaging and late binding at the
  core of OOP, and private name spaces in Plan 9. With messaging in
  OOP, the decision about what code to run is made dynamically, as
  late as possible.  With private name spaces, each process sees a its
  own file system hierarchy. The /foo/bar/baz that I see might not be
  the same one you see.  In a sense, private name spaces late bind
  file contents. This is a big deal when all system <em>functions</em> are
  accessed using files.</p>
</blockquote>
<blockquote>
<p>There’s a great quote from Kay in the Early History of Smalltalk,
  that I still don’t fully understand, but I think applies here.</p>
</blockquote>
<blockquote>
<p>“Smalltalk is a recursion on the notion of computer itself. Instead
  of dividing ‘computer stuff’ into things each less strong than the
  whole–like data structures, procedures, and functions which are the
  usual paraphernalia of programming languages – each Smalltalk object
  is a recursion on the entire possibilities of the computer.”</p>
</blockquote>
<p>This seems pretty reasonable descriptively, but not really great
software engineering.</p>
<p>Recently I <a href="https://git.eclipse.org/r/#/c/81946/">submitted a bug fix</a>
which illustrates one case of this: jgit was willing to write git tree
entries with zero-length names.  These entries represent, roughly,
filenames.  So by removing power, I was able to reduce bugs.  This is
sort of a small case of a power reduction – previously, the domain of
the function was approximately all strings; now it’s all-but-one.</p>
<p>But let’s look at a stronger case: OpenSSL.  OpenSSL famously had a
wide surface area which allowed all sorts of use cases.
Unfortunately, most of those use cases were wrong, from a security
perspective.  Maybe there’s room in the world for a security library
where everything is permitted.  But mostly I would rather use <a href="http://www.libressl.org/">the
library</a> where only correct things are
possible.</p>
<p>I guess this isn’t always true – I use a lot of Python, and when I’m
writing Python to write SVG files, I don’t bother with an interface
that would prevent me from making formatting errors.  I just use print
statements.  But I probably would prefer the interface if I were
programming for external consumption, as opposed to hacking together
some throw-away code to get something else done.</p>
<p>Those are some special cases, but the most general reason for limiting
what your code can do, is that limits make analysis easier.  Valgrind
has to do a tremendous amount of work to show that one particular run
of your C code doesn’t have memory errors.  Java simply never has that
problem (C++ references don’t either).  Regular expressions are far
less powerful than full parsers, so it’s easier for a human reader to
understand what they’re doing.  Pure functions and immutable data
structures are weaker than impure/mutable – but if you use a lot of
them, it’s easier to track down where that stupid variable got
changed.  You can also build abstractions like map-reduce on top of
them.</p>
<p>Which I guess gets to a point that David makes later:</p>
<blockquote>
<p>I think the key idea is find uniform interfaces (the message, the
  file), make them as dynamic as possible, and build a system around
  that.  Another striking thing about Plan 9 is that everything uses
  9P – the remote file system protocol – both locally and remotely.
  If you didn’t have to interact with the outside world, you’d
  basically have only one network protocol for all services.</p>
<p>But this also reminds me of the STEPS project to build a complete
  system in 20,000 lines of code (also Alan Kay, et al). To do that,
  you have to discover powerful abstractions and use them
  everywhere. Having just one network protocol is a good start.</p>
</blockquote>
<p>[rearranged from earlier]</p>
<blockquote>
<p>Consider the Plan 9 window manager. It consumes a screen, a mouse,
  and a keyboard from the computer, (/dev/draw, /dev/mouse, etc.)…
  …and then re-exports virtual screens, mice, and keyboards to each
  of the windows that it makes.  The programs in each window don’t
  know they’re in a window. You could run them w/o the window manager
  and they’d take up the whole screen.</p>
</blockquote>
<p>In indexed-color (e.g. 256-color) graphics, which Plan 9 supported,
there is a difference between being full-screen and being windowed;
when you are full-screen, you have full control over the palette.
When you aren’t, you have a sad negotiation problem.</p>
<p>Also, in a windowed mode, you can be partially covered up and then
exposed, while in a full-screen mode, you can’t.  So either the
full-screen interface has to contemplate this possibility, or the
windowed interface has to be artificially weakened.</p>
<p>Anyway, a file (or series of files) is the wrong interface to a
screen.  You want a higher-level interface that can do things like
scrolling, or playing movies, or drawing textured triangles.  These
are both often hardware-accelerated, and this matters a lot for smooth
graphics.  This sort of rich interface is best accessed through a
series of functions, which communicate, in part, by reifying objects
("a window”, or “a button") so that they can be referenced.</p>
<p>Because I can write any old string to a file, there is nothing that
will check for me whether I have written a string that does something
meaningful (until I run my program).  Plan 9’s use of C’s file reading
APIs makes this even worse: are short reads or short writes possible?
What do they mean?  Sure, you could document that, but you shouldn’t
have to; a good API <em>is</em> the documentation about what’s possible.</p>
<p>And to a reader of code, uniformity makes navigation difficult.  What’s
this piece of code doing?  The same thing as all of the other code:
reading and writing some files.  At this point, strace is a more useful
debugging tool than grep, since at least I can see which file is being
read/written by a particular piece of code.  Larry Wall once said,
“Lisp has all the visual appeal of oatmeal with fingernail clippings
mixed in.”  There’s more to life than visual appeal, but I do think
there’s something to the idea that different tools should look
different so you don’t accidentally grab the scalpel when you
wanted the cautery pen.</p>
<p>I also don’t believe that local resources should be treated the same
as remote resources.  This is a seductive idea – they’re just streams
of bytes, who cares where they’re stored?  And sometimes, it’s
reasonable: when you’re building casual software where you’re not
going to think too hard about failure cases.  But when engineering
something that will see heavy use, it matters whether a read failed
because of a network failure vs a disk failure.  Network failures are
recoverable; disk failures more-or-less aren’t.  And often a stream
isn’t the interface that you want for network communication anyway –
something that’s datagram-based and best-effort is better for games
and telephony.</p>
<p>And this is why basically nothing is 20,000 lines of code, and if
anything is 20,000 lines of code, it’s “<a href="http://yosefk.com/blog/my-history-with-forth-stack-machines.html">by shaving off as many
requirements of every imaginable kind as you can</a>”.
As programmers, we deal with extremely heterogeneous systems.  A
carpenter might pound a thousand identical nails; we just write a
nail-pounding function.  So it’s not surprising that we end up with
specialized rather than uniform interfaces, and it’s not bad either.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Whipsaw!]]></title>
    <link href="https://novalis.org/blog/2016-09-25-whipsaw.html"/>
    <published>2016-09-25T12:45:39-04:00</published>
    <updated>2025-03-20T10:13:13.010694-04:00</updated>
    <id>https://novalis.org/blog/2016-09-25-whipsaw.html</id>
    <content type="html"><![CDATA[<p>For the Power Broker game design contest, my friend Ed and I designed
“Whipsaw!”.  It’s a set-collection card game with lying.  You can’t
have a Robert Moses game without lying.  We didn’t win the contest,
but we had fun making and playing the game.</p>
<p>When I told some folks about this at NYC Playtest, I was told that
people who like set-collection games don’t like lying games and
visa-versa, so nobody would ever play it.  But in fact all of our
playtesters liked it just fine.  Also, poker is kind of that.</p>
<p>Random side note about poker: the notion of a game that is (almost)
exclusively played for money is bizarre.  Remember when MtG started
there was this notion of playing for ante?  And then people tried it
and it was terrible and it never caught on.  If someone invented poker
today, as a Euro-style game, would people think of the real money
thing as a gimmick?  Would it be almost an art game, like <a href="http://cordialminuet.com/">Cordial
Minuet</a> or <a href="http://venturebeat.com/2013/05/11/brenda-romero-train-board-game-holocaust">Train</a>?</p>
<p>We didn’t do nearly as much playtesting on Whipsaw! as I’ve done on
Loading Zone.  It’s a much simpler game, and we were on a pretty tight
timeline.  It’s definitely not perfect: in playtests, players didn’t lie
as much as we wanted them to.  That might be because it’s hard to convince
people to lie (or hard to do so in a set-collection game!).  Or it
might be because the incentives are wrong.  But we weren’t
able to figure out a way to improve the situation.</p>
<p>The game works like this: you’re trying to build parkways (there are
four).  The scoring is roughly quadratic: most parkway cards give
victory points for each card in that parkway.  So you would rather
have all of one parkway than half of two.  The cost of a parkway card
is some number each of legislators, judges, and bankers.  You have a
hand of these resource cards, and draw more every turn.  They’re
played face-down, so you can lie about what you’ve played.  Each type
of card can also be played as an action: bankers lend money (which
acts as additional bankers but costs points at the end of the game),
legislators call bluffs, and judges temporarily block legislators,
giving you a chance to “make it right”.  To make lying more
interesting, the resources have colored backs which give incomplete
information about what they are.  So, the cards with black backs are
mostly judges – but not all. The game has a little more complexity, but
that’s the gist.</p>
<p>Whipsaw! came together pretty quickly: I wrote up a first draft, then
Ed and I tested it.  My version was too long: it had six parkways
instead of four.  And it had a weird complication: instead of judges
blocking bluff calls, special lawyer cards would do it.  Lawyers could
also block opponents’ lawyers.  (In this version, instead of using
legislators to call bluffs, you would do it by paying the cost of it
yourself).  Scoring was roughly linear (and Lost Cities-inspired: you
could actually go negative if you didn’t have enough cards in a
parkway).</p>
<p>My notes on this playtest say that the major fun parts were:
- It played pretty quickly.
- Getting away with lying was fun.
- Strategizing about lying was fun.
- Lawyers were probably the most fun part.
- The colored backs made lying more interesting.</p>
<p>And the notes say that the major flaws were:
- It was too long – 30 minutes would be better.
- There was maybe not enough lying..
- There was definitely not enough calling of bluffs (in part because
it was expensive).
- Some of the complexity was silly.
- And it was maybe hard to know what resources to save in your hand, and
in general save vs spend was not an interesting decision.
- Set collection wasn’t that interesting.
- It was hard to track what other people were doing (too many cards, in part).</p>
<p>Ed’s second draft fixed most of this.  He added more of a narrative
arc by dividing the game deck into three “years”, with more-expensive
properties available in the later years.  He reduced the number of
roads, and adjusted the scoring.  And he invented the rules about
how legislators, judges, and bankers worked.  The game was pretty
close to the final form at this point.</p>
<p>I ran a few more tests – at NYC Playtest, and at Recurse Center, and
made some minor tweaks.  And then we declared the game done and
submitted.  We should probably have done some artwork.</p>
<p>Want to give Whipsaw! a try?  Here are the <a href="https://novalis.org/blog/images/whipsaw.pdf">print-and-play
rules and cards</a>.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Projective]]></title>
    <link href="https://novalis.org/blog/2016-09-03-projective.html"/>
    <published>2016-09-03T15:05:23-04:00</published>
    <updated>2025-03-20T10:13:13.058695-04:00</updated>
    <id>https://novalis.org/blog/2016-09-03-projective.html</id>
    <content type="html"><![CDATA[<p>One of my favorite games is <a href="http://setgame.com">Set</a>.  When I first
discovered it, in 1998, I made a Java applet since I couldn’t
immediately find the cards.  It’s apparently been used as an example
in a college course, which is pretty surprising given that it’s
undergraduate Java (to be fair, I had hacked on it occasionally
since).  My applet used to be a fairly accurate representation of the
original game, but a few months ago I got a letter from the lawyers
for the company who make Set.  They were pretty polite, but I had to
change the graphics.  So now my applet has polka-dots.</p>
<p>Set is played on ℤ<sub>3</sub><sup>4</sup>.  There’s a variant
called <a href="https://en.wikipedia.org/wiki/Projective_Set_(game)">Projective
Set</a>, which is
played on something called a finite vector space –
𝔽<sub>2</sub><sup>6</sup>.  Basically, that’s the six-bit
numbers (but Projective Set excludes the zero card).  The rule is that
N cards can be removed if, for each bit position, the cards sum to zero
mod 2.  Or, perhaps more simply, each symbol appears an even number of
times.  Any seven distinct cards contain at least one such group.</p>
<p><img alt="tilde, square, triangle, plus" src="https://novalis.org/blog/images/projset-14.png"/>
<img alt="plus, star" src="https://novalis.org/blog/images/projset-23.png"/>
<img alt="square, plus, circle" src="https://novalis.org/blog/images/projset-41.png"/>
<img alt="tilde, triangle, plus, star, circle" src="https://novalis.org/blog/images/projset-60.png"/></p>
<p>These four cards can be removed.</p>
<p>One of <a href="http://daniellesucher.com">Danielle</a>’s co-workers lamented not
being able to buy a copy, so I decided to make some.  Unlike the one
shown on the Wikipedia page, mine are accessible to the colorblind.  I
guess I should note that my version is in fact just called
“Projective”, as Set is a trademark of Set Enterprises and I don’t
want to annoy their lawyers any more than my applet already has.  <a href="https://www.thegamecrafter.com/games/projective">So
now you can buy a copy</a>.
I’m not making money off of this because doing so would be a hassle;
the price is what The Game Crafter set.  I got mine yesterday, and it looks
pretty good.  Danielle beat me up some, and I enjoyed it.</p>
<p>This got me to thinking about what other mathematical objects could be
used for pattern recognition games.  I immediately thought of
quaternions, and then got
<a href="https://www.youtube.com/watch?v=SZXHoWwBcDc">Hamilton</a> stuck in my
head.  Did I mention that I’m not great at math?  I had forgotten that
the quaternions are non-commutative, making the game much trickier to
design.  But I guess I don’t need to be totally accurate to the math.
As long as I keep i<sup>2</sup>=k<sup>2</sup>=k<sup>2</sup>=ijk=-1,
everything will probably work out.  The idea will be to find N cards
whose product is one.  I’m thinking of calling it Uno.</p>
<p>I even came up with some icons, based on the
Swedish point of interest symbol:</p>
<p><img alt="icons for the quaternion game" src="https://novalis.org/blog/images/quatset-icons.png" title="Quaternion icons"/></p>
<p>Notice that each of i, j, and k can be combined with a rotation to
form the -1 symbol, and i, j, and k can be overlapped to do the same.</p>
<p>This might be too easy, so maybe I’ll need to do ℚ<sup>2</sup>
or something.  Or just go straight to 𝕆, whose multiplication
table is too big to remember.  But you can always use this
simple and easy to understand diagram (from Wikipedia):</p>
<p><img alt="Fano plane diagram" src="https://upload.wikimedia.org/wikipedia/commons/2/2d/FanoPlane.svg" title="The Fano Plane"/></p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Word Freq]]></title>
    <link href="https://novalis.org/blog/2016-08-22-word-freq.html"/>
    <published>2016-08-22T01:47:40-04:00</published>
    <updated>2025-03-20T10:13:12.994694-04:00</updated>
    <id>https://novalis.org/blog/2016-08-22-word-freq.html</id>
    <content type="html"><![CDATA[<p>I created a totally stupid game called “Word Freq”.  It simply asks
you which of two randomly chosen n-grams (presently, only 2-grams are
included) appears more often in the Google n-gram database.</p>
<p>It’s kind of fun tho.</p>
<p><a href="http://wordfreq.novalis.org">Play it here</a>.</p>
<p>I’m downloading and processing the 3-grams now, but they’re really big –
like several terabytes of data.  Then I guess I’ll merge the 1-grams,
2-grams, and 3-grams, so that you can have interesting matchhups
like “conformity” vs “the policy of”.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Computers and law]]></title>
    <link href="https://novalis.org/blog/2016-08-19-computers-and-law.html"/>
    <published>2016-08-19T01:02:59-04:00</published>
    <updated>2025-03-20T10:13:12.886694-04:00</updated>
    <id>https://novalis.org/blog/2016-08-19-computers-and-law.html</id>
    <content type="html"><![CDATA[<p>My mom emailed me to ask about machine interpretation of laws
(i.e. software judges and lawyers).  I replied:</p>
<p>About fifteen years ago, I got into an argument about this in the
context of a video game.  The idea was that the game would have guards 
which would punish you if you did something illegal.  The problem was 
that the game supported building machines, and Turing proved that no 
computer program can, in the general case, figure out what a machine 
will do.  So if you built a sufficiently complicated machine, either you 
would get away with murder or be wrongly convicted.</p>
<p>Humans, of course, have the same problem, but we pretend not to.</p>
<p>Self-driving cars are a relatively easy case: only a monster would 
program in anything but pure consequentialism. Especially since, as a
practical matter, self-driving cars are likely to be much safer than 
human-driven cars.</p>
<p>Before computers can replace lawyers in the the general case, they will 
have to understand human language (in order to interpret contracts, 
laws, and precedents).  This is the single hardest problem in computer 
science. We have made almost no progress here.  If we can solve this 
problem, we have achieved general intelligence, and within a year or two 
nobody will have a job.</p>
<p>There are areas now where computers could assist us.  For instance, 
let’s say we’re considering Solomon’s case: which of two women is the 
mother of a child.  Imagine that one woman is has brown hair and brown 
eyes, and the other has blonde hair and blue eyes.  The child has brown 
hair and blue eyes.  (We don’t have a DNA test for some reason).  How do 
we combine our two pieces of data?  There’s a fairly simple formula that 
does it precisely (given some odds of the various inputs).  But right 
now, in order for a jury to use this formula, we need to call a 
statistician to the stand.  And if the jury finds one of the women twice 
as credible, they don’t have a way to incorporate that data, even though 
the formula could easily do it.  This would be a good first step, but 
for political reasons it would be shocking to me if we took it.</p>
<hr/>
<p>I should have added: This thing where the law is designed to be
interpreted by humans is <a href="http://ansuz.sooke.bc.ca/entry/23">famously hard for programmers to
grasp</a>.  I had forgotten that the
thing where computers are bad at interpreting language (yet good at
following rules) is just as hard for lawyers.  I think the lawyers’
confusion is part of what’s behind the recent encryption debate
(roughly 40% members of congress have law degrees).</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Feldcon]]></title>
    <link href="https://novalis.org/blog/2016-08-15-feldcon.html"/>
    <published>2016-08-15T23:44:45-04:00</published>
    <updated>2025-03-20T10:13:12.926694-04:00</updated>
    <id>https://novalis.org/blog/2016-08-15-feldcon.html</id>
    <content type="html"><![CDATA[<p>Last weekend, I attended <a href="https://boardgamegeek.com/blogpost/56834/feldcon-2016">Feldcon</a>,
a one-day board gaming event where we played nothing but Stefan Feld’s
games.  I had never played a Feld before, but I figured if someone
liked him enough to have a whole convention, he must be pretty good.
I carefully prepared by reading the rules to Macao and Castles of
Burgundy – but I didn’t end up playing either of them.</p>
<p>I think Feld is good, but mostly his games weren’t for me.  Still, I
learned something about what I like in games, and that’s valuable.  I
had been slowly working on designing a more Euro-style game, and now I
have a stronger sense of what sort of play I want to encourage.</p>
<p>In all of games I played, there were multiple ways to score.  I do
like games that have multiple viable strategies, so this should have
been appealing (and in fact it often was).  But one play was not
really enough to learn to keep track of all of them (in some of the
games), or figure out which I should be focusing on.  Can you win at
Bruges without touching your canal?  I don’t know, but I sure didn’t!</p>
<p>I played:</p>
<ul>
<li><p><a href="https://boardgamegeek.com/boardgame/127060/bora-bora">Bora Bora</a>: A
clever action selection mechanism: each player rolls three dice, then
takes turns placing the dice on various actions.  Higher numbers are
more powerful, but you can’t place a higher numbered die after someone
has placed a lower number on a given action.  The game had a lot of
bits: cards, tiles for women, men, tasks, jewelry, resources, fish,
offerings and turn order, along with dice, (cardboard) shells, and
various wooden pieces.  There was a satisfying variety of actions, but
I found it a bit overwhelming to pay attention to all of the ways to
score.  I guess a second play would have helped here.  It didn’t seem
reasonable to put together a coherent strategy up front, because the
dice and opponents’ plays could easily screw it up.  Being forced to
react to changing circumstances is something I like.  This was
probably my second-favorite of the games, although I think with more
play, Trajan might displace it.</p></li>
<li><p><a href="https://boardgamegeek.com/boardgame/102680/trajan">Trajan</a>. The key
innovation of Trajan is the Mancala-like action selection mechanism.
Mastering this mechanic would allow more planning about what actions
to take, but it seems like a pure computation exercise.  I guess that
could be fun – in theory, portions of my game-in-progress, <a href="http://loadingzonegame.com">Loading Zone</a>, are like that.
Unlike Loading Zone, you might want to explore a broader tree for
Trajan’s Mancala, since you might want to be able to react to your
opponents’ choices.  Still, the Mancala thing was <em>neat</em>, which counts
for a lot in a first play-through.</p></li>
<li><p><a href="https://boardgamegeek.com/boardgame/91873/strasbourg">Strasbourg</a>
was my favorite of the games I tried.  It’s got an all-pay auction
mechanic that I really dug.  As a first-time player, I managed to
screw up and make one of my goals impossible in turn one – I didn’t
realize that I would need to win every meat auction.  I wonder if
somehow moving the goal choosing later in the game would reduce the
variance.  But maybe if I were a stronger player, I would have chosen
more goals and been less sad about losing one.</p></li>
<li><p><a href="https://boardgamegeek.com/boardgame/31594/year-dragon">In the Year of the
Dragon</a>.  A
disaster aversion game.  It turns out that I really don’t like games
where you can end up in an unwinnable state and then have to sit there
losing for the rest of the game.  That didn’t happen to me; I did get
a little screwed but mostly lost through some poor choices.  But it
was even painful to watch it happen to another player. I’m OK building
something that’s less than optimal (but still scoring some points).
And I’m OK with getting destroyed.  But if I’m getting destroyed, I
want it to be over quickly.  In a two-player game, I can just resign,
but Feld’s games seem mostly to be intended for three or more.</p></li>
<li><p><a href="https://boardgamegeek.com/boardgame/136888/bruges">Bruges</a>.
Another disaster aversion game, although less so.  The push-your-luck
aspect made disaster aversion much more painful; it feels hideously
unfair when you were playing pretty cleanly but just rolled the wrong
six.  Worse, there was one card which was basically a “screw your
neighbor” (and another which made one player much more resilient),
each of which seemed to dramatically change the game.  The game seemed
to want me to primarily build my canal and only secondarily recruit
people, but the people were so much more interesting than the canal.
I never seemed to have enough actions; each (4-action) turn you can
actually recruit fewer than one person on average, since you will gain
1⅔ threat tiles and you need at least 3 actions (half of a
worker-creation, one house, at least half of a money-action, the
person) to recruit.  I know that making hard choices is the essence of
gaming, but I wanted to feel like I had lots of good choices, instead
of having to constantly spend all of these interesting people I
could be living with.</p></li>
</ul>
<p>Across all of Feld’s games, I liked the multiple small decisions
(especially in the rare cases where they were decisions under
uncertainty).  I generally liked the feeling of abundance – there are
lots of things I could do!  The two games I liked least had less of
the abundance feeling, unsurprisingly.  But because it was generally
hard to choose actions (because I had to fuck around with Mancala
stones, or hire workers, or have the right dice), it was hard to build
up a strategy.  The only choice was to be mostly reactive.  By the
“abundance of actions” metric, I think Bora Bora was the strongest of
the games I played, followed closely by Trajan.</p>
<p>Overall, I’m super-glad I spent nearly twelve straight hours playing
these games, because I know I’ll be thinking about them for a long
time.</p>
<p>Thanks to <a href="https://twitter.com/dnlnwmn">Daniel</a> for organizing, and to
<a href="http://brooklyngamelab.com/">Brooklyn Game Lab</a> for hosting.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Lamp]]></title>
    <link href="https://novalis.org/blog/2016-08-14-lamp.html"/>
    <published>2016-08-14T22:32:02-04:00</published>
    <updated>2025-03-20T10:13:13.042695-04:00</updated>
    <id>https://novalis.org/blog/2016-08-14-lamp.html</id>
    <content type="html"><![CDATA[<p>I made a shallot-shaped lamp.</p>
<p><img alt="pic of the lamp" src="https://novalis.org/blog/images/lamp.jpg" title="Shallot-shaped lamp"/></p>
<p>I was inspired by a lamp that hangs outside of <a href="http://ramennyc.wixsite.com/popup">my favorite ramen
joint</a>.  I had originally intended
to make something much closer to the original, but I wasn’t able to
get a satisfying design.  So I decided to go with something with more
curves.</p>
<p>To design the lamp, I wrote a crappy Python program filled with magic
numbers.  It generated two files: a POV-Ray scene description, and a
SVG for the laser cutter.  This let me rapidly iterate on the
design. Here’s a video render of an earlier version (I didn’t bother
to make a video of the final version):</p>
<video controls="" height="600" width="800"> <source src="https://novalis.org/blog/images/lamp-render.webm" type="video/webm"/></video>
<p>I hadn’t touched POV-Ray for like fifteen years, but it came back to
me pretty quickly.  It was pretty much exactly what I needed for a quick
visualization of 3d parts.  As an aside, my usual approach for both
POV-Ray and SVG is to just use print statements.  Yeah, there’s no
guarantee that you’ll be generating correct output, but if you make
a mistake, it’s usually visible and easy to fix.</p>
<p>I initially planned to have the lamp be made entirely out of laser-cut
wood, with a standard press-fit tab/slot arrangement.  I prototyped
this at <a href="https://www.nycresistor.com">NYC Resistor</a>, and discovered
that fitting 25 slots into a ~60 mm ring was not going to work well.
The wood was just too fragile.</p>
<p>So I bought some stainless steel rings, cut them open, and and cut
circular holes in the ribs.  The holes are sized (after some more
prototyping) so that they fit quite snugly onto the rings, which made
assembly kind of a pain.  I think next time I would cut the holes
looser and use rubber o-rings to constrain the positioning of the
ribs.  It’s not expensive to get Viton o-rings in an appropriate size
(Viton was the material used for Challenger’s infamous o-rings, but
hopefully nobody will be launching my lamp into space).</p>
<p>I did the final laser cut at <a href="http://www.ponoko.com">Ponoko</a>, because
I didn’t want to try to track down an appropriately sized/shaped piece
of wood for Resistor’s laser.  One kind of stupid thing is that
fitting the lamp ribs onto Ponoko’s largest (P3) sheet was a manual
process.  Each rib is individually shaped, so they don’t nest cleanly.
I guess I probably could have coded some solution which nudged the
pieces around until they fit, but it was quicker to do it manually.</p>
<p>I’m pretty happy with the end result.  The photo at the top of this
post was taken immediately after turning the lamp off; because it has
an incandescent bulb, you can still see a bit of the glow.</p>
]]></content>
  </entry>


</feed>