Waving Hands

Duelling wizards. Two hands each. The right run of gestures is a spell.

Richard Bartle's 1977 pencil-and-paper duel, free in your browser. Each turn every wizard chooses a gesture per hand and all reveal together; a Fireball is F-S-S-D-D on one hand, a Shield is a single palm. Play the bot, or open a table for up to a dozen wizards and play by turns.

{#if local} {:else} {/if}

or join one

A code opens the door either way: take a seat if one is free, or watch from the Peanut Gallery.

or bring a seat from another device
{#if error}

{error}

{/if}
{#if seats.length || local}
your duels
{#if local} {/if} {#each seats as held (held.roomId)} {/each} {#if reports.length}
your reports to the keeper
{#each reports as r (r.id)} {@const last = r.thread[r.thread.length - 1]}
{r.roomId}

“{r.happened}”{#if r.image} (with a picture){/if}

{#each r.thread as line, j (j)} {#if line.from === 'player'}

you: {line.text}

{:else}

{line.status} {line.text}

{/if} {/each} {#if !last}

the keeper is studying the moment

{:else if last.from === 'player'}

your word is with the keeper

{/if} {#if r.thread.some((l) => l.from === 'desk')}
{ e.preventDefault(); void answer(r); }}>
{/if}
{/each} {#if answerError}

{answerError}

{/if} {/if}
{/if}
about this game

Waving Hands is Richard Bartle's game from 1977, played with pencil, paper and two hands. It was later known as Spellbinder and Spellcaster, and Andrew Plotkin's Spellcast brought it to university X terminals in 1993, which is where the maker of this page first met it.

This version keeps the game as written: all forty spells, the same simultaneous resolution, the same ledger of letters. The rules text it follows is the fanzine transcription, kept in full on the rules page. The bot reads your gestures as you would read its; the hand silhouettes on the buttons are adapted from Plotkin's bitmaps, with his notice retained.

It is free and keeps no accounts. A duel against the bot lives in your own browser. A duel between people lives on a small server as an append-only ledger of moves, so it can be replayed from its first gesture, and each wizard is shown only what the rules let them see.

Send word

A rule read wrong, a bug, a duel you would like to tell of: write to eric@ericwagoner.com, @kestrelsnest.social on Bluesky, or @eric@toots.kestrelsnest.social on Mastodon. The keeper of this hall roosts at kestrelsnest.social.

{#if tally}

The tally

{tally.gamesFinished}
{tally.gamesFinished === 1 ? 'duel' : 'duels'} fought to a finish, of {tally.gamesBegun} begun at {tally.tablesOpened} {tally.tablesOpened === 1 ? 'table' : 'tables'}
{tally.namesSeated}
{tally.namesSeated === 1 ? 'name has' : 'names have'} taken a seat
{tally.turnsPlayed}
turns of gestures written; {tally.longestGameTurns} in the longest duel
{hours(tally.minutesAtTable)}
at the table, by the clock between reveals
{tally.gamesWithBot}
{tally.gamesWithBot === 1 ? 'duel' : 'duels'} with the bot seated; {tally.talkLines} {tally.talkLines === 1 ? 'line' : 'lines'} of table talk
{#each Object.entries(tally.byGame) as [label, n] (label)}
{n}
{label}
{/each}

{#if tally.firstGameAt}The first duel began {new Date(tally.firstGameAt).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}.{/if} Names are counted, not people: one wizard under two names is two here. Table time counts only the minutes between reveals, so a duel left open overnight adds nothing for the night.

{/if} {#if family.length}

More games in {#if hall}Kestrel's Hall{:else}Kestrel's Hall{/if}

    {#each family as g (g.slug)}
  • {g.name}: {g.pitch} {g.players} players; {g.origin}.
  • {/each}
{/if}

The games of Kestrel's Hall are free and will stay free. They run on small servers that cost a few dollars a month; anyone who wants to chip in toward the hosting can at ko-fi.com/kestrelsnest. Nothing is unlocked by it and nothing is withheld without it.

Waving Hands is Richard Bartle's, 1977. This page was made by Eric and a very enthusiastic AI, 2026.