Waving Hands: a browser duel after Bartle's 1977 game

SvelteKit 5 single-player version against a heuristic bot. The engine
resolves all forty spells simultaneously as the rules describe, the
ledger of gestures is the interface, and the duel is saved in the
browser. Tester feedback rounds added per-hand planning, threat
evidence, a result strip with one-time rule explanations, a phone
layout and a structured rules page. Deploys as a static site behind
Caddy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Eric Wagoner
2026-09-22 15:33:29 -04:00
co-authored by Claude Fable 5.1
commit 865555e911
38 changed files with 8112 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
# Waving Hands
A browser remake of Richard Bartle's 1977 pencil-and-paper wizard duel, also known as
Spellbinder and Spellcaster, and the game behind Andrew Plotkin's *Spellcast* for X Windows.
Each turn both wizards secretly choose a gesture for each hand, then reveal them together.
The right run of gestures on one hand is a spell. Gestures can overlap, so `F-F-F` casts
Paralysis and following it with `S-S-D-D` finishes a Fireball. Both palms at once is surrender.
The full rules, as transcribed from the *Duel Purpose* fanzine, are in
`docs/waving-hands-rules.txt`.
## Playing
```sh
npm install
npm run dev
```
You duel a heuristic bot. Choose a gesture per hand, pick which completed spell (if any) each
hand casts and at whom, and reveal. Beneath each hand is a list of the spells that hand is
part-way through; selecting one makes its next gesture, and the diamond pins it. Every entry
in the spell sheet offers "Plan with left hand" and "Plan with right hand", showing what that
hand still has to make, so a duel can start from a chosen spell rather than a guessed gesture.
When a rule decides something surprising (a shield that stopped a goblin but not a wound
spell, a countered spell, a one-handed clap, a reused run of gestures) the result strip
explains it once per duel; the checkbox under the hands turns this off. Warnings
above the hands cite the opponent's gestures that could finish a hostile spell, and selecting
a warning lights those gestures up in the ledger. After each reveal a short strip shows what
changed each wizard's health and everything else worth knowing, with the full chronicle in
the sidebar. The rules are at `/rules`.
The duel is saved to the browser's local storage after every change, so it survives reading
the rules, a refresh, or a phone putting the tab to sleep. Starting a new duel asks first if
one is under way. Nothing is rendered on the server.
## Layout
- `src/lib/game/spells.ts` the spell book and monster stats
- `src/lib/game/gestures.ts` sequence matching, threat detection, gesture-sharing conflicts
- `src/lib/game/resolve.ts` simultaneous turn resolution
- `src/lib/game/bot.ts` the opponent
- `src/lib/game/duel.svelte.ts` reactive store binding the engine to the UI
- `src/lib/components/` ledger, hand pickers, status, chronicle, spell sheet
## Simplifications
Raise dead only heals; there is no one left to raise in a two-wizard duel once someone dies.
Paralysis and charm person pick the hand at cast time rather than after the reveal.
A hastened wizard's second pair of gestures is bound by the same enchantments as the first.
Under time stop the frozen wizard's ledger shows a row of question marks, so they know a
stopped moment passed even if nothing touched them.
## The bot
The opponent scores every pair of gestures by the spells they finish, the spells they move
toward, and what your visible gestures threaten. Spells it cast in the last few turns are
discounted so it does not fall into a rut, and each named opponent weights the spell book a
little differently.
## Deploying
See `deploy/README.md`: one small droplet running Caddy serves the static build.
## Tests
```sh
npm test
```
## Credits
The gesture silhouettes on the buttons and the favicon are adapted from the bitmaps in
Andrew Plotkin's *Spellcast* for X Windows (1993). Its notice: "This implementation is by
Andrew Plotkin. It is copyright 1993 by Andrew Plotkin. The source code may be freely copied,
distributed, and modified, as long as this copyright notice is retained. The source code and
any derivative works may not be sold for profit without the permission of Andrew Plotkin and
Richard Bartle."