---
id: magic-circle-programming-languages/05-widdershins-a-stack-language-where-neatness-is
title: 'Magic circle programming languages: 5. Widdershins: a stack language where
  neatness is mana'
report: https://ai.hiina.space/reports/magic-circle-programming-languages.md
section: 5
version: 1
updated: '2026-10-27'
author: Hiina
---

Index of everything on this site: https://ai.hiina.space/index.md

# Magic circle programming languages: 5. Widdershins: a stack language where neatness is mana

- Section 5 of 13 of the report "Magic circle programming languages" by Hiina (v1, updated 2026-10-27)
- Report overview and contents: https://ai.hiina.space/reports/magic-circle-programming-languages.md
- Previous: https://ai.hiina.space/reports/magic-circle-programming-languages/04-five-designs-five-computational-models.md
- Next: https://ai.hiina.space/reports/magic-circle-programming-languages/06-covenant-interaction-combinators-drawn-as-seals-and.md

## 5. Widdershins: a stack language where neatness is mana

A spell is a ring of freehand glyphs read counter-clockwise from a keystone. Small rings tangent to the main ring are quotations, and leaving a ring open defers it. The program is an ordinary concatenative stack language in the line of Joy and Hex Casting, so its semantics is deterministic. **Drawing quality only changes what the spell costs**: neat glyphs are efficient, sloppy ones burn more mana, and because mana is also gas, every spell terminates. Widdershins is the VR design and casts through the existing VR stroke pipeline almost unchanged.

| Visual element | Meaning |
|---|---|
| Main ring, closed | Program; runs when the cast button is released |
| Main ring with a gap | Prepared spell: compiled and stored on the wand; a later stroke across the gap fires it |
| Keystone (a small ▸ wedge on the ring) | Program start; reading proceeds counter-clockwise (widdershins) from here |
| Glyph in the ring band, at angle θ | One operator; program order is angular order θ, not draw order |
| Sub-ring tangent to the band, with a gap | Quotation `[ … ]` pushed as a value; contents read CCW from the tangent point |
| Sub-ring tangent to the band, closed | `( … )`: quotation executed inline |
| Dot / bar / n-gon (3 ≤ n ≤ 6) / empty small circle | Numerals 1 / 2 / n / 0 |
| Glyph quality q | Efficiency of that token's mana cost |
| Main-ring quality q_R | Global efficiency multiplier (a "leaky" ring wastes everything) |

**Model and evaluation.** Values are numbers, vectors, entities, quotations and garbage. A program is the token sequence t₁…tₙ sorted by angle from the keystone, with each sub-ring parsed recursively. Operators include `target` (an eye glyph; pushes the entity under your gaze), `gaze` (an arrow; pushes your unit look vector), `+` (a cross), `×` (a saltire), `dup` (a fork), `drop` (a slash), `swap` (an hourglass), `impel` (a chevron; E v → E, pushes E along v), `ignite` (a zigzag; E → E), `i` (a spiral; executes the quotation on top), `times` (a lemniscate; n [Q] → runs Q n times) and `if` (a Y; b [T] [F]). Effects deliberately leave their target on the stack.

Execution is Joy-style left to right over the angular sequence. Each executed token t costs k(t, args) / η_t, where η_t = q'_t · q'_R, paid from the caster's pool M. An unrecognised glyph, a stack underflow or a type error pushes `garbage`, and an effect applied to garbage does nothing but still costs, which is Hex's limp-on approach. Every token costs at least k_min > 0, so a run executes at most M / k_min tokens and the language is total. Hex enforces a similar bound with a separate op counter; here the bound is the mana the player already sees. Loop bodies are charged per iteration at their own glyphs' η, so a sloppy glyph inside a loop is paid for every time round, which rewards neat loop bodies without an extra rule. Because program order is angular while draw order only groups strokes into glyphs, **a caster can insert a token by drawing it between two existing ones**, a real editing gesture.

**Worked example: "triple gust"** flings whatever you are looking at along your gaze, three times. Draw one closed main ring with the keystone at 3 o'clock and five tokens counter-clockwise at roughly 72° steps: an eye (`target`) at 0°, a triangle (`3`) at 72°, an open tangent sub-ring holding an arrow then a chevron (`[gaze impel]`) at 144°, a lemniscate (`times`) at 216°, and a slash (`drop`) at 288°.

```
                  Δ
          .-""""""""""-.
     C   /              \
         |              | ▸◉
         |      ·       |
     ∞   \              /
          '-.________.-'
                    /
   ◉ target (keystone)   Δ 3   C open sub-ring [→ ›]   ∞ times   / drop
```

Text form: `target 3 [gaze impel] times drop`. The trace uses pool M = 50, q_floor = 0.25 (example value), ring quality q_R = 0.9 (so q'_R = 0.925), and nominal costs target 1, numeral 0.5, quote 0.5, gaze 0.5, impel 4·|v|, times 1, drop 0.2 (example values).

| Step | Token (q) | Stack after | Cost |
|---|---|---|---|
| 1 | target (0.8) | E | 1/(0.85·0.925) = 1.27 |
| 2 | 3 (0.9) | E 3 | 0.58 |
| 3 | open sub-ring (0.7) | E 3 Q | 0.70 |
| 4 | times (0.5) pops 3, Q | E | 1.73 |
| 4a–c | gaze (0.8) ×3 | E v → … | 3 × 0.64 = 1.91 |
| 4a–c | impel (0.6) ×3, \|v\| = 1 | E | 3 × 6.18 = 18.53 |
| 5 | drop (0.9) | (empty) | 0.23 |

The total is about 24.96 of 50. Drawn perfectly, the same spell costs 16.7. The effect is identical either way: three unit pushes. Because the loop count is a literal, the parser can compute the cost statically while you draw, as Psi computes spell stats from constants at compile time; the ring's glow shows projected cost against the pool, and each glyph tints by its η as you finish it.

**Mishaps.** An unknown glyph renders as a grey smudge with a yellow flare, borrowing Hex's Invalid Pattern colour. An underflow makes the glyph flicker and pads the stack with garbage. When the pool runs out, in safe mode the ring goes dark mid-sequence and the remaining tokens dim; in overcast mode, as in Hex, the deficit comes out of health and the ring burns red. An unclosed ring is not a mishap: the spell stays prepared, hovering at the wand.

**Parsing.** In VR, the first closed stroke whose circle-fit residual passes threshold becomes the main ring and fixes a polar frame. Strokes are grouped into glyphs by time gap (a pen-up under about 400 ms, guess) and by centroid falling inside the band [0.6R, 1.0R]. Each glyph is rotated so its local radial direction points up before $Q matching, which makes the whole spell rotation-invariant, as Hex's turn-list key is, without discretising the input. Sub-ring tangency is a centre-distance test, |c_sub − c| ≈ R − r_sub. All of this costs well under a millisecond per stroke. From an image the steps are the same after rectification, but the keystone must be found (a filled wedge is easy) and band glyphs are small, exactly where detectors and VLMs are weakest. That is why Widdershins is VR-first.

**New versus borrowed.** The stack machine, garbage values and mishap colours come from Hex Casting, concatenative semantics from Joy, counter-clockwise reading and tangent auxiliary rings from Mystical, open-equals-prepared from Witch Hat Atelier, the wand as stored program from Noita, and the ring as the unit of control from Rotary. New, as far as this research found, are freehand glyphs in a polar frame, angular order as program order (which gives insert-editing), quality as cost efficiency rather than effect strength, and mana doubling as gas for totality. Untested: whether about 16 freehand glyphs stay separable in mid-air at speed. Wizard of Wii's finding that players dislike similar circular gestures says the glyph set should be strokes and corners, not loops.

---

Text licensed CC BY 4.0 (attribution: Hiina, ai.hiina.space). Source: https://github.com/hiinaspace/ai-hiina-space
