Chapter
Shape overlaps
Method
The check copies the recognizer's shape step from Assets/Scripts/Scoring and runs it on every proposed template:
- Resample each thumb's stroke to 64 evenly spaced points (
Geometry.Resample). - Normalize: centroid to the origin, larger side scaled to 1, with orientation and direction kept (
Geometry.Normalize). - Take the mean point-to-point distance d to the other spell's template, thumb by thumb, and turn it into a shape score, exp(−d / 0.15) (
PartScorers.Shape). - A drawing counts as an attempt at a spell when both thumbs score at least 0.30, which means d under about 0.18 (
ShapeMinimum). The scorer then picks the spell with the best overall score among the recognized ones, learned or not.
Every spell was compared with every other spell. Because the scorer also checks every ordered pair of spells as a composite (Grimoire.Castable, 27 × 27 = 729 chains, built with SpellComposer.Join), every spell was also compared with every chain, and every chain with every other chain.
This is a shape-only check on perfect templates. It doesn't model corners (20% of the overall score), size (10%), pace (15%) or sync (20%), all of which pull apart shapes that look alike but differ in corners, size or speed. So "recognized" here means the scorer has to fall back on those other parts, not that the cast certainly goes wrong. Every pair marked "watch" needs a device test.
Collisions fixed in this roadmap
These are Spell Set shapes that the check found too close to another spell. Each is redrawn in this roadmap.
| Spell Set shape | Collides with | Shape score | Why | Roadmap fix | After the fix |
|---|---|---|---|---|---|
| Squall: an M, two peaks in a row | Gale into Gale | 0.43 | Two Gales threaded is an M. A player who knows Gale but not Squall and draws Squall gets either "You have not learned Squall" or a free Gale-into-Gale | A lightning bolt | 0.27 against Hush (watch list); Gale into Gale no longer near |
| Echo: a tiny arc, top to bottom, bulging outward | Brace | 0.54 | Once normalized, a rounded bracket and a square bracket are nearly the same path | A short stroke inward | Clear of every other spell |
| Tailwind: a check mark | Drift | 0.46 | The check's long arm is Drift, and it is most of the stroke | Gale's peak upside down (a V) | Clear (nearest: Table Mend, 0.18) |
| Root: a low wave | Calm | 0.39 | A low wave normalizes to almost a straight outward line | A wave almost as tall as it is wide | 0.20 against Calm |
| Hasten: spiral outward, clockwise (right thumb) | Wither | 0.31 | Its outer half-turn, most of the stroke, is Wither's arch | Spiral counter-clockwise | Clear of Wither |
| (first draft) Weigh as a staircase | Repel | 0.33 | Its first two steps are an L | An N | 0.07 against Repel (nearest: Root, 0.20) |
Pairs to watch on device
These pairs stay apart on shape (both below 0.30, or right at it) but are close enough that a careless draw could cross over. Corners, size or direction should separate them.
| Pair | Shape score | What separates them |
|---|---|---|
| Coil and Hush | 0.30 | Size (34 mm against 12 mm). Hush is a straight vertical line, the shape many tall, narrow strokes collapse toward once normalized. Repel (0.28), Linger (0.27), Squall (0.27) and Tally (0.25) also sit near Hush. |
| Hasten and Recall | 0.26 | Direction only: same size, no corners, both spirals. They are a deliberate pair (speed time up, wind it back), but a player who starts Hasten from the wrong end may get Recall. |
| Coil and Linger | 0.25 | Linger loops; Coil doesn't. Same tier, close sizes. |
| Brace and Tally | 0.23 | Both two-corner Warden shapes starting with the same outward stroke; the corner positions differ. |
| Root and Calm | 0.20 | Size, and Root's height. |
| Weigh and Root | 0.20 | Weigh has two corners; Root has none. |
| Gale and Tailwind | under 0.10 | The recognizer keeps them apart, but they are the same peak flipped. Players may mix them up even when the scorer doesn't; teach them in different chapters. |
Problems in how threads are built
The thread checks turned up four problems in SpellComposer and Grimoire. None is specific to this roadmap, and the code would need to change to fix them. They are listed for the Lead to ticket.
- C1. A straight stroke threaded into itself is the same shape. Hush into Hush, Calm into Calm, Listen into Listen, Echo into Echo and Drift into Drift each score 1.00 against the single spell, because a straight line joined to itself is a longer straight line. Only size tells them apart, so drawing Hush twice as big casts Hush into Hush, double the effect plus 20%. Recommendation:
Grimoire.Castableskips self-chains whose joint isn't a corner. - C2. Still Choir spells disappear inside threads.
SpellComposer.Joinscales each part to its own size, so a 12 mm Choir stroke becomes a short tail on a 30 mm spell. Once normalized, "X into Hush" looks like X: 597 of the 1,318 chain pairs that are recognized as each other involve a Choir part. Two examples: Hush into Calm draws a small Repel (0.34 against Repel), and Echo into Toll and Calm into Toll both score 0.56 against Knell (Hush into Toll). Recommendation: score each half of a chain separately at the known joint, as well as the whole, and require both halves to be recognized. Until then Knell stays on hold, and no other Choir thread gets a name. - C3. A chain is only as distinct as its weaker half. When two chains share one part exactly, the other halves only need to be roughly alike for the whole to be recognized as both. Brace into Mend against Coil into Mend scores 0.58, and that pair already exists among today's eight spells, which have 27 such chain pairs. Corners usually settle it (Brace has two, Coil none), so this matters most when both halves are smooth: Thornshield (Coil into Facet Seal) against Linger into Facet Seal scores 0.49. The C2 fix (score each half) also fixes this.
- C4. A draw can match an unlearned chain. The scorer picks the best match among every spell and every chain, learned or not, and fizzles with "You have not learned …" if the winner is unlearned. With 729 chains in the candidate list, a slightly sloppy single spell is more likely to land on some chain the player can't cast yet. Recommendation: when the best match is an unlearned chain and a learned single spell is also recognized, cast the learned spell. This is a narrow exception to the "never fall back" rule, which was written with single spells in mind.